LLVM OpenMP 22.0.0git
omp60_memory_routines.c
Go to the documentation of this file.
1// RUN: %libomp-compile -Wl,--export-dynamic && %libomp-run
2
3// REQUIRES: linux
4
5// Test OpenMP 6.0 memory management routines.
6// Test host runtime's basic support with an emulated offload runtime.
7
8#include <stdlib.h>
9#include <omp.h>
10
11#define NUM_DEVICES 4
12
13//
14// Required offload runtime interfaces
15//
16extern int __tgt_get_num_devices(void) { return NUM_DEVICES; }
17
18extern int __tgt_get_mem_resources(int num_devices, const int *devices,
19 int host, omp_memspace_handle_t memspace,
20 int *resources) {
21 int i;
22 // We expect valid inputs within this test.
23 int num_resources = num_devices;
24 if (resources) {
25 // Simple resouce ID mapping example in the backend (=device ID).
26 // This does not represent any real backend.
27 for (i = 0; i < num_devices; i++)
28 resources[i] = devices[i];
29 }
30 return num_resources;
31}
32
33extern void *__tgt_omp_alloc(size_t size, omp_allocator_handle_t allocator) {
34 return malloc(size);
35}
36
37extern void __tgt_omp_free(void *ptr, omp_allocator_handle_t allocator) {
38 free(ptr);
39}
40
41// Code above is also used by the corresponding Fortran test
42
43#define CHECK_OR_RET_FAIL(Expr) \
44 do { \
45 if (!(Expr)) \
46 return EXIT_FAILURE; \
47 } while (0)
48
49// Test user-initialized allocator with the given memory space
52 al = omp_init_allocator(ms, 0, NULL);
54 void *m = omp_alloc(1024, al);
55 CHECK_OR_RET_FAIL(m != NULL);
56 omp_free(m, al);
57 omp_destroy_allocator(al);
58 return EXIT_SUCCESS;
59}
60
62 void *m = omp_alloc(1024, al);
63 CHECK_OR_RET_FAIL(m != NULL);
64 omp_free(m, al);
65 omp_destroy_allocator(al);
66 return EXIT_SUCCESS;
67}
68
69static int test_mem_space(void) {
70 int i, count;
71 int num_devices = omp_get_num_devices();
72 CHECK_OR_RET_FAIL(num_devices == NUM_DEVICES);
73
74 int *all_devices = (int *)malloc(sizeof(int) * num_devices);
75 for (i = 0; i < num_devices; i++)
76 all_devices[i] = i;
77
81
82 // Test the following API routines.
83 // * omp_get_device_memspace
84 // * omp_get_device_and_host_memspace
85 // * omp_get_devices_memspace
86 // * omp_get_devices_and_host_memspace
87 // Test if runtime returns the same memory space handle for the same input.
88 // Test if we can use the memory space to intialize allocator.
89 for (i = 0; i < num_devices; i++) {
90 ms1 = omp_get_device_memspace(i, predef);
92 ms2 = omp_get_device_memspace(i, predef);
93 CHECK_OR_RET_FAIL(ms1 == ms2);
94 CHECK_OR_RET_FAIL(test_user_allocator(ms1) == EXIT_SUCCESS);
95 ms1 = ms2 = omp_null_mem_space;
96
97 ms1 = omp_get_device_and_host_memspace(i, predef);
99 ms2 = omp_get_device_and_host_memspace(i, predef);
100 CHECK_OR_RET_FAIL(ms1 == ms2);
101 CHECK_OR_RET_FAIL(test_user_allocator(ms1) == EXIT_SUCCESS);
102 ms1 = ms2 = omp_null_mem_space;
103
104 for (count = 1; i + count <= num_devices; count++) {
105 int *devices = &all_devices[i];
106 ms1 = omp_get_devices_memspace(count, devices, predef);
108 ms2 = omp_get_devices_memspace(count, devices, predef);
109 CHECK_OR_RET_FAIL(ms1 == ms2);
110 CHECK_OR_RET_FAIL(test_user_allocator(ms1) == EXIT_SUCCESS);
111 ms1 = ms2 = omp_null_mem_space;
112
113 ms1 = omp_get_devices_and_host_memspace(count, devices, predef);
115 ms2 = omp_get_devices_and_host_memspace(count, devices, predef);
116 CHECK_OR_RET_FAIL(ms1 == ms2);
117 CHECK_OR_RET_FAIL(test_user_allocator(ms1) == EXIT_SUCCESS);
118 ms1 = ms2 = omp_null_mem_space;
119 }
120 }
121
122 // Test the following API routines.
123 // * omp_get_devices_all_memspace
124 // Test if runtime returns the same memory space handle for the same input.
125 ms1 = omp_get_devices_all_memspace(predef);
127 ms2 = omp_get_devices_all_memspace(predef);
128 CHECK_OR_RET_FAIL(ms1 == ms2);
129
130 free(all_devices);
131
132 return EXIT_SUCCESS;
133}
134
135static int test_mem_allocator(void) {
136 int i, count;
137 int num_devices = omp_get_num_devices();
138 CHECK_OR_RET_FAIL(num_devices == NUM_DEVICES);
139
140 int *all_devices = (int *)malloc(sizeof(int) * num_devices);
141 for (i = 0; i < num_devices; i++)
142 all_devices[i] = i;
143
146
147 // Test the following API routines.
148 // * omp_get_device_allocator
149 // * omp_get_device_and_host_allocator
150 // * omp_get_devices_allocator
151 // * omp_get_devices_and_host_allocator
152 for (i = 0; i < num_devices; i++) {
153 al = omp_get_device_allocator(i, predef);
155 CHECK_OR_RET_FAIL(test_allocator(al) == EXIT_SUCCESS);
157
158 al = omp_get_device_and_host_allocator(i, predef);
160 CHECK_OR_RET_FAIL(test_allocator(al) == EXIT_SUCCESS);
162
163 for (count = 1; i + count <= num_devices; count++) {
164 int *devices = &all_devices[i];
165 al = omp_get_devices_allocator(count, devices, predef);
167 CHECK_OR_RET_FAIL(test_allocator(al) == EXIT_SUCCESS);
169
170 al = omp_get_devices_and_host_allocator(count, devices, predef);
172 CHECK_OR_RET_FAIL(test_allocator(al) == EXIT_SUCCESS);
174 }
175 }
176
177 // Test the following API routines.
178 // * omp_get_devices_all_allocator
179 al = omp_get_devices_all_allocator(predef);
181 CHECK_OR_RET_FAIL(test_allocator(al) == EXIT_SUCCESS);
182
183 free(all_devices);
184
185 return EXIT_SUCCESS;
186}
187
188// Just test what we can expect from the emulated backend.
189static int test_sub_mem_space(void) {
190 int i;
192 ms = omp_get_devices_all_memspace(omp_default_mem_space);
194 int num_resources = omp_get_memspace_num_resources(ms);
195 CHECK_OR_RET_FAIL(num_resources == NUM_DEVICES);
196
197 // Check if single-resource sub memspace is correctly returned.
198 for (i = 0; i < num_resources; i++) {
199 omp_memspace_handle_t sub = omp_get_submemspace(ms, 1, &i);
201 CHECK_OR_RET_FAIL(sub != ms);
202 int num_sub_resources = omp_get_memspace_num_resources(sub);
203 CHECK_OR_RET_FAIL(num_sub_resources == 1);
204 }
205
206 // Check if all-resrouce sub memspace is correctly returned.
207 int *resources = (int *)malloc(sizeof(int) * num_resources);
208 for (i = 0; i < num_resources; i++)
209 resources[i] = i;
210 omp_memspace_handle_t sub = omp_get_submemspace(ms, num_resources, resources);
212 CHECK_OR_RET_FAIL(sub == ms);
213
214 return EXIT_SUCCESS;
215}
216
217int main() {
218 int rc = test_mem_space();
219 CHECK_OR_RET_FAIL(rc == EXIT_SUCCESS);
220
221 rc = test_mem_allocator();
222 CHECK_OR_RET_FAIL(rc == EXIT_SUCCESS);
223
224 rc = test_sub_mem_space();
225 CHECK_OR_RET_FAIL(rc == EXIT_SUCCESS);
226
227 return rc;
228}
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t size
omp_memspace_handle_t const omp_default_mem_space
void * omp_memspace_handle_t
Definition kmp.h:1065
void * omp_allocator_handle_t
Definition kmp.h:1082
omp_memspace_handle_t const omp_null_mem_space
omp_allocator_handle_t const omp_null_allocator
int omp_get_num_devices(void)
sub
void omp_free(void *ptr, omp_allocator_handle_t allocator)
void * omp_alloc(size_t size, omp_allocator_handle_t allocator)
#define i
Definition kmp_stub.cpp:87
void __tgt_omp_free(void *ptr, omp_allocator_handle_t allocator)
int __tgt_get_mem_resources(int num_devices, const int *devices, int host, omp_memspace_handle_t memspace, int *resources)
#define NUM_DEVICES
void * __tgt_omp_alloc(size_t size, omp_allocator_handle_t allocator)
static int test_sub_mem_space(void)
#define CHECK_OR_RET_FAIL(Expr)
int __tgt_get_num_devices(void)
static int test_mem_allocator(void)
static int test_mem_space(void)
static int test_allocator(omp_allocator_handle_t al)
static int test_user_allocator(omp_memspace_handle_t ms)
int main()