[clang] [llvm] [OpenMP] Diagnostic check for imperfect loop collapse (PR #96087)

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 19 08:34:24 PDT 2024


alexey-bataev wrote:

> > > FWIW, I don't think there's a reasonable, safe way to collapse loops like this and maintain parallel semantics, but ICBW.
> > 
> > 
> > I think, there is a proper way. Just annotate these instructions with something like:
> > ```
> > if (first inner loop iteration) {
> >   arr[i][i] = ...;
> > }
> > ```
> > 
> > 
> >     
> >       
> >     
> > 
> >       
> >     
> > 
> >     
> >   
> > and it should be correct
> 
> I think you're right for this particular test case, but I don't think that solution works in general. Consider something like:
> 
> ```
> int arr1[N][N], arr2[N];
> 
> #pragma omp parallel for collapse(2)
> {
>   for (int i = 0; i < N; i++) {
>     arr2[i] = i;
>     for (int j = 0; j < N; j++) {
>       arr1[i][j] += arr2[i];
>     }
>   }
> }
> ```
> 
> Now, if collapsed loop iterations take place in parallel or in an arbitrary order, there could be a read from arr2[i] before the write (in the "first" inner loop iteration). That is, I think we'd have something like:
> 
> ```
> for (int ij = 0; ij < N*N; ij++) {
>   int i = ij / N, j = ij % N;
>   if (j == 0) {
>     arr2[i] = i;
>   }
>   arr1[i][j] += arr2[i];
> }
> ```
> 
> and that's still not safe.

something like
```
bool Init[N] = {false};
for (int ij = 0; ij < N*N; ij++) {
  int i = ij / N, j = ij % N;
  #pragma omp critical
  if (!Init[i]) {
    arr2[i] = i;
    Init[i] = true;
  }
  arr1[i][j] += arr2[i];
}
```
remarks or anything else still is not correct in this case.

https://github.com/llvm/llvm-project/pull/96087


More information about the cfe-commits mailing list