omp parallel for with race condition from -fsanitize=thread

Viewed 66

I am using OpenMP for some basic multiprocessing computations and a very simple code is producing data races when compiled with sanitizers but seems to work correctly with any number of threads once the sanitizer is removed. I reduce it to a MWE:

#include <omp.h>
#include <iostream>
#include <cmath>
#include <cstdlib>

void fill(double * array, int size);
double suma(const double * array, int size);

int main(int argc, char *argv[])
{
  const int N = std::atoi(argv[1]);
  double * data = new double [N];

  fill(data, N);
  std::cout << data[0] << "\n";

  double total = suma(data, N);
  std::cout << total/N << "\n";

  delete [] data;

  return 0;
}

void fill(double * array, int size)
{
#pragma omp parallel for
  for(int ii = 0; ii < size; ii++) {
      array[ii] = 2*ii*std::sin(std::sqrt(ii/56.7)) +
        std::cos(std::pow(1.2*ii, 0.3));
  }
}

double suma(const double * array, int size)
{
  double val = 0.0;
#pragma omp parallel for reduction(+:val)
  for(int ii = 0; ii < size; ii++) {
    val += array[ii];
  }
  return val;
}

I compiled it as

g++ -g -fopenmp -fsanitize=thread mwe.cpp

with g++ version 11.2.0, and then execute it as

OMP_NUM_THREADS=2 ./a.out 10000000 1

and then I get sanitizers errors like:

==================                                                                                                                                                                                                                      
WARNING: ThreadSanitizer: data race (pid=26332)                                                                                                                                                                                         
  Write of size 4 at 0x7ffd2ecd3e90 by main thread:                                                                                                                                                                                     
    #0 suma(double const*, int) mwe.cpp:37 (a.out+0x4014ac)                                                                                                                    
    #1 main mwe.cpp:17 (a.out+0x401380)                                                                                                                                        
                                                                                                                                                                                                                                        
  Previous read of size 8 at 0x7ffd2ecd3e90 by thread T1:                                                                                                                                                                               
    [failed to restore the stack]                                                                                                                                                                                                       
                                                                                                                                                                                                                                        
  Location is stack of main thread.                                                                                                                                                                                                     
                                                                                                                                                                                                                                        
  Location is global '<null>' at 0x000000000000 ([stack]+0x00000001ee90)                                                                                                                                                                
                                                                                                                                                                                                                                        
  Thread T1 (tid=26334, running) created by main thread at:                                                                                                                                                                             
    #0 pthread_create <null> (libtsan.so.0+0x5fdc5)                                                                                                                                                                                     
    #1 <null> <null> (libgomp.so.1+0x1d99b)                                                                                                                                                                                             
    #2 main mwe.cpp:14 (a.out+0x401340)                                                                                                                                        
                                                                                                                                                                                                                                        
SUMMARY: ThreadSanitizer: data race mwe.cpp:37 in suma(double const*, int)                                                                                                     
==================                                                                                                                                                                                                                      
==================                                                                                                                                                                                                                      
WARNING: ThreadSanitizer: data race (pid=26332)                                                                                                                                                                                         
  Read of size 8 at 0x7ffd2ecd3e80 by thread T1:                                                                                                                                                                                        
    #0 suma(double const*, int) [clone ._omp_fn.0] mwe.cpp:37 (a.out+0x401766)                                                                                                 
    #1 <null> <null> (libgomp.so.1+0x1d385)                                                                                                                                                                                             
                                                                                                                                                                                                                                        
  Previous write of size 8 at 0x7ffd2ecd3e80 by main thread:                                                                                                                                                                            
    #0 suma(double const*, int) mwe.cpp:37 (a.out+0x4014be) 
    #1 main mwe.cpp:17 (a.out+0x401380)

  Location is stack of main thread.

  Location is global '<null>' at 0x000000000000 ([stack]+0x00000001ee80)

  Thread T1 (tid=26334, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x5fdc5)
    #1 <null> <null> (libgomp.so.1+0x1d99b)
    #2 main mwe.cpp:14 (a.out+0x401340)

SUMMARY: ThreadSanitizer: data race mwe.cpp:37 in suma(double const*, int) [clone ._omp_fn.0]
==================

I cannot see the source of this data race to fix it. Actually, I was using std::vector first, with the same result. What could be wrong with the code? I am pretty sure that there could be alternative ways to implement what I want to do, but I want to learn how to fix the current one. Or is this a false positive? Thanks in advance.

Edit: title with correct sanitizer option

0 Answers
Related