| // Validate the atomic cross-team reduction fast path under unified shared |
| // memory. |
| // |
| // RUN: %libomptarget-compilexx-generic -fopenmp-force-usm \ |
| // RUN: -fopenmp-target-atomic-reduction && env HSA_XNACK=1 \ |
| // RUN: %libomptarget-run-generic | %fcheck-generic |
| // RUN: %libomptarget-compileoptxx-generic -fopenmp-force-usm \ |
| // RUN: -fopenmp-target-atomic-reduction && env HSA_XNACK=1 \ |
| // RUN: %libomptarget-run-generic | %fcheck-generic |
| // |
| // REQUIRES: amdgpu, unified_shared_memory |
| |
| #include <cassert> |
| #include <climits> |
| #include <cstdio> |
| #include <omp.h> |
| |
| int main() { |
| const int N = 1 << 16; |
| |
| long *sum = (long *)omp_alloc(sizeof(long), llvm_omp_target_shared_mem_alloc); |
| *sum = 7; |
| #pragma omp target teams distribute parallel for reduction(+ : sum[0]) |
| for (int i = 0; i < N; ++i) |
| sum[0] += i; |
| assert(sum[0] == 7 + (long)(N - 1) * N / 2 && "atomic + reduction incorrect"); |
| omp_free(sum, llvm_omp_target_shared_mem_alloc); |
| |
| double *fsum = |
| (double *)omp_alloc(sizeof(double), llvm_omp_target_shared_mem_alloc); |
| *fsum = 0.5; |
| #pragma omp target teams distribute parallel for reduction(+ : fsum[0]) |
| for (int i = 0; i < N; ++i) |
| fsum[0] += 1.0; |
| assert(fsum[0] == 0.5 + (double)N && "atomic fp + reduction incorrect"); |
| omp_free(fsum, llvm_omp_target_shared_mem_alloc); |
| |
| int *mx = (int *)omp_alloc(sizeof(int), llvm_omp_target_shared_mem_alloc); |
| int *mn = (int *)omp_alloc(sizeof(int), llvm_omp_target_shared_mem_alloc); |
| *mx = INT_MIN; |
| *mn = INT_MAX; |
| #pragma omp target teams distribute parallel for reduction(max : mx[0]) \ |
| reduction(min : mn[0]) |
| for (int i = 0; i < N; ++i) { |
| mx[0] = i > mx[0] ? i : mx[0]; |
| mn[0] = i < mn[0] ? i : mn[0]; |
| } |
| assert(mx[0] == N - 1 && mn[0] == 0 && "atomic min/max reduction incorrect"); |
| omp_free(mx, llvm_omp_target_shared_mem_alloc); |
| omp_free(mn, llvm_omp_target_shared_mem_alloc); |
| |
| unsigned *bits = |
| (unsigned *)omp_alloc(sizeof(unsigned), llvm_omp_target_shared_mem_alloc); |
| *bits = 0; |
| #pragma omp target teams distribute parallel for reduction(| : bits[0]) |
| for (int i = 0; i < N; ++i) |
| bits[0] |= (unsigned)i; |
| assert(bits[0] == (unsigned)(N - 1) && "atomic | reduction incorrect"); |
| omp_free(bits, llvm_omp_target_shared_mem_alloc); |
| |
| printf("SUCCESS\n"); |
| // CHECK: SUCCESS |
| return 0; |
| } |