|
1 | | -! Validate that a device pointer allocated via OpenMP runtime APIs can be |
2 | | -! consumed by a TARGET region using the is_device_ptr clause. |
| 1 | +! Validate that a device pointer obtained via omp_get_mapped_ptr can be used |
| 2 | +! inside a TARGET region with the is_device_ptr clause. |
3 | 3 | ! REQUIRES: flang, amdgcn-amd-amdhsa |
4 | | -! UNSUPPORTED: nvptx64-nvidia-cuda |
5 | | -! UNSUPPORTED: nvptx64-nvidia-cuda-LTO |
6 | | -! UNSUPPORTED: aarch64-unknown-linux-gnu |
7 | | -! UNSUPPORTED: aarch64-unknown-linux-gnu-LTO |
8 | | -! UNSUPPORTED: x86_64-unknown-linux-gnu |
9 | | -! UNSUPPORTED: x86_64-unknown-linux-gnu-LTO |
10 | 4 |
|
11 | 5 | ! RUN: %libomptarget-compile-fortran-run-and-check-generic |
12 | 6 |
|
13 | 7 | program is_device_ptr_target |
14 | | - use omp_lib |
15 | | - use iso_c_binding |
| 8 | + use iso_c_binding, only : c_ptr, c_loc |
16 | 9 | implicit none |
17 | 10 |
|
18 | | - integer, parameter :: n = 4 |
19 | | - integer, target :: host(n) |
20 | | - type(c_ptr) :: device_ptr |
21 | | - integer(c_int) :: rc |
22 | | - integer :: i |
23 | | - |
24 | | - do i = 1, n |
25 | | - host(i) = i |
26 | | - end do |
| 11 | + interface |
| 12 | + function omp_get_mapped_ptr(host_ptr, device_num) & |
| 13 | + bind(C, name="omp_get_mapped_ptr") |
| 14 | + use iso_c_binding, only : c_ptr, c_int |
| 15 | + type(c_ptr) :: omp_get_mapped_ptr |
| 16 | + type(c_ptr), value :: host_ptr |
| 17 | + integer(c_int), value :: device_num |
| 18 | + end function omp_get_mapped_ptr |
| 19 | + end interface |
27 | 20 |
|
28 | | - device_ptr = omp_target_alloc(int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), & |
29 | | - omp_get_default_device()) |
30 | | - if (.not. c_associated(device_ptr)) then |
31 | | - print *, "device alloc failed" |
32 | | - stop 1 |
33 | | - end if |
34 | | - |
35 | | - rc = omp_target_memcpy(device_ptr, c_loc(host), & |
36 | | - int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), & |
37 | | - 0_c_size_t, 0_c_size_t, & |
38 | | - omp_get_default_device(), omp_get_initial_device()) |
39 | | - if (rc .ne. 0) then |
40 | | - print *, "host->device memcpy failed" |
41 | | - call omp_target_free(device_ptr, omp_get_default_device()) |
42 | | - stop 1 |
43 | | - end if |
| 21 | + integer, parameter :: n = 4 |
| 22 | + integer, parameter :: dev = 0 |
| 23 | + integer, target :: a(n) |
| 24 | + type(c_ptr) :: dptr |
| 25 | + integer :: flag |
44 | 26 |
|
45 | | - call fill_on_device(device_ptr) |
| 27 | + a = [2, 4, 6, 8] |
| 28 | + flag = 0 |
46 | 29 |
|
47 | | - rc = omp_target_memcpy(c_loc(host), device_ptr, & |
48 | | - int(n, c_size_t) * int(c_sizeof(host(1)), c_size_t), & |
49 | | - 0_c_size_t, 0_c_size_t, & |
50 | | - omp_get_initial_device(), omp_get_default_device()) |
51 | | - call omp_target_free(device_ptr, omp_get_default_device()) |
| 30 | + !$omp target data map(tofrom: a, flag) |
| 31 | + dptr = omp_get_mapped_ptr(c_loc(a), dev) |
52 | 32 |
|
53 | | - if (rc .ne. 0) then |
54 | | - print *, "device->host memcpy failed" |
55 | | - stop 1 |
56 | | - end if |
| 33 | + !$omp target is_device_ptr(dptr) map(tofrom: flag) |
| 34 | + flag = flag + 1 |
| 35 | + !$omp end target |
| 36 | + !$omp end target data |
57 | 37 |
|
58 | | - if (all(host == [2, 4, 6, 8])) then |
| 38 | + if (flag .eq. 1 .and. all(a == [2, 4, 6, 8])) then |
59 | 39 | print *, "PASS" |
60 | 40 | else |
61 | | - print *, "FAIL", host |
| 41 | + print *, "FAIL", a |
62 | 42 | end if |
63 | 43 |
|
64 | | -contains |
65 | | - subroutine fill_on_device(ptr) |
66 | | - type(c_ptr) :: ptr |
67 | | - integer, pointer :: p(:) |
68 | | - call c_f_pointer(ptr, p, [n]) |
69 | | - |
70 | | - !$omp target is_device_ptr(ptr) |
71 | | - p(1) = 2 |
72 | | - p(2) = 4 |
73 | | - p(3) = 6 |
74 | | - p(4) = 8 |
75 | | - !$omp end target |
76 | | - end subroutine fill_on_device |
77 | 44 | end program is_device_ptr_target |
78 | 45 |
|
79 | 46 | !CHECK: PASS |
0 commit comments