Skip to content

Commit

Permalink
Removed med low-memory mode (low and ultralow kept -- but renamed)
Browse files Browse the repository at this point in the history
  • Loading branch information
smarco committed Mar 7, 2022
1 parent 684b6d4 commit 0fa83da
Show file tree
Hide file tree
Showing 9 changed files with 51 additions and 80 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ The WFA2 library allows computing alignments with different spans or shapes. Alt

### <a name="wfa2.mem"></a> 2.4 Memory modes

The WFA2 library implements various memory modes: `wavefront_memory_high`, `wavefront_memory_med`, `wavefront_memory_low`, `wavefront_memory_ultralow`. These modes allow regulating the overall memory consumption at the expense of execution time. The standard WFA algorithm, which stores explicitly all wavefronts in memory, correspond to the mode `wavefront_memory_high`. The other methods progressively reduce the memory usage at the expense of slightlier larger alignment times. These memory modes can be used transparently with other alignment options and generate identical results. Note that the score-only alignment is not affected by this option (using a minimal memory footprint of `O(s)`).
The WFA2 library implements various memory modes: `wavefront_memory_high`, `wavefront_memory_med`, `wavefront_memory_low`. These modes allow regulating the overall memory consumption at the expense of execution time. The standard WFA algorithm, which stores explicitly all wavefronts in memory, correspond to the mode `wavefront_memory_high`. The other methods progressively reduce the memory usage at the expense of slightlier larger alignment times. These memory modes can be used transparently with other alignment options and generate identical results. Note that the score-only alignment is not affected by this option (using a minimal memory footprint of `O(s)`).

<details><summary>Memory-mode configuration</summary>
<p>
Expand Down
1 change: 0 additions & 1 deletion bindings/cpp/WFAligner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ WFAligner::WFAligner(
case MemoryHigh: this->attributes.memory_mode = wavefront_memory_high; break;
case MemoryMed: this->attributes.memory_mode = wavefront_memory_med; break;
case MemoryLow: this->attributes.memory_mode = wavefront_memory_low; break;
case MemoryUltralow: this->attributes.memory_mode = wavefront_memory_ultralow; break;
default: this->attributes.memory_mode = wavefront_memory_high; break;
}
this->attributes.alignment_scope = (alignmentScope==Score) ? compute_score : compute_alignment;
Expand Down
1 change: 0 additions & 1 deletion bindings/cpp/WFAligner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ class WFAligner {
MemoryHigh,
MemoryMed,
MemoryLow,
MemoryUltralow,
};
enum AlignmentScope {
Score,
Expand Down
33 changes: 27 additions & 6 deletions tools/align_benchmark/align_benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ bool align_benchmark_read_input(
*/
void align_benchmark_print_progress(
const int seqs_processed) {
const uint64_t time_elapsed_alg = timer_get_total_ns(&parameters.timer_global);
const uint64_t time_elapsed_alg = timer_get_current_total_ns(&parameters.timer_global);
const float rate_alg = (float)seqs_processed/(float)TIMER_CONVERT_NS_TO_S(time_elapsed_alg);
fprintf(stderr,"...processed %d reads (alignment = %2.3f seq/s)\n",seqs_processed,rate_alg);
}
Expand Down Expand Up @@ -739,7 +739,7 @@ void usage() {
" --ends-free P0,Pf,T0,Tf \n"
" [Wavefront parameters] \n"
" --wfa-score-only \n"
" --wfa-memory-mode 'high'|'med'|'low'|'ultralow' \n"
" --wfa-memory-mode 'high'|'med'|'low' \n"
" --wfa-heuristic <Strategy> \n"
" --wfa-heuristic-parameters <P1>,<P2>[,<P3>] \n"
" [Strategy='banded-static'] \n"
Expand Down Expand Up @@ -929,17 +929,15 @@ void parse_arguments(int argc,char** argv) {
case 1000: // --wfa-score-only
parameters.wfa_score_only = true;
break;
case 1001: // --wfa-memory-mode in {'high','med','low','ultralow'}
case 1001: // --wfa-memory-mode in {'high','med','low'}
if (strcmp(optarg,"high")==0) {
parameters.wfa_memory_mode = wavefront_memory_high;
} else if (strcmp(optarg,"med")==0) {
parameters.wfa_memory_mode = wavefront_memory_med;
} else if (strcmp(optarg,"low")==0) {
parameters.wfa_memory_mode = wavefront_memory_low;
} else if (strcmp(optarg,"ultralow")==0) {
parameters.wfa_memory_mode = wavefront_memory_ultralow;
} else {
fprintf(stderr,"Option '--wfa-memory-mode' must be in {'high','med','low','ultralow'}\n");
fprintf(stderr,"Option '--wfa-memory-mode' must be in {'high','med','low'}\n");
exit(1);
}
break;
Expand Down Expand Up @@ -1108,6 +1106,29 @@ void parse_arguments(int argc,char** argv) {
}
break;
}
// Check 'wfa-heuristic'
switch (parameters.wfa_heuristic) {
case wf_heuristic_banded_static:
case wf_heuristic_xdrop:
case wf_heuristic_zdrop:
if (parameters.wfa_heuristic_p1 == -1 ||
parameters.wfa_heuristic_p2 == -1) {
fprintf(stderr,"Heuristic requires parameters '--wfa-heuristic-parameters' <P1>,<P2>\n");
exit(1);
}
break;
case wf_heuristic_banded_adaptive:
case wf_heuristic_wfadaptive:
if (parameters.wfa_heuristic_p1 == -1 ||
parameters.wfa_heuristic_p2 == -1 ||
parameters.wfa_heuristic_p3 == -1) {
fprintf(stderr,"Heuristic requires parameters '--wfa-heuristic-parameters' <P1>,<P2>,<P3>\n");
exit(1);
}
break;
default:
break;
}
// Checks parallel
if (parameters.num_threads > 1) {
if (parameters.plot > 0) {
Expand Down
4 changes: 2 additions & 2 deletions wavefront/wavefront_align.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ void wavefront_align_terminate(
// Fetch wavefront
if (wf_components->memory_modular) score = score % wf_components->max_score_scope;
wavefront_t* const mwavefront = wf_components->mwavefronts[score];
// DEBUG
//wavefront_aligner_print(stderr,wf_aligner,score_final-10,score_final,6,16);
// Retrieve alignment
if (wf_aligner->alignment_scope == compute_score) {
cigar_clear(&wf_aligner->cigar);
Expand Down Expand Up @@ -246,6 +244,8 @@ int wavefront_align_sequences(
// Exact extend s-wavefront
const bool finished = (*wf_align_extend)(wf_aligner,score);
if (finished) {
// DEBUG
// wavefront_aligner_print(stderr,wf_aligner,0,score,7,0);
if (wf_aligner->align_status.status == WF_STATUS_SUCCESSFUL) {
wavefront_align_terminate(wf_aligner,score);
}
Expand Down
31 changes: 11 additions & 20 deletions wavefront/wavefront_aligner.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,26 +134,17 @@ void wavefront_aligner_set_system(
// Copy all parameters
wf_aligner->system = *system;
// Reset effective limits
if (system->max_memory_compact == -1 || system->max_memory_resident == -1) {
switch (wf_aligner->memory_mode) {
case wavefront_memory_med:
wf_aligner->system.max_partial_compacts = 5;
wf_aligner->system.max_memory_compact = BUFFER_SIZE_2G;
wf_aligner->system.max_memory_resident = BUFFER_SIZE_2G + BUFFER_SIZE_256M;
break;
case wavefront_memory_low:
wf_aligner->system.max_partial_compacts = 2;
wf_aligner->system.max_memory_compact = BUFFER_SIZE_1G;
wf_aligner->system.max_memory_resident = BUFFER_SIZE_1G + BUFFER_SIZE_256M;
break;
case wavefront_memory_ultralow:
wf_aligner->system.max_partial_compacts = 1;
wf_aligner->system.max_memory_compact = BUFFER_SIZE_256M;
wf_aligner->system.max_memory_resident = BUFFER_SIZE_256M + BUFFER_SIZE_256M;
break;
default:
break;
}
wf_aligner->system.max_memory_compact = BUFFER_SIZE_256M;
wf_aligner->system.max_memory_resident = BUFFER_SIZE_256M + BUFFER_SIZE_256M;
switch (wf_aligner->memory_mode) {
case wavefront_memory_med:
wf_aligner->system.max_partial_compacts = 4;
break;
case wavefront_memory_low:
wf_aligner->system.max_partial_compacts = 1;
break;
default:
break;
}
// Profile
timer_reset(&wf_aligner->system.timer);
Expand Down
5 changes: 2 additions & 3 deletions wavefront/wavefront_attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,8 @@ typedef struct {
*/
typedef enum {
wavefront_memory_high = 0, // High-memore mode (fastest, stores all WFs explicitly)
wavefront_memory_med = 1, // Succing-memory mode (fast, offloads multiple BT-blocks)
wavefront_memory_low = 2, // Succing-memory mode (medium, offloads half-full BT-blocks)
wavefront_memory_ultralow = 3, // Succing-memory mode (slow, offloads only full BT-blocks)
wavefront_memory_med = 1, // Succing-memory mode (medium, offloads half-full BT-blocks)
wavefront_memory_low = 2, // Succing-memory mode (slow, offloads only full BT-blocks)
} wavefront_memory_t;

/*
Expand Down
45 changes: 2 additions & 43 deletions wavefront/wavefront_backtrace_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,37 +70,6 @@ void wavefront_backtrace_offload_blocks_selective(
}
wf_backtrace_buffer_add_used(bt_buffer,current_pos-global_pos);
}
void wavefront_backtrace_offload_blocks_all(
wf_offset_t* const out_offsets,
pcigar_t* const out_bt_pcigar,
bt_block_idx_t* const out_bt_prev,
const int lo,
const int hi,
wf_backtrace_buffer_t* const bt_buffer) {
// Offload all BT-blocks (no matter the occupancy)
int k = lo;
while (k <= hi) {
// Fetch BT-buffer free memory
int bt_blocks_available;
bt_block_t* bt_block_mem;
const bt_block_idx_t global_pos = wf_backtrace_buffer_get_mem(bt_buffer,&bt_block_mem,&bt_blocks_available);
// Offload as many BT-blocks as possible
const int offloaded_blocks = MIN(hi-k+1,bt_blocks_available);
int offset;
PRAGMA_LOOP_VECTORIZE
for (offset=0;offset<offloaded_blocks;++offset) {
// Store
bt_block_mem[offset].pcigar = out_bt_pcigar[k+offset];
bt_block_mem[offset].prev_idx = out_bt_prev[k+offset];
// Reset
out_bt_pcigar[k+offset] = 0;
out_bt_prev[k+offset] = global_pos+offset;
}
// Update offloaded
wf_backtrace_buffer_add_used(bt_buffer,offloaded_blocks);
k += offloaded_blocks;
}
}
/*
* Backtrace offloading (linear)
*/
Expand All @@ -117,17 +86,12 @@ int wavefront_backtrace_offload_blocks_linear(
// Select memory-mode
switch (wavefront_memory) {
case wavefront_memory_med:
wavefront_backtrace_offload_blocks_all(
out_offsets,out_bt_pcigar,out_bt_prev,lo,hi,bt_buffer);
return 0; // Maximum occupancy (all empty)
break;
case wavefront_memory_low:
wavefront_backtrace_offload_blocks_selective(
out_offsets,out_bt_pcigar,out_bt_prev,
lo,hi,PCIGAR_HALF_FULL_MASK,bt_buffer);
return PCIGAR_MAX_LENGTH/2; // Half occupancy
break;
case wavefront_memory_ultralow:
case wavefront_memory_low:
wavefront_backtrace_offload_blocks_selective(
out_offsets,out_bt_pcigar,out_bt_prev,
lo,hi,PCIGAR_FULL_MASK,bt_buffer);
Expand Down Expand Up @@ -180,16 +144,11 @@ int wavefront_backtrace_offload_blocks_affine(
// Select memory-mode
switch (wavefront_memory) {
case wavefront_memory_med:
wavefront_backtrace_offload_blocks_all(
out_offsets,out_bt_pcigar,out_bt_prev,lo,hi,bt_buffer);
return 0; // Maximum occupancy (all empty)
break;
case wavefront_memory_low:
wavefront_backtrace_offload_blocks_selective(
out_offsets,out_bt_pcigar,out_bt_prev,
lo,hi,PCIGAR_HALF_FULL_MASK,bt_buffer);
return PCIGAR_MAX_LENGTH/2; // Half occupancy
case wavefront_memory_ultralow:
case wavefront_memory_low:
wavefront_backtrace_offload_blocks_selective(
out_offsets,out_bt_pcigar,out_bt_prev,
lo,hi,PCIGAR_ALMOST_FULL_MASK,bt_buffer);
Expand Down
9 changes: 6 additions & 3 deletions wavefront/wavefront_heuristic.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ void wavefront_cufoff_banded_adaptive(
const int max_wf_length = wf_heuristic->max_k - wf_heuristic->min_k + 1;
if (wf_length > max_wf_length) {
// Sample wavefront
const int quarter = wf_length/4;
const int leeway = (wf_length - max_wf_length) / 2;
const int quarter = wf_length / 4;
const int dist_p0 = wf_compute_distance_end2end(
offsets[lo],lo,pattern_length,text_length);
const int dist_p1 = wf_compute_distance_end2end(
Expand All @@ -212,11 +213,13 @@ void wavefront_cufoff_banded_adaptive(
offsets[hi],hi,pattern_length,text_length);
// Heuristically decide where to place the band
int new_lo = lo;
if (dist_p0 > dist_p3) new_lo += quarter;
if (dist_p1 > dist_p2) new_lo += quarter;
if (dist_p0 > dist_p3) new_lo += leeway;
if (dist_p1 > dist_p2) new_lo += leeway;
// Set wavefront limits
wavefront->lo = new_lo;
if (wavefront->lo < lo) wavefront->lo = lo;
wavefront->hi = new_lo + max_wf_length - 1;
if (wavefront->hi > hi) wavefront->hi = hi;
}
// Set wait steps (don't repeat this heuristic often)
wf_heuristic->steps_wait = wf_heuristic->steps_between_cutoffs;
Expand Down

0 comments on commit 0fa83da

Please sign in to comment.