oacc-parallel.c revision 1.1.1.2.4.2 1 1.1.1.2.4.2 martin /* Copyright (C) 2013-2018 Free Software Foundation, Inc.
2 1.1 mrg
3 1.1 mrg Contributed by Mentor Embedded.
4 1.1 mrg
5 1.1 mrg This file is part of the GNU Offloading and Multi Processing Library
6 1.1 mrg (libgomp).
7 1.1 mrg
8 1.1 mrg Libgomp is free software; you can redistribute it and/or modify it
9 1.1 mrg under the terms of the GNU General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
11 1.1 mrg any later version.
12 1.1 mrg
13 1.1 mrg Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
14 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 1.1 mrg FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 1.1 mrg more details.
17 1.1 mrg
18 1.1 mrg Under Section 7 of GPL version 3, you are granted additional
19 1.1 mrg permissions described in the GCC Runtime Library Exception, version
20 1.1 mrg 3.1, as published by the Free Software Foundation.
21 1.1 mrg
22 1.1 mrg You should have received a copy of the GNU General Public License and
23 1.1 mrg a copy of the GCC Runtime Library Exception along with this program;
24 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 1.1 mrg <http://www.gnu.org/licenses/>. */
26 1.1 mrg
27 1.1 mrg /* This file handles OpenACC constructs. */
28 1.1 mrg
29 1.1 mrg #include "openacc.h"
30 1.1 mrg #include "libgomp.h"
31 1.1 mrg #include "libgomp_g.h"
32 1.1 mrg #include "gomp-constants.h"
33 1.1 mrg #include "oacc-int.h"
34 1.1 mrg #ifdef HAVE_INTTYPES_H
35 1.1 mrg # include <inttypes.h> /* For PRIu64. */
36 1.1 mrg #endif
37 1.1 mrg #include <string.h>
38 1.1 mrg #include <stdarg.h>
39 1.1 mrg #include <assert.h>
40 1.1 mrg
41 1.1 mrg static int
42 1.1 mrg find_pset (int pos, size_t mapnum, unsigned short *kinds)
43 1.1 mrg {
44 1.1 mrg if (pos + 1 >= mapnum)
45 1.1 mrg return 0;
46 1.1 mrg
47 1.1 mrg unsigned char kind = kinds[pos+1] & 0xff;
48 1.1 mrg
49 1.1 mrg return kind == GOMP_MAP_TO_PSET;
50 1.1 mrg }
51 1.1 mrg
52 1.1.1.2 mrg static void goacc_wait (int async, int num_waits, va_list *ap);
53 1.1.1.2 mrg
54 1.1.1.2 mrg
55 1.1.1.2 mrg /* Launch a possibly offloaded function on DEVICE. FN is the host fn
56 1.1.1.2 mrg address. MAPNUM, HOSTADDRS, SIZES & KINDS describe the memory
57 1.1.1.2 mrg blocks to be copied to/from the device. Varadic arguments are
58 1.1.1.2 mrg keyed optional parameters terminated with a zero. */
59 1.1 mrg
60 1.1 mrg void
61 1.1.1.2 mrg GOACC_parallel_keyed (int device, void (*fn) (void *),
62 1.1.1.2 mrg size_t mapnum, void **hostaddrs, size_t *sizes,
63 1.1.1.2 mrg unsigned short *kinds, ...)
64 1.1 mrg {
65 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
66 1.1 mrg va_list ap;
67 1.1 mrg struct goacc_thread *thr;
68 1.1 mrg struct gomp_device_descr *acc_dev;
69 1.1 mrg struct target_mem_desc *tgt;
70 1.1 mrg void **devaddrs;
71 1.1 mrg unsigned int i;
72 1.1 mrg struct splay_tree_key_s k;
73 1.1 mrg splay_tree_key tgt_fn_key;
74 1.1 mrg void (*tgt_fn);
75 1.1.1.2 mrg int async = GOMP_ASYNC_SYNC;
76 1.1.1.2 mrg unsigned dims[GOMP_DIM_MAX];
77 1.1.1.2 mrg unsigned tag;
78 1.1 mrg
79 1.1 mrg #ifdef HAVE_INTTYPES_H
80 1.1.1.2 mrg gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
81 1.1.1.2 mrg __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
82 1.1 mrg #else
83 1.1.1.2 mrg gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
84 1.1.1.2 mrg __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
85 1.1 mrg #endif
86 1.1 mrg goacc_lazy_initialize ();
87 1.1 mrg
88 1.1 mrg thr = goacc_thread ();
89 1.1 mrg acc_dev = thr->dev;
90 1.1 mrg
91 1.1 mrg /* Host fallback if "if" clause is false or if the current device is set to
92 1.1 mrg the host. */
93 1.1 mrg if (host_fallback)
94 1.1 mrg {
95 1.1 mrg goacc_save_and_set_bind (acc_device_host);
96 1.1 mrg fn (hostaddrs);
97 1.1 mrg goacc_restore_bind ();
98 1.1 mrg return;
99 1.1 mrg }
100 1.1 mrg else if (acc_device_type (acc_dev->type) == acc_device_host)
101 1.1 mrg {
102 1.1 mrg fn (hostaddrs);
103 1.1 mrg return;
104 1.1 mrg }
105 1.1 mrg
106 1.1.1.2 mrg /* Default: let the runtime choose. */
107 1.1.1.2 mrg for (i = 0; i != GOMP_DIM_MAX; i++)
108 1.1.1.2 mrg dims[i] = 0;
109 1.1.1.2 mrg
110 1.1.1.2 mrg va_start (ap, kinds);
111 1.1.1.2 mrg /* TODO: This will need amending when device_type is implemented. */
112 1.1.1.2 mrg while ((tag = va_arg (ap, unsigned)) != 0)
113 1.1.1.2 mrg {
114 1.1.1.2 mrg if (GOMP_LAUNCH_DEVICE (tag))
115 1.1.1.2 mrg gomp_fatal ("device_type '%d' offload parameters, libgomp is too old",
116 1.1.1.2 mrg GOMP_LAUNCH_DEVICE (tag));
117 1.1 mrg
118 1.1.1.2 mrg switch (GOMP_LAUNCH_CODE (tag))
119 1.1.1.2 mrg {
120 1.1.1.2 mrg case GOMP_LAUNCH_DIM:
121 1.1.1.2 mrg {
122 1.1.1.2 mrg unsigned mask = GOMP_LAUNCH_OP (tag);
123 1.1.1.2 mrg
124 1.1.1.2 mrg for (i = 0; i != GOMP_DIM_MAX; i++)
125 1.1.1.2 mrg if (mask & GOMP_DIM_MASK (i))
126 1.1.1.2 mrg dims[i] = va_arg (ap, unsigned);
127 1.1.1.2 mrg }
128 1.1.1.2 mrg break;
129 1.1.1.2 mrg
130 1.1.1.2 mrg case GOMP_LAUNCH_ASYNC:
131 1.1.1.2 mrg {
132 1.1.1.2 mrg /* Small constant values are encoded in the operand. */
133 1.1.1.2 mrg async = GOMP_LAUNCH_OP (tag);
134 1.1.1.2 mrg
135 1.1.1.2 mrg if (async == GOMP_LAUNCH_OP_MAX)
136 1.1.1.2 mrg async = va_arg (ap, unsigned);
137 1.1.1.2 mrg break;
138 1.1.1.2 mrg }
139 1.1 mrg
140 1.1.1.2 mrg case GOMP_LAUNCH_WAIT:
141 1.1.1.2 mrg {
142 1.1.1.2 mrg unsigned num_waits = GOMP_LAUNCH_OP (tag);
143 1.1.1.2 mrg
144 1.1.1.2 mrg if (num_waits)
145 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
146 1.1.1.2 mrg break;
147 1.1.1.2 mrg }
148 1.1.1.2 mrg
149 1.1.1.2 mrg default:
150 1.1.1.2 mrg gomp_fatal ("unrecognized offload code '%d',"
151 1.1.1.2 mrg " libgomp is too old", GOMP_LAUNCH_CODE (tag));
152 1.1.1.2 mrg }
153 1.1.1.2 mrg }
154 1.1.1.2 mrg va_end (ap);
155 1.1.1.2 mrg
156 1.1 mrg acc_dev->openacc.async_set_async_func (async);
157 1.1 mrg
158 1.1 mrg if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
159 1.1 mrg {
160 1.1 mrg k.host_start = (uintptr_t) fn;
161 1.1 mrg k.host_end = k.host_start + 1;
162 1.1 mrg gomp_mutex_lock (&acc_dev->lock);
163 1.1 mrg tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k);
164 1.1 mrg gomp_mutex_unlock (&acc_dev->lock);
165 1.1 mrg
166 1.1 mrg if (tgt_fn_key == NULL)
167 1.1 mrg gomp_fatal ("target function wasn't mapped");
168 1.1 mrg
169 1.1 mrg tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
170 1.1 mrg }
171 1.1 mrg else
172 1.1 mrg tgt_fn = (void (*)) fn;
173 1.1 mrg
174 1.1 mrg tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
175 1.1.1.2 mrg GOMP_MAP_VARS_OPENACC);
176 1.1 mrg
177 1.1 mrg devaddrs = gomp_alloca (sizeof (void *) * mapnum);
178 1.1 mrg for (i = 0; i < mapnum; i++)
179 1.1.1.2 mrg devaddrs[i] = (void *) (tgt->list[i].key->tgt->tgt_start
180 1.1.1.2 mrg + tgt->list[i].key->tgt_offset);
181 1.1 mrg
182 1.1.1.2 mrg acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
183 1.1.1.2 mrg async, dims, tgt);
184 1.1 mrg
185 1.1 mrg /* If running synchronously, unmap immediately. */
186 1.1 mrg if (async < acc_async_noval)
187 1.1 mrg gomp_unmap_vars (tgt, true);
188 1.1 mrg else
189 1.1.1.2.4.1 christos tgt->device_descr->openacc.register_async_cleanup_func (tgt, async);
190 1.1 mrg
191 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
192 1.1 mrg }
193 1.1 mrg
194 1.1.1.2 mrg /* Legacy entry point, only provide host execution. */
195 1.1.1.2 mrg
196 1.1.1.2 mrg void
197 1.1.1.2 mrg GOACC_parallel (int device, void (*fn) (void *),
198 1.1.1.2 mrg size_t mapnum, void **hostaddrs, size_t *sizes,
199 1.1.1.2 mrg unsigned short *kinds,
200 1.1.1.2 mrg int num_gangs, int num_workers, int vector_length,
201 1.1.1.2 mrg int async, int num_waits, ...)
202 1.1.1.2 mrg {
203 1.1.1.2 mrg goacc_save_and_set_bind (acc_device_host);
204 1.1.1.2 mrg fn (hostaddrs);
205 1.1.1.2 mrg goacc_restore_bind ();
206 1.1.1.2 mrg }
207 1.1.1.2 mrg
208 1.1 mrg void
209 1.1 mrg GOACC_data_start (int device, size_t mapnum,
210 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds)
211 1.1 mrg {
212 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
213 1.1 mrg struct target_mem_desc *tgt;
214 1.1 mrg
215 1.1 mrg #ifdef HAVE_INTTYPES_H
216 1.1 mrg gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
217 1.1 mrg __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
218 1.1 mrg #else
219 1.1 mrg gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
220 1.1 mrg __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
221 1.1 mrg #endif
222 1.1 mrg
223 1.1 mrg goacc_lazy_initialize ();
224 1.1 mrg
225 1.1 mrg struct goacc_thread *thr = goacc_thread ();
226 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
227 1.1 mrg
228 1.1 mrg /* Host fallback or 'do nothing'. */
229 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
230 1.1 mrg || host_fallback)
231 1.1 mrg {
232 1.1.1.2 mrg tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true,
233 1.1.1.2 mrg GOMP_MAP_VARS_OPENACC);
234 1.1 mrg tgt->prev = thr->mapped_data;
235 1.1 mrg thr->mapped_data = tgt;
236 1.1 mrg
237 1.1 mrg return;
238 1.1 mrg }
239 1.1 mrg
240 1.1 mrg gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
241 1.1 mrg tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
242 1.1.1.2 mrg GOMP_MAP_VARS_OPENACC);
243 1.1 mrg gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
244 1.1 mrg tgt->prev = thr->mapped_data;
245 1.1 mrg thr->mapped_data = tgt;
246 1.1 mrg }
247 1.1 mrg
248 1.1 mrg void
249 1.1 mrg GOACC_data_end (void)
250 1.1 mrg {
251 1.1 mrg struct goacc_thread *thr = goacc_thread ();
252 1.1 mrg struct target_mem_desc *tgt = thr->mapped_data;
253 1.1 mrg
254 1.1 mrg gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
255 1.1 mrg thr->mapped_data = tgt->prev;
256 1.1 mrg gomp_unmap_vars (tgt, true);
257 1.1 mrg gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
258 1.1 mrg }
259 1.1 mrg
260 1.1 mrg void
261 1.1 mrg GOACC_enter_exit_data (int device, size_t mapnum,
262 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds,
263 1.1 mrg int async, int num_waits, ...)
264 1.1 mrg {
265 1.1 mrg struct goacc_thread *thr;
266 1.1 mrg struct gomp_device_descr *acc_dev;
267 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
268 1.1 mrg bool data_enter = false;
269 1.1 mrg size_t i;
270 1.1 mrg
271 1.1 mrg goacc_lazy_initialize ();
272 1.1 mrg
273 1.1 mrg thr = goacc_thread ();
274 1.1 mrg acc_dev = thr->dev;
275 1.1 mrg
276 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
277 1.1 mrg || host_fallback)
278 1.1 mrg return;
279 1.1 mrg
280 1.1.1.2 mrg if (num_waits)
281 1.1 mrg {
282 1.1 mrg va_list ap;
283 1.1 mrg
284 1.1 mrg va_start (ap, num_waits);
285 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
286 1.1 mrg va_end (ap);
287 1.1 mrg }
288 1.1 mrg
289 1.1 mrg acc_dev->openacc.async_set_async_func (async);
290 1.1 mrg
291 1.1 mrg /* Determine if this is an "acc enter data". */
292 1.1 mrg for (i = 0; i < mapnum; ++i)
293 1.1 mrg {
294 1.1 mrg unsigned char kind = kinds[i] & 0xff;
295 1.1 mrg
296 1.1 mrg if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
297 1.1 mrg continue;
298 1.1 mrg
299 1.1 mrg if (kind == GOMP_MAP_FORCE_ALLOC
300 1.1 mrg || kind == GOMP_MAP_FORCE_PRESENT
301 1.1 mrg || kind == GOMP_MAP_FORCE_TO)
302 1.1 mrg {
303 1.1 mrg data_enter = true;
304 1.1 mrg break;
305 1.1 mrg }
306 1.1 mrg
307 1.1.1.2 mrg if (kind == GOMP_MAP_DELETE
308 1.1 mrg || kind == GOMP_MAP_FORCE_FROM)
309 1.1 mrg break;
310 1.1 mrg
311 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
312 1.1 mrg kind);
313 1.1 mrg }
314 1.1 mrg
315 1.1 mrg if (data_enter)
316 1.1 mrg {
317 1.1 mrg for (i = 0; i < mapnum; i++)
318 1.1 mrg {
319 1.1 mrg unsigned char kind = kinds[i] & 0xff;
320 1.1 mrg
321 1.1 mrg /* Scan for PSETs. */
322 1.1 mrg int psets = find_pset (i, mapnum, kinds);
323 1.1 mrg
324 1.1 mrg if (!psets)
325 1.1 mrg {
326 1.1 mrg switch (kind)
327 1.1 mrg {
328 1.1 mrg case GOMP_MAP_POINTER:
329 1.1 mrg gomp_acc_insert_pointer (1, &hostaddrs[i], &sizes[i],
330 1.1 mrg &kinds[i]);
331 1.1 mrg break;
332 1.1 mrg case GOMP_MAP_FORCE_ALLOC:
333 1.1 mrg acc_create (hostaddrs[i], sizes[i]);
334 1.1 mrg break;
335 1.1 mrg case GOMP_MAP_FORCE_PRESENT:
336 1.1 mrg acc_present_or_copyin (hostaddrs[i], sizes[i]);
337 1.1 mrg break;
338 1.1 mrg case GOMP_MAP_FORCE_TO:
339 1.1 mrg acc_present_or_copyin (hostaddrs[i], sizes[i]);
340 1.1 mrg break;
341 1.1 mrg default:
342 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
343 1.1 mrg kind);
344 1.1 mrg break;
345 1.1 mrg }
346 1.1 mrg }
347 1.1 mrg else
348 1.1 mrg {
349 1.1 mrg gomp_acc_insert_pointer (3, &hostaddrs[i], &sizes[i], &kinds[i]);
350 1.1 mrg /* Increment 'i' by two because OpenACC requires fortran
351 1.1 mrg arrays to be contiguous, so each PSET is associated with
352 1.1 mrg one of MAP_FORCE_ALLOC/MAP_FORCE_PRESET/MAP_FORCE_TO, and
353 1.1 mrg one MAP_POINTER. */
354 1.1 mrg i += 2;
355 1.1 mrg }
356 1.1 mrg }
357 1.1 mrg }
358 1.1 mrg else
359 1.1 mrg for (i = 0; i < mapnum; ++i)
360 1.1 mrg {
361 1.1 mrg unsigned char kind = kinds[i] & 0xff;
362 1.1 mrg
363 1.1 mrg int psets = find_pset (i, mapnum, kinds);
364 1.1 mrg
365 1.1 mrg if (!psets)
366 1.1 mrg {
367 1.1 mrg switch (kind)
368 1.1 mrg {
369 1.1 mrg case GOMP_MAP_POINTER:
370 1.1 mrg gomp_acc_remove_pointer (hostaddrs[i], (kinds[i] & 0xff)
371 1.1 mrg == GOMP_MAP_FORCE_FROM,
372 1.1 mrg async, 1);
373 1.1 mrg break;
374 1.1.1.2 mrg case GOMP_MAP_DELETE:
375 1.1 mrg acc_delete (hostaddrs[i], sizes[i]);
376 1.1 mrg break;
377 1.1 mrg case GOMP_MAP_FORCE_FROM:
378 1.1 mrg acc_copyout (hostaddrs[i], sizes[i]);
379 1.1 mrg break;
380 1.1 mrg default:
381 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
382 1.1 mrg kind);
383 1.1 mrg break;
384 1.1 mrg }
385 1.1 mrg }
386 1.1 mrg else
387 1.1 mrg {
388 1.1 mrg gomp_acc_remove_pointer (hostaddrs[i], (kinds[i] & 0xff)
389 1.1 mrg == GOMP_MAP_FORCE_FROM, async, 3);
390 1.1 mrg /* See the above comment. */
391 1.1 mrg i += 2;
392 1.1 mrg }
393 1.1 mrg }
394 1.1 mrg
395 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
396 1.1 mrg }
397 1.1 mrg
398 1.1 mrg static void
399 1.1.1.2 mrg goacc_wait (int async, int num_waits, va_list *ap)
400 1.1 mrg {
401 1.1 mrg struct goacc_thread *thr = goacc_thread ();
402 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
403 1.1 mrg
404 1.1.1.2 mrg while (num_waits--)
405 1.1 mrg {
406 1.1.1.2 mrg int qid = va_arg (*ap, int);
407 1.1.1.2 mrg
408 1.1 mrg if (acc_async_test (qid))
409 1.1 mrg continue;
410 1.1 mrg
411 1.1.1.2 mrg if (async == acc_async_sync)
412 1.1.1.2 mrg acc_wait (qid);
413 1.1.1.2 mrg else if (qid == async)
414 1.1.1.2 mrg ;/* If we're waiting on the same asynchronous queue as we're
415 1.1.1.2 mrg launching on, the queue itself will order work as
416 1.1.1.2 mrg required, so there's no need to wait explicitly. */
417 1.1.1.2 mrg else
418 1.1 mrg acc_dev->openacc.async_wait_async_func (qid, async);
419 1.1 mrg }
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg void
423 1.1 mrg GOACC_update (int device, size_t mapnum,
424 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds,
425 1.1 mrg int async, int num_waits, ...)
426 1.1 mrg {
427 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
428 1.1 mrg size_t i;
429 1.1 mrg
430 1.1 mrg goacc_lazy_initialize ();
431 1.1 mrg
432 1.1 mrg struct goacc_thread *thr = goacc_thread ();
433 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
434 1.1 mrg
435 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
436 1.1 mrg || host_fallback)
437 1.1 mrg return;
438 1.1 mrg
439 1.1.1.2 mrg if (num_waits)
440 1.1 mrg {
441 1.1 mrg va_list ap;
442 1.1 mrg
443 1.1 mrg va_start (ap, num_waits);
444 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
445 1.1 mrg va_end (ap);
446 1.1 mrg }
447 1.1 mrg
448 1.1 mrg acc_dev->openacc.async_set_async_func (async);
449 1.1 mrg
450 1.1 mrg for (i = 0; i < mapnum; ++i)
451 1.1 mrg {
452 1.1 mrg unsigned char kind = kinds[i] & 0xff;
453 1.1 mrg
454 1.1 mrg switch (kind)
455 1.1 mrg {
456 1.1 mrg case GOMP_MAP_POINTER:
457 1.1 mrg case GOMP_MAP_TO_PSET:
458 1.1 mrg break;
459 1.1 mrg
460 1.1 mrg case GOMP_MAP_FORCE_TO:
461 1.1 mrg acc_update_device (hostaddrs[i], sizes[i]);
462 1.1 mrg break;
463 1.1 mrg
464 1.1 mrg case GOMP_MAP_FORCE_FROM:
465 1.1 mrg acc_update_self (hostaddrs[i], sizes[i]);
466 1.1 mrg break;
467 1.1 mrg
468 1.1 mrg default:
469 1.1 mrg gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
470 1.1 mrg break;
471 1.1 mrg }
472 1.1 mrg }
473 1.1 mrg
474 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
475 1.1 mrg }
476 1.1 mrg
477 1.1 mrg void
478 1.1 mrg GOACC_wait (int async, int num_waits, ...)
479 1.1 mrg {
480 1.1.1.2 mrg if (num_waits)
481 1.1.1.2 mrg {
482 1.1.1.2 mrg va_list ap;
483 1.1 mrg
484 1.1.1.2 mrg va_start (ap, num_waits);
485 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
486 1.1.1.2 mrg va_end (ap);
487 1.1.1.2 mrg }
488 1.1.1.2 mrg else if (async == acc_async_sync)
489 1.1.1.2 mrg acc_wait_all ();
490 1.1.1.2 mrg else if (async == acc_async_noval)
491 1.1.1.2 mrg goacc_thread ()->dev->openacc.async_wait_all_async_func (acc_async_noval);
492 1.1 mrg }
493 1.1 mrg
494 1.1 mrg int
495 1.1 mrg GOACC_get_num_threads (void)
496 1.1 mrg {
497 1.1 mrg return 1;
498 1.1 mrg }
499 1.1 mrg
500 1.1 mrg int
501 1.1 mrg GOACC_get_thread_num (void)
502 1.1 mrg {
503 1.1 mrg return 0;
504 1.1 mrg }
505 1.1.1.2 mrg
506 1.1.1.2 mrg void
507 1.1.1.2 mrg GOACC_declare (int device, size_t mapnum,
508 1.1.1.2 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds)
509 1.1.1.2 mrg {
510 1.1.1.2 mrg int i;
511 1.1.1.2 mrg
512 1.1.1.2 mrg for (i = 0; i < mapnum; i++)
513 1.1.1.2 mrg {
514 1.1.1.2 mrg unsigned char kind = kinds[i] & 0xff;
515 1.1.1.2 mrg
516 1.1.1.2 mrg if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
517 1.1.1.2 mrg continue;
518 1.1.1.2 mrg
519 1.1.1.2 mrg switch (kind)
520 1.1.1.2 mrg {
521 1.1.1.2 mrg case GOMP_MAP_FORCE_ALLOC:
522 1.1.1.2 mrg case GOMP_MAP_FORCE_FROM:
523 1.1.1.2 mrg case GOMP_MAP_FORCE_TO:
524 1.1.1.2 mrg case GOMP_MAP_POINTER:
525 1.1.1.2 mrg case GOMP_MAP_DELETE:
526 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
527 1.1.1.2 mrg &kinds[i], 0, 0);
528 1.1.1.2 mrg break;
529 1.1.1.2 mrg
530 1.1.1.2 mrg case GOMP_MAP_FORCE_DEVICEPTR:
531 1.1.1.2 mrg break;
532 1.1.1.2 mrg
533 1.1.1.2 mrg case GOMP_MAP_ALLOC:
534 1.1.1.2 mrg if (!acc_is_present (hostaddrs[i], sizes[i]))
535 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
536 1.1.1.2 mrg &kinds[i], 0, 0);
537 1.1.1.2 mrg break;
538 1.1.1.2 mrg
539 1.1.1.2 mrg case GOMP_MAP_TO:
540 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
541 1.1.1.2 mrg &kinds[i], 0, 0);
542 1.1.1.2 mrg
543 1.1.1.2 mrg break;
544 1.1.1.2 mrg
545 1.1.1.2 mrg case GOMP_MAP_FROM:
546 1.1.1.2 mrg kinds[i] = GOMP_MAP_FORCE_FROM;
547 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
548 1.1.1.2 mrg &kinds[i], 0, 0);
549 1.1.1.2 mrg break;
550 1.1.1.2 mrg
551 1.1.1.2 mrg case GOMP_MAP_FORCE_PRESENT:
552 1.1.1.2 mrg if (!acc_is_present (hostaddrs[i], sizes[i]))
553 1.1.1.2 mrg gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
554 1.1.1.2 mrg (unsigned long) sizes[i]);
555 1.1.1.2 mrg break;
556 1.1.1.2 mrg
557 1.1.1.2 mrg default:
558 1.1.1.2 mrg assert (0);
559 1.1.1.2 mrg break;
560 1.1.1.2 mrg }
561 1.1.1.2 mrg }
562 1.1.1.2 mrg }
563