The code below works when --stdpar isn’t set (not passed to GPU), but fails when it is. The error being output is to obscure to figure out what is failing / where it’s failing:
terminate called after throwing an instance of 'thrust::system::system_error'
what(): scan failed to synchronize: cudaErrorIllegalAddress: an illegal memory access was encountered
Can someone provide some hints as to what I’m doing wrong?
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <execution>
#include <algorithm>
#include <numeric>
using namespace std;
using namespace std::execution;
struct Element {
int idx;
int up;
int upLeft;
int res;
};
int calcWeight(char *a, char *b) {
if (a == NULL || b == NULL) { // indel score
return -1;
} else if (*a == *b) {
return 1;
} else {
return 0;
}
}
int main(void) {
vector<char> str1 {'T', 'A', 'C', 'T'};
vector<char> str2 {'G', 'A', 'C', 'G', 'T'};
vector<int> prevRow(str1.size() + 1);
vector<Element> row(str1.size() + 1);
transform(
par_unseq,
row.begin(),
row.end(),
row.begin(),
[](auto x) {
x.idx = 1;
return x;
}
);
exclusive_scan(
par_unseq,
row.begin(),
row.end(),
row.begin(),
Element { 0, 0, 0, -999999},
[](auto a, auto b) {
Element ret;
ret.idx = a.idx + b.idx;
return ret;
}
);
transform(
par_unseq,
row.begin(),
row.end(),
row.begin(),
[&str2](auto x) {
x.up = 0;
x.upLeft = 0;
x.res = -999999;
return x;
}
);
transform_exclusive_scan(
par_unseq,
row.begin(),
row.end(),
prevRow.begin(),
0,
[](auto a, auto b) {
return a + b;
},
[&str1](auto x) {
return calcWeight(&str1[x.idx], NULL);
}
);
for (auto str2It = str2.begin(); str2It != str2.end(); str2It++) {
auto ch2 = *str2It;
transform_inclusive_scan(
par_unseq,
row.begin(),
row.end(),
row.begin(),
[](auto a, auto b) {
Element ret;
ret.up = b.up;
ret.upLeft = b.upLeft;
ret.res = max({
a.res + b.res,
b.up,
b.upLeft
});
return ret;
},
[&prevRow, &str1, &ch2](auto x) {
auto i = x.idx;
x.up = prevRow[i] + calcWeight(NULL, &ch2);
if (i == 0) {
} else {
x.upLeft = prevRow[i-1] + calcWeight(&str1[i-1], &ch2);
}
x.res = calcWeight(&str1[i], NULL);
return x;
}
);
transform(
par_unseq,
row.begin(),
row.end(),
prevRow.begin(),
[](auto x) {
return x.res;
}
);
}
cout << "Final weight:" << prevRow.back();