-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[OpenMP] Address __kmp_dist_for_static_init issue #129902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This test is currently causing a runtime failure related to some interaction between serial `teams` regions and `distribute parallel do` execution, triggered by `if` clauses attached to `parallel` evaluating to `false`. A potential fix to the issue is being proposed: llvm/llvm-project#129902.
This test is currently causing a runtime failure related to some interaction between serial `teams` regions and `distribute parallel do` execution, triggered by `if` clauses attached to `parallel` evaluating to `false`. A potential fix to the issue is being proposed: llvm/llvm-project#129902.
This test is currently causing a runtime failure related to some interaction between serial `teams` regions and `distribute parallel do` execution, triggered by `if` clauses attached to `parallel` evaluating to `false`. A potential fix to the issue is being proposed: llvm/llvm-project#129902.
@skatrak can you try the following patch instead? Use of the
|
@hansangbae thank you for checking this. Your suggestion is not working for me, unfortunately. It's somehow picking up another team of threads, because Interestingly, on a 24-core CPU, I get Also, |
@skatrak @hansangbae Can you guys dig a bit deeper why this is the case? I'm tempted to think that there's an underlying bug that surfaces through the containing |
@mjklemm If you look closely at the test I shared, you can see it actually contains no target regions in it. But the same issue arises if an !$omp target teams distribute parallel do if(.false.)
...
!$omp target teams if(.false.)
!$omp distribute parallel do if(.false.)
...
!$omp target teams distribute parallel do if(target:.false.) if(parallel:.false.)
... Basically, this bug is triggered anytime |
The assertion breaks, because of an "optimization" in the kmp code, that always triggers problems: Without checking, I would assume that
Breaks with your patch. You will compare 4 with 1 |
I just created a gist to reproduce this exact issue without having to use flang: https://gist.github.com/skatrak/b6da0b65c433d35cd7170e4d3a007f03. It directly calls the relevant OpenMP runtime functions, so it's hopefully easier to debug. |
Thank you @jprotze for the explanation. The problem with @hansangbae's solution is that for some reason it does still not fix the issue in this case, as I shared previously. Also, replacing the assert with your suggestion on its own doesn't stop it from asserting either, because The example you shared where my patch would break is, as far as I understand, invalid OpenMP. This is because I can imagine it's possible that the bug is elsewhere in the runtime or the sequence of runtime calls is somehow incorrect and we're reaching the call to |
Yes, that is correct. The sequence of directives that @jprotze shared should not be allowed as per the nesting rules for |
Sure, you are right. I just thought about the nesting from the perspective of lomp data structures, but not whether the code actually makes sense. With the code from your gist, I can reproduce the issue after I set OMP_NUM_THREADS>1 (while 1 is the default on my test system :) When spawning the teams, the runtime already forks nteams*nthreads-var threads, even if they are not used. These are organized in this additional base_team structure. In case of __kmp_fork_call, a special code path is taken For now, I think, your patch is the best solution to fix the broken assertion. As a long-term solution, I think that |
This patch attempts to provide a fix for an issue that appears when the `__kmp_dist_for_static_init` function is called from a serialized team. This is triggered by code generated by flang for `distribute parallel do` constructs whenever an `if` clause for the `parallel` leaf construct is present. This results in the introduction of a call to `__kmpc_fork_call_if` in place of `__kmpc_fork_call`. When it evaluates to `false`, it defers execution to `__kmp_serialized_parallel`, which creates a new serial team that is picked up by `__kmp_dist_for_static_init`, resulting in an incorrect `team` pointer that causes the `nteams == (kmp_uint32)team->t.t_parent->t.t_nproc` assertion to fail. The sequence of calls replicating this issue can be summarized as: - __kmpc_fork_teams - __kmpc_fork_call_if - __kmpc_dist_for_static_init_* Since I am not familiar with the implementation of the OpenMP runtime, it is possible that the previous sequence of calls is incorrect, or that the bug can be better fixed in another way, so I am open to discussing this. The following Fortran program can be compiled with flang to show the issue: ```f90 ! Compile and run: flang -fopenmp test.f90 -o test && ./test ! Check LLVM IR: flang -fc1 -emit-llvm -fopenmp test.f90 -o - program main implicit none integer, parameter :: n = 10 integer :: i, idx(n) !$omp teams !$omp distribute parallel do if(.false.) do i=1,n idx(i) = i end do !$omp end teams print *, idx end program ```
4aeb31f
to
2b04a0f
Compare
Thank you again @jprotze for the detailed look, your explanation does line up with what I was seeing. I just updated the patch to guard against the Edit: There's one other spot where this appears to also make sense to do ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
This patch attempts to provide a fix for an issue that appears when the
__kmp_dist_for_static_init
function is called from a serialized team.This is triggered by code generated by flang for
distribute parallel do
constructs whenever anif
clause for theparallel
leaf construct is present. This results in the introduction of a call to__kmpc_fork_call_if
in place of__kmpc_fork_call
. When it evaluates tofalse
, it defers execution to__kmp_serialized_parallel
, which creates a new serial team that is picked up by__kmp_dist_for_static_init
, resulting in an incorrectteam
pointer that causes thenteams == (kmp_uint32)team->t.t_parent->t.t_nproc
assertion to fail.The sequence of calls replicating this issue can be summarized as:
__kmpc_fork_teams
__kmpc_fork_call_if
__kmpc_dist_for_static_init_*
Since I am not familiar with the implementation of the OpenMP runtime, it is possible that the above sequence of calls is incorrect, or that the bug can be better fixed in another way, so I am open to discussing this.
The following Fortran program can be compiled with flang to show the issue: