Recently OpenMP has transitioned to using the "new" driver which primarily merges the device and host linking phases into a single wrapper that handles both at the same time. This replaced a few tools that were only used for OpenMP offloading, such as the `clang-offload-wrapper` and `clang-nvlink-wrapper`. The new driver carries some marked benefits compared to the old driver that is now being deprecated. Things like device-side LTO, static library support, and more compatible tooling. As such, we should be able to completely deprecate the old driver, at least for OpenMP. The old driver support will still exist for CUDA and HIP, although both of these can currently be compiled on Linux with `--offload-new-driver` to use the new method. Note that this does not deprecate the `clang-offload-bundler`, although it is unused by OpenMP now, it is still used by the HIP toolchain both as their device binary format and object format. When I proposed deprecating this code I heard some vendors voice concernes about needing to update their code in their fork. They should be able to just revert this commit if it lands. Reviewed By: jdoerfert, MaskRay, ye-luo Differential Revision: https://reviews.llvm.org/D130020
154 lines
4.3 KiB
C
154 lines
4.3 KiB
C
// Check that specifying device as omp_get_initial_device():
|
|
// - Doesn't cause the runtime to fail.
|
|
// - Offloads code to the host.
|
|
// - Doesn't transfer data. In this case, just check that neither host data nor
|
|
// default device data are affected by the specified transfers.
|
|
// - Works whether it's specified directly or as the default device.
|
|
|
|
// RUN: %libomptarget-compile-run-and-check-generic
|
|
|
|
// amdgpu does not have a working printf definition
|
|
// XFAIL: amdgcn-amd-amdhsa
|
|
// XFAIL: amdgcn-amd-amdhsa-LTO
|
|
|
|
#include <stdio.h>
|
|
#include <omp.h>
|
|
|
|
static void check(char *X, int Dev) {
|
|
printf(" host X = %c\n", *X);
|
|
#pragma omp target device(Dev)
|
|
printf("device X = %c\n", *X);
|
|
}
|
|
|
|
#define CHECK_DATA() check(&X, DevDefault)
|
|
|
|
int main(void) {
|
|
int DevDefault = omp_get_default_device();
|
|
int DevInit = omp_get_initial_device();
|
|
|
|
//--------------------------------------------------
|
|
// Initialize data on the host and default device.
|
|
//--------------------------------------------------
|
|
|
|
// CHECK: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
char X = 'd';
|
|
#pragma omp target enter data map(to:X)
|
|
X = 'h';
|
|
CHECK_DATA();
|
|
|
|
//--------------------------------------------------
|
|
// Check behavior when specifying host directly.
|
|
//--------------------------------------------------
|
|
|
|
// CHECK-NEXT: omp_is_initial_device() = 1
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target device(DevInit) map(always,tofrom:X)
|
|
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: omp_is_initial_device() = 1
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target teams device(DevInit) num_teams(1) map(always,tofrom:X)
|
|
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
|
|
CHECK_DATA();
|
|
|
|
// Check that __kmpc_push_target_tripcount_mapper doesn't fail. I'm not sure
|
|
// how to check that it actually pushes to the initial device.
|
|
#pragma omp target teams device(DevInit) num_teams(1)
|
|
#pragma omp distribute
|
|
for (int i = 0; i < 2; ++i)
|
|
;
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target data device(DevInit) map(always,tofrom:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target enter data device(DevInit) map(always,to:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target exit data device(DevInit) map(always,from:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target update device(DevInit) to(X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target update device(DevInit) from(X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
//--------------------------------------------------
|
|
// Check behavior when device defaults to host.
|
|
//--------------------------------------------------
|
|
|
|
omp_set_default_device(DevInit);
|
|
|
|
// CHECK-NEXT: omp_is_initial_device() = 1
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target map(always,tofrom:X)
|
|
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: omp_is_initial_device() = 1
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target teams num_teams(1) map(always,tofrom:X)
|
|
printf("omp_is_initial_device() = %d\n", omp_is_initial_device());
|
|
CHECK_DATA();
|
|
|
|
// Check that __kmpc_push_target_tripcount_mapper doesn't fail. I'm not sure
|
|
// how to check that it actually pushes to the initial device.
|
|
#pragma omp target teams num_teams(1)
|
|
#pragma omp distribute
|
|
for (int i = 0; i < 2; ++i)
|
|
;
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target data map(always,tofrom:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target enter data map(always,to:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target exit data map(always,from:X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target update to(X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
// CHECK-NEXT: host X = h
|
|
// CHECK-NEXT: device X = d
|
|
#pragma omp target update from(X)
|
|
;
|
|
CHECK_DATA();
|
|
|
|
return 0;
|
|
}
|