blob: ef00e0a2ee6dfd9e14051c773e53cff66e965461 [file]
// 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;
}