I'm getting warnings about data races from Thread Sanitizer in this toy example:
#include <vector>
#include <algorithm>
#include <iostream>
int main () {
std::vector<int> vec(10);
// increase each vector entry 10 times. Each increment is one task.
#pragma omp parallel
#pragma omp single
for (int i=0; i < vec.size(); ++i){
for (int j=0; j < vec.size(); ++j){
#pragma omp task depend(mutexinoutset : vec[i])
++vec[i];
}
}
// output as a sanity check
// expected output: "vec: 10 10 10 10 10 10 10 10 10 10 "
std::cout << "vec: ";
std::for_each(vec.begin(), vec.end(), [](auto x) {std::cout << x << " ";});
std::cout << std::endl;
}
Compiling the code above and executing it via
export TSAN_OPTIONS='ignore_noninstrumented_modules=1'
clang++-15 \
-g \
-fopenmp \
-fno-omit-frame-pointer \
-fsanitize=thread \
toyExample.cpp \
&& OMP_NUM_THREADS=8 ./a.out
yields the following error message:
==================
WARNING: ThreadSanitizer: data race (pid=188516)
Write of size 4 at 0x7f7c50cac568 by main thread:
#0 .omp_outlined._debug__ /home/seriously/tmp/toyExample.cpp:12 (a.out+0xeab61) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#1 .omp_outlined..1 /home/seriously/tmp/toyExample.cpp:8 (a.out+0xeae35) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#2 __kmp_invoke_microtask ??:? (libomp.so+0xcf832) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
#3 main /home/seriously/tmp/toyExample.cpp:8 (a.out+0xea948) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
Previous read of size 4 at 0x7f7c50cac568 by thread T1:
#0 .omp_task_entry. /home/seriously/tmp/toyExample.cpp:13 (a.out+0xead8c) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#1 .omp_task_entry. /home/seriously/tmp/toyExample.cpp:12 (a.out+0xead8c)
#2 __kmpc_omp_target_task_alloc ??:? (libomp.so+0x68eae) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
#3 .omp_outlined._debug__ /home/seriously/tmp/toyExample.cpp:9 (a.out+0xeac0f) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#4 .omp_outlined..1 /home/seriously/tmp/toyExample.cpp:8 (a.out+0xeae35) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#5 __kmp_invoke_microtask ??:? (libomp.so+0xcf832) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
#6 main /home/seriously/tmp/toyExample.cpp:8 (a.out+0xea948) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
Location is heap block of size 1048576 at 0x7f7c50bcd000 allocated by main thread:
#0 malloc ??:? (a.out+0x744e3) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#1 <null> <null> (libomp.so+0x1fa19) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
#2 .omp_outlined..1 /home/seriously/tmp/toyExample.cpp:8 (a.out+0xeae35) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#3 __kmp_invoke_microtask ??:? (libomp.so+0xcf832) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
#4 main /home/seriously/tmp/toyExample.cpp:8 (a.out+0xea948) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
Thread T1 (tid=188518, running) created by main thread at:
#0 pthread_create ??:? (a.out+0x68346) (BuildId: 902718ddaac57a371260d1b7f7662a4d9b64a996)
#1 __kmpc_team_static_init_8u ??:? (libomp.so+0xab437) (BuildId: cd83ad3c973e7bba593f306526ed18d28b66ff1e)
SUMMARY: ThreadSanitizer: data race /home/seriously/tmp/toyExample.cpp:12 in .omp_outlined._debug__
==================
vec: 10 10 10 10 10 10 10 10 10 10
ThreadSanitizer: reported 1 warnings
The sanity check output is always correct, thus, strongly indicating that this is a false positive. Introducing an actual data race by removing the depend clause immediately affects the sanity check output.
My question is now: Did I misuse OpenMP Tasks or TSan? Or does Tsan simply not support OpenMP explicit tasks?