This is an archive of the discontinued LLVM Phabricator instance.

[flang][OpenMP] Fix firstprivate with barrier
ClosedPublic

Authored by shraiysh on May 16 2022, 7:39 AM.

Details

Summary

This patch fixes the unintentional data race in firstprivate
implementation. There is a Read-Write race when one thread tries
to copy the value inside the omp.parallel region while other
thread modifies it from inside the region (using pointers or
some other form of indirect access).

For detailed discussion please refer to discourse.

Diff Detail

Event Timeline

shraiysh created this revision.May 16 2022, 7:39 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptMay 16 2022, 7:39 AM
shraiysh requested review of this revision.May 16 2022, 7:39 AM
NimishMishra accepted this revision.May 23 2022, 3:18 AM

LGTM. With a couple of nits.

Please do wait for someone else's comments on the patch as well.

flang/test/Lower/OpenMP/omp-parallel-firstprivate-clause-scalar.f90
9

Could you use the captured value of arg0 instead of the hardcoded value? I think the captured value is [[ARG1]] here.

This revision is now accepted and ready to land.May 23 2022, 3:18 AM
NimishMishra added inline comments.May 23 2022, 3:19 AM
flang/lib/Lower/OpenMP.cpp
81

Can we move this to the above if condition where copyHostAssociateVar is called? After the function call, we can create this barrier operation.

shraiysh updated this revision to Diff 431324.May 23 2022, 3:59 AM
shraiysh marked 2 inline comments as done.

Addressed comments.

Please do wait for someone else's comments on the patch as well.

Sure

shraiysh requested review of this revision.May 23 2022, 3:59 AM
shraiysh added inline comments.
flang/lib/Lower/OpenMP.cpp
81

If there are n firstprivate variables, that would create a barrier after each of them - and hence n barriers. We do not want to do that. We want one barrier after all the copying is done and hence this had to be moved outside the for loop.

flang/test/Lower/OpenMP/omp-parallel-firstprivate-clause-scalar.f90
9

Right, thank you. Done.

Thanks for this fix. Please include more regression tests. Maybe in one another single file to test the position of this barrier?

1. omp parallel firstprivate
      omp do
2. omp parallel
      omp do firstprivate
  comment for no barrier. Maybe this case is not needed.
3. omp parallel do firstprivate
flang/lib/Lower/OpenMP.cpp
95–96

Should this fix be here unconditionally?

Thanks for this fix. Please include more regression tests. Maybe in one another single file to test the position of this barrier?

Sure, will add these tests.

flang/lib/Lower/OpenMP.cpp
95–96

We do not need a barrier when data is not copied from outside. When there is no firstprivate clause, the current implementation is correct and free from any data races. Hence we need this only when we encounter the firstprivate clause.

peixin added inline comments.May 25 2022, 2:18 AM
flang/lib/Lower/OpenMP.cpp
95–96

What I mean is this.

shraiysh added inline comments.May 25 2022, 6:43 AM
flang/lib/Lower/OpenMP.cpp
95–96

Okay this should work. I misunderstood your suggestion to be outside the loop, my bad :). Will incorporate this in the next update.

peixin added a comment.Jun 8 2022, 1:52 AM

Can you promote the priority for this patch since this blocks the patch of lowering default clause?

Can you promote the priority for this patch since this blocks the patch of lowering default clause?

Sure, will get this done soon.

shraiysh updated this revision to Diff 435437.Jun 9 2022, 12:15 AM

Addressed comments

peixin accepted this revision.Jun 9 2022, 3:53 AM

LGTM. Please wait for @kiranchandramohan 's confirmation.

This revision is now accepted and ready to land.Jun 9 2022, 3:53 AM

LGTM. Please wait for @kiranchandramohan 's confirmation.

Sure. Thanks for the review.

Thanks @shraiysh for the fix.

When the clauses are listed separately, this will create multiple barriers. We probably need to test whether there was a firstprivate clause and then add a barrier at the end.

subroutine sb
  integer :: x, y
  !$omp parallel firstprivate(x) firstprivate(y)
  x = x/y
  !$omp end parallel
end subroutine
shraiysh updated this revision to Diff 435968.Jun 10 2022, 10:35 AM

Addressed comment. Thank you for pointing the issue out @kiranchandramohan.

peixin requested changes to this revision.Jun 12 2022, 6:29 PM
peixin added inline comments.
flang/lib/Lower/OpenMP.cpp
104

Why do you add the firstprivate attribute to barrier operation? It is kind of strange. Maybe I misunderstand the attribute of barrier operation? Also, it is costly to traverse the operations in the block, which can be skipped. I add one boolean value hasCopyin for lowering of copyin clause (D127468). You can also add one for firstprivate clause.

This revision now requires changes to proceed.Jun 12 2022, 6:29 PM
shraiysh updated this revision to Diff 436478.Jun 13 2022, 11:00 AM

Thanks @peixin for the suggestion. Addressed it.

peixin added inline comments.Jun 13 2022, 6:03 PM
flang/lib/Lower/OpenMP.cpp
97

Why do you repeatedly erase and add the barrier operation? Why not add it only once after the loop of opClauseList?

shraiysh added inline comments.Jun 14 2022, 10:18 PM
flang/lib/Lower/OpenMP.cpp
97

Should this fix be here unconditionally?

It's either a condition here or a condition at the end of the loop. I kept it here as per your previous comment of adding barrier unconditionally.

It is a minor detail and I don't prefer one way or another. Let me know whatever seems better :)

peixin added inline comments.Jun 14 2022, 11:35 PM
flang/lib/Lower/OpenMP.cpp
97

Oh. Sorry, I might misguide you. My previous comment is mainly for doing the barrier in funtion privatizeVars or createPrivateVarSyms. I was not aware of the multiple firstprivate clauses needing only one barrier, and that comment is not for adding the barrier in the for loop or out of the for loop. How about the following:

bool hasFirstprivate{false};
for ( ...) {
  if (...) {
    ...
  } else if (...firstprivate) {
    ...
    hasFirstprivate = true;
  }
}
if (hasFirstprivate)
 firOpBuilder.create<mlir::omp::BarrierOp>(...).
shraiysh added inline comments.Jun 14 2022, 11:37 PM
flang/lib/Lower/OpenMP.cpp
97

Sounds good. Will update to this. Thanks.

shraiysh updated this revision to Diff 437507.Jun 16 2022, 5:00 AM

Addressed comments.

peixin accepted this revision.Jun 16 2022, 5:03 AM

LGTM

flang/lib/Lower/OpenMP.cpp
87

Nit

This revision is now accepted and ready to land.Jun 16 2022, 5:03 AM

ping @kiranchandramohan . This blocks the review for the lowering of default clause.

LG. Thanks @shraiysh @peixin.

BTW, I did not understand how this blocks the default clause patch. AFAIS, there is no dependency.

LG. Thanks @shraiysh @peixin.

BTW, I did not understand how this blocks the default clause patch. AFAIS, there is no dependency.

@NimishMishra marked the dependence in D123930. I guess he wants to add the test case for this scenario, too?

NimishMishra added a comment.EditedJun 16 2022, 6:12 AM

LG. Thanks @shraiysh @peixin.

BTW, I did not understand how this blocks the default clause patch. AFAIS, there is no dependency.

@shraiysh mentioned in D123930 that should D123930 merge first, we would need explicit barrier in the default clause lowering patch. However, should D125689 patch go in first, then there would be no such need. So I added the dependency.

This revision was automatically updated to reflect the committed changes.