1 | // RUN: %libomptarget-compile-run-and-check-generic |
2 | |
3 | // REQUIRES: unified_shared_memory |
4 | |
5 | #include <omp.h> |
6 | #include <stdio.h> |
7 | |
8 | // --------------------------------------------------------------------------- |
9 | // Various definitions copied from OpenMP RTL |
10 | |
11 | extern void __tgt_register_requires(int64_t); |
12 | |
13 | extern void __tgt_target_data_begin(int64_t device_id, int32_t arg_num, |
14 | void **args_base, void **args, |
15 | int64_t *arg_sizes, int64_t *arg_types); |
16 | |
17 | extern void __tgt_target_data_end(int64_t device_id, int32_t arg_num, |
18 | void **args_base, void **args, |
19 | int64_t *arg_sizes, int64_t *arg_types); |
20 | |
21 | // End of definitions copied from OpenMP RTL. |
22 | // --------------------------------------------------------------------------- |
23 | |
24 | #pragma omp requires unified_shared_memory |
25 | |
26 | #define N 1024 |
27 | |
28 | int main(int argc, char *argv[]) { |
29 | int fails; |
30 | void *host_alloc = 0, *device_alloc = 0; |
31 | int *a = (int *)malloc(N * sizeof(int)); |
32 | |
33 | // Manual registration of requires flags for Clang versions |
34 | // that do not support requires. |
35 | __tgt_register_requires(8); |
36 | |
37 | // Init |
38 | for (int i = 0; i < N; ++i) { |
39 | a[i] = 10; |
40 | } |
41 | host_alloc = &a[0]; |
42 | |
43 | // Dummy target region that ensures the runtime library is loaded when |
44 | // the target data begin/end functions are manually called below. |
45 | #pragma omp target |
46 | {} |
47 | |
48 | // Manual calls |
49 | int device_id = omp_get_default_device(); |
50 | int arg_num = 1; |
51 | void **args_base = (void **)&a; |
52 | void **args = (void **)&a; |
53 | int64_t arg_sizes[arg_num]; |
54 | |
55 | arg_sizes[0] = sizeof(int) * N; |
56 | |
57 | int64_t arg_types[arg_num]; |
58 | |
59 | // Ox400 enables the CLOSE map type in the runtime: |
60 | // OMP_TGT_MAPTYPE_CLOSE = 0x400 |
61 | // OMP_TGT_MAPTYPE_TO = 0x001 |
62 | arg_types[0] = 0x400 | 0x001; |
63 | |
64 | device_alloc = host_alloc; |
65 | |
66 | __tgt_target_data_begin(device_id, arg_num, args_base, args, arg_sizes, |
67 | arg_types); |
68 | |
69 | #pragma omp target data use_device_ptr(a) |
70 | { device_alloc = a; } |
71 | |
72 | __tgt_target_data_end(device_id, arg_num, args_base, args, arg_sizes, |
73 | arg_types); |
74 | |
75 | // CHECK: a was copied to the device |
76 | if (device_alloc != host_alloc) |
77 | printf(format: "a was copied to the device\n" ); |
78 | |
79 | free(a); |
80 | |
81 | // CHECK: Done! |
82 | printf(format: "Done!\n" ); |
83 | |
84 | return 0; |
85 | } |
86 | |