Skip to content

Commit 955771c

Browse files
committed
Fix race condition increment issue
1 parent 78f78c4 commit 955771c

File tree

1 file changed

+41
-8
lines changed

1 file changed

+41
-8
lines changed

src/SplitCode.h

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#define SPLITCODE_VERSION "0.31.5"
55

6+
#include <atomic>
67
#include <string>
78
#include <iostream>
89
#include <vector>
@@ -84,6 +85,7 @@ struct SplitCode {
8485
thisIsParent = true;
8586
isNested = false;
8687
opt_show_not_found = false;
88+
qc_rows = 0;
8789
}
8890

8991
SplitCode(int nFiles, SplitCode* sc) { // nesting
@@ -143,6 +145,7 @@ struct SplitCode {
143145
num_reads_assigned = 0;
144146
summary_n_reads_filtered = 0;
145147
summary_n_reads_filtered_assigned = 0;
148+
qc_rows = 0;
146149
this->summary_file = sc->summary_file;
147150

148151
this->trim_5_str = ""; // Only applies to parent
@@ -216,6 +219,7 @@ struct SplitCode {
216219
no_tags = false;
217220
thisIsParent = true;
218221
isNested = false;
222+
qc_rows = 0;
219223
this->summary_file = summary_file;
220224
this->trim_5_str = trim_5_str;
221225
this->trim_3_str = trim_3_str;
@@ -458,13 +462,23 @@ struct SplitCode {
458462
if (do_qc) {
459463
of << "\t" << "\"tag_qc\": " << "[" << "\n";
460464
bool first = true;
461-
for (int i = 0; i < qc.size(); i++) {
465+
/*for (int i = 0; i < qc.size(); i++) {
462466
if (qc[i].size() == 0) continue;
463467
for (int j = 0; j < qc[i].size(); j++) {
464468
if (!first) of << ",";
465469
if (!first) of << "\n";
466470
first = false;
467-
of << "\t\t{\"tag\": \"" << names[i] << "\", \"distance\": " << j << ", \"count\": " << qc[i][j] << "}";
471+
of << "\t\t{\"tag\": \"" << names[i] << "\", \"distance\": " << j << ", \"count\": " << *(qc[i][j]) << "}";
472+
}
473+
}*/
474+
for (std::size_t i = 0; i < qc_rows; ++i) {
475+
for (std::size_t j = 0; j < QC_COLS; ++j) {
476+
auto count = qc_at(i, j).load(std::memory_order_relaxed);
477+
if (!first) of << ",\n";
478+
first = false;
479+
of << "\t\t{\"tag\": \"" << names[i]
480+
<< "\", \"distance\": " << j
481+
<< ", \"count\": " << count << "}";
468482
}
469483
}
470484
if (!first) of << "\n";
@@ -1055,9 +1069,18 @@ struct SplitCode {
10551069
}
10561070
}*/
10571071
if (do_qc) {
1058-
qc.resize(names.size());
1059-
for (size_t i = 0; i < qc.size(); i++) {
1060-
qc[i].resize(4,0);
1072+
/*qc.resize(names.size());
1073+
for (auto &row : qc) {
1074+
row.clear();
1075+
row.reserve(4);
1076+
for (int j = 0; j < 4; ++j) {
1077+
row.emplace_back(std::make_unique<std::atomic<unsigned long long>>(0ULL));
1078+
}
1079+
}*/
1080+
qc_rows = names.size();
1081+
qc = std::make_unique<std::atomic<unsigned long long>[]>(qc_rows * QC_COLS);
1082+
for (std::size_t i = 0; i < qc_rows * QC_COLS; ++i) {
1083+
qc[i].store(0, std::memory_order_relaxed);
10611084
}
10621085
}
10631086

@@ -1076,6 +1099,10 @@ struct SplitCode {
10761099
init = true;
10771100
}
10781101

1102+
inline std::atomic<unsigned long long> &qc_at(std::size_t row, std::size_t col) {
1103+
return qc[row * QC_COLS + col];
1104+
}
1105+
10791106
struct VectorHasher {
10801107
size_t operator()(const std::vector<uint32_t>& v) const {
10811108
uint64_t r = v.size()-1;
@@ -4214,8 +4241,11 @@ struct SplitCode {
42144241
}
42154242
if (do_qc && !u.empty()) { // Now, store the QC
42164243
for (auto &q : qc_vec) {
4217-
auto& qc_ = qc[q.first];
4218-
qc_[q.second > 3 ? 3 : q.second]++;
4244+
//auto& qc_ = qc[q.first];
4245+
//(*(qc_[q.second > 3 ? 3 : q.second]))++;
4246+
std::size_t row = q.first;
4247+
std::size_t col = q.second > 3 ? 3 : q.second;
4248+
qc_at(row, col).fetch_add(1, std::memory_order_relaxed);
42194249
}
42204250
}
42214251
}
@@ -4945,7 +4975,10 @@ struct SplitCode {
49454975
std::unordered_map<std::vector<uint32_t>, std::string, VectorHasher> groupmapinv_keep;
49464976
std::unordered_map<std::vector<uint32_t>, int, VectorHasher> groupmapinv_discard;
49474977

4948-
std::vector<std::vector<uint64_t>> qc; // outer vector index = tag name id; vector indices = tag edit distance; value = count
4978+
//std::vector<std::vector<std::unique_ptr<std::atomic<unsigned long long>>>> qc; // outer vector index = tag name id; vector indices = tag edit distance; value = count
4979+
std::unique_ptr<std::atomic<unsigned long long>[]> qc;
4980+
std::size_t qc_rows;
4981+
static constexpr std::size_t QC_COLS = 4;
49494982
bool do_qc; // Should we do QC (i.e. do tag-level statistics?)
49504983

49514984
std::unordered_map<uint32_t,int> min_finds_map;

0 commit comments

Comments
 (0)