Skip to content

Commit

Permalink
Feat: openmp parallel the pair align loop
Browse files Browse the repository at this point in the history
Internal ctest changing into directory: /home/lxy/recruitment-2024-autumn/build
Test project /home/lxy/recruitment-2024-autumn/build
    Start 1: tiny case
1/3 Test #1: tiny case ........................   Passed    0.87 sec
    Start 2: small case
2/3 Test #2: small case .......................   Passed    2.41 sec
    Start 3: medium case
3/3 Test #3: medium case ......................   Passed   72.31 sec

100% tests passed, 0 tests failed out of 3

Total Test time (real) =  75.59 sec
  • Loading branch information
XinyiLiu577086410 committed Dec 13, 2024
1 parent bf16053 commit 93078bb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
27 changes: 21 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,25 @@ add_test(NAME "tiny case" COMMAND ${CMAKE_BINARY_DIR}/SmithWaterman ${dataset}/t
add_test(NAME "small case" COMMAND ${CMAKE_BINARY_DIR}/SmithWaterman ${dataset}/small_q.fna ${dataset}/small_t.fna ${dataset}/small_ref.txt)
add_test(NAME "medium case" COMMAND ${CMAKE_BINARY_DIR}/SmithWaterman ${dataset}/medium_q.fna ${dataset}/medium_t.fna ${dataset}/medium_ref.txt)

if (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
target_compile_options(SmithWaterman PRIVATE -O3 -acc -Minfo=acc)
find_package(OpenACC) # 若成功,执行cmake -B 会输出 "-- Found OpenACC_CXX: -acc"
if(OpenACC_CXX_FOUND)
target_link_libraries(SmithWaterman OpenACC::OpenACC_CXX) # 否则无法正确链接acc的一系列库
option(USE_OPENMP "Enable OpenMP support" OFF)
option(USE_OPENACC "Enable OpenACC support" OFF)

if(USE_OPENMP)
if (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
target_compile_options(SmithWaterman PRIVATE -O3 -mp -Minfo=mp)
find_package(OpenMP)
if(OpenMP_CXX_FOUND)
target_link_libraries(SmithWaterman OpenMP::OpenMP_CXX)
endif()
endif()
endif()
endif()

if(USE_OPENACC)
if (CMAKE_CXX_COMPILER_ID STREQUAL "NVHPC")
target_compile_options(SmithWaterman PRIVATE -O3 -acc -Minfo=acc)
find_package(OpenACC) # 若成功,执行cmake -B 会输出 "-- Found OpenACC_CXX: -acc"
if(OpenACC_CXX_FOUND)
target_link_libraries(SmithWaterman OpenACC::OpenACC_CXX) # 否则无法正确链接acc的一系列库
endif()
endif()
endif()
5 changes: 5 additions & 0 deletions build_example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Select one of the following 2 lines to generate the build files
cmake -DUSE_OPENMP=ON -DUSE_OPENACC=OFF -B build # for OpenMP
cmake -DUSE_OPENMP=OFF -DUSE_OPENACC=ON -B build # for OpenACC
# Build the code
cmake --build build/
2 changes: 2 additions & 0 deletions env.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
spack load nvhpc
spack load [email protected]
74 changes: 53 additions & 21 deletions src/SmithWaterman.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,28 @@ SmithWaterman::SmithWaterman(const std::string& query_seq_path,
assert(query_seqs_size >= 1);
target_seqs_size = target_seqs.size();
assert(target_seqs_size >= 1);
#pragma acc enter data copyin(this[0:1])
for (auto& query_seq : query_seqs) {
auto seq_ptr = query_seq.sequence.data();
#pragma acc enter data copyin(seq_ptr[:query_seq.sequence.size()])
}
for (auto& target_seq : target_seqs) {
auto seq_ptr = target_seq.sequence.data();
#pragma acc enter data copyin(seq_ptr[:target_seq.sequence.size()])
}
}

SmithWaterman::~SmithWaterman() {}
SmithWaterman::~SmithWaterman() {
for (auto& target_seq : target_seqs) {
auto seq_ptr = target_seq.sequence.data();
#pragma acc exit data delete(seq_ptr[0:target_seq.sequence.size()])
}
for (auto& query_seq : query_seqs) {
auto seq_ptr = query_seq.sequence.data();
#pragma acc exit data delete(seq_ptr[0:query_seq.sequence.size()])
}
#pragma acc exit data delete(this[0:1])
}

std::vector<size_t> SmithWaterman::solve() {
// Iterate through the query sequences
Expand Down Expand Up @@ -65,30 +84,43 @@ void SmithWaterman::pair_align(FastaSequence& query_seq,
// Store the highest score in each pairwise-alignment process.
// Default to 0.

auto query_sequence_ptr = query_seq.sequence.data();
auto target_sequence_ptr = target_seq.sequence.data();
auto H_ptr = H.data();

int64_t max_score = 0;
// Pairwise-Alignment between the two sequences
const int64_t max_x = query_seq_length + target_seq_length;
for (int64_t x = 1 + 1; x <= max_x; x++) {
int64_t local_max = 0;
for(int64_t i = 1; i <= query_seq_length; i++) {
int64_t j = x - i;
if (j >= 1 && j <= target_seq_length) {
int64_t index = pad * i + j;
// From the upper element
const int64_t up = H[index - pad] + gap_score;
// From the left element
const int64_t left = H[index - 1] + gap_score;
// From the upper-left element
const bool match = query_seq.sequence.at(i - 1) == target_seq.sequence.at(j - 1);
const int64_t upleft = H[index - pad - 1] + (match ? match_score : mismatch_score);
int64_t max = std::max({up, left, upleft, 0l});
H[index] = max;
local_max = std::max(local_max, max);
#pragma acc data present(this[:1], query_sequence_ptr[:query_seq_length], target_sequence_ptr[:target_seq_length])\
create(H_ptr[0:(query_seq_length + 1) * (target_seq_length + 1)]) copy(max_score)
{
#pragma acc parallel
{
// Pairwise-Alignment between the two sequences
const int64_t max_x = query_seq_length + target_seq_length;
#pragma acc loop seq
for (int64_t x = 1 + 1; x <= max_x; x++) {
int64_t local_max = -999;
#pragma acc loop independent reduction(max: local_max)
#pragma omp parallel for reduction(max: local_max)
for(int64_t i = 1; i <= query_seq_length; i++) {
const int64_t j = x - i;
if (j >= 1 && j <= target_seq_length) {
const int64_t index = pad * i + j;
// From the upper element
const int64_t up = H_ptr[index - pad] + gap_score;
// From the left element
const int64_t left = H_ptr[index - 1] + gap_score;
// From the upper-left element
const bool match = query_sequence_ptr[i - 1] == target_sequence_ptr[j - 1];
const int64_t upleft = H_ptr[index - pad - 1] + (match ? match_score : mismatch_score);
const int64_t max = std::max({up, left, upleft, 0l});
H_ptr[index] = max;
local_max = std::max(local_max, max);
}
}
max_score = std::max(max_score, local_max);
}
}
max_score = std::max(max_score, local_max);
}

max_scores.push_back(max_score);
}

Expand Down

0 comments on commit 93078bb

Please sign in to comment.