Hi parlay maintainers, there seems to be an evasive bug in the integration of parlay and TBB that took me a painful amount of time to catch. The following is a minimal reproducible example:
#include <iostream>
#include "parlaylib-master/include/parlay/primitives.h"
#define vec parlay::sequence
struct MstPrune {
vec<int> parent;
vec<vec<int>> mst;
void operator() (const int eventNregion) {
int neg1 = -1;
parent.assign(eventNregion, neg1);
for (int i = 0, iend = parent.size(); i < iend; ++i) parent[i] = i;
mst.resize(eventNregion);
for (int i = 0; i < eventNregion; ++i) mst[i].resize(0);
for (int i = 0; i < eventNregion; ++i) mst[parent[i]].emplace_back(i);
}
};
int main(int argc, char* argv[]) {
vec<int> sizes(argc);
for (int i = 0; i < argc; ++i) sizes[i] = std::atoi(argv[i]);
vec<MstPrune> mst(parlay::num_workers());
parlay::parallel_for(0, argc, [&](auto i)->void {
auto t = parlay::worker_id();
mst[t](sizes[i]);
});
int S = 0;
for (auto& m: mst) {
for (auto& x: m.mst) { for (auto& y: x) S += y; }
}
if (S != 77) std::cout << "---------- S = " << S << " ----------\n";
else std::cout << "S = " << S << ", ";
}
#undef vec
After compiling the code with the following command
g++ -std=c++20 -Ofast -DPARLAY_TBB -ltbb bug.cpp -o bug
and run
for i in {1..1000}; do ./bug 1 1 1 1 12 1 1 2 2 4 3; done
You should be able to see nondeterministic result varying around the true answer "77".
If we change vec<int> parent; to std::vector<int> parent;, everything works fine.
If we switch to parlay's default thread scheduler, i.e. g++ -std=c++20 -Ofast -pthread bug.cpp -o bug , everything also works fine.
I tested both the latest oneAPI/tbb and an older version. The problem remains the same.
When the code is compiled as a shared library and linked to runtimes, segmentation fault will pop.
Could you help check if the bug is reproducible and provide some assistance?
Hi parlay maintainers, there seems to be an evasive bug in the integration of parlay and TBB that took me a painful amount of time to catch. The following is a minimal reproducible example:
After compiling the code with the following command
g++ -std=c++20 -Ofast -DPARLAY_TBB -ltbb bug.cpp -o bugand run
for i in {1..1000}; do ./bug 1 1 1 1 12 1 1 2 2 4 3; doneYou should be able to see nondeterministic result varying around the true answer "77".
If we change
vec<int> parent;tostd::vector<int> parent;, everything works fine.If we switch to parlay's default thread scheduler, i.e.
g++ -std=c++20 -Ofast -pthread bug.cpp -o bug, everything also works fine.I tested both the latest oneAPI/tbb and an older version. The problem remains the same.
When the code is compiled as a shared library and linked to runtimes, segmentation fault will pop.
Could you help check if the bug is reproducible and provide some assistance?