oacc-parallel.c revision 1.1.1.2 1 1.1.1.2 mrg /* Copyright (C) 2013-2016 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 mrg {
190 1.1 mrg gomp_copy_from_async (tgt);
191 1.1 mrg acc_dev->openacc.register_async_cleanup_func (tgt);
192 1.1 mrg }
193 1.1 mrg
194 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
195 1.1 mrg }
196 1.1 mrg
197 1.1.1.2 mrg /* Legacy entry point, only provide host execution. */
198 1.1.1.2 mrg
199 1.1.1.2 mrg void
200 1.1.1.2 mrg GOACC_parallel (int device, void (*fn) (void *),
201 1.1.1.2 mrg size_t mapnum, void **hostaddrs, size_t *sizes,
202 1.1.1.2 mrg unsigned short *kinds,
203 1.1.1.2 mrg int num_gangs, int num_workers, int vector_length,
204 1.1.1.2 mrg int async, int num_waits, ...)
205 1.1.1.2 mrg {
206 1.1.1.2 mrg goacc_save_and_set_bind (acc_device_host);
207 1.1.1.2 mrg fn (hostaddrs);
208 1.1.1.2 mrg goacc_restore_bind ();
209 1.1.1.2 mrg }
210 1.1.1.2 mrg
211 1.1 mrg void
212 1.1 mrg GOACC_data_start (int device, size_t mapnum,
213 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds)
214 1.1 mrg {
215 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
216 1.1 mrg struct target_mem_desc *tgt;
217 1.1 mrg
218 1.1 mrg #ifdef HAVE_INTTYPES_H
219 1.1 mrg gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
220 1.1 mrg __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
221 1.1 mrg #else
222 1.1 mrg gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
223 1.1 mrg __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
224 1.1 mrg #endif
225 1.1 mrg
226 1.1 mrg goacc_lazy_initialize ();
227 1.1 mrg
228 1.1 mrg struct goacc_thread *thr = goacc_thread ();
229 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
230 1.1 mrg
231 1.1 mrg /* Host fallback or 'do nothing'. */
232 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
233 1.1 mrg || host_fallback)
234 1.1 mrg {
235 1.1.1.2 mrg tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true,
236 1.1.1.2 mrg GOMP_MAP_VARS_OPENACC);
237 1.1 mrg tgt->prev = thr->mapped_data;
238 1.1 mrg thr->mapped_data = tgt;
239 1.1 mrg
240 1.1 mrg return;
241 1.1 mrg }
242 1.1 mrg
243 1.1 mrg gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
244 1.1 mrg tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
245 1.1.1.2 mrg GOMP_MAP_VARS_OPENACC);
246 1.1 mrg gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
247 1.1 mrg tgt->prev = thr->mapped_data;
248 1.1 mrg thr->mapped_data = tgt;
249 1.1 mrg }
250 1.1 mrg
251 1.1 mrg void
252 1.1 mrg GOACC_data_end (void)
253 1.1 mrg {
254 1.1 mrg struct goacc_thread *thr = goacc_thread ();
255 1.1 mrg struct target_mem_desc *tgt = thr->mapped_data;
256 1.1 mrg
257 1.1 mrg gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
258 1.1 mrg thr->mapped_data = tgt->prev;
259 1.1 mrg gomp_unmap_vars (tgt, true);
260 1.1 mrg gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg void
264 1.1 mrg GOACC_enter_exit_data (int device, size_t mapnum,
265 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds,
266 1.1 mrg int async, int num_waits, ...)
267 1.1 mrg {
268 1.1 mrg struct goacc_thread *thr;
269 1.1 mrg struct gomp_device_descr *acc_dev;
270 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
271 1.1 mrg bool data_enter = false;
272 1.1 mrg size_t i;
273 1.1 mrg
274 1.1 mrg goacc_lazy_initialize ();
275 1.1 mrg
276 1.1 mrg thr = goacc_thread ();
277 1.1 mrg acc_dev = thr->dev;
278 1.1 mrg
279 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
280 1.1 mrg || host_fallback)
281 1.1 mrg return;
282 1.1 mrg
283 1.1.1.2 mrg if (num_waits)
284 1.1 mrg {
285 1.1 mrg va_list ap;
286 1.1 mrg
287 1.1 mrg va_start (ap, num_waits);
288 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
289 1.1 mrg va_end (ap);
290 1.1 mrg }
291 1.1 mrg
292 1.1 mrg acc_dev->openacc.async_set_async_func (async);
293 1.1 mrg
294 1.1 mrg /* Determine if this is an "acc enter data". */
295 1.1 mrg for (i = 0; i < mapnum; ++i)
296 1.1 mrg {
297 1.1 mrg unsigned char kind = kinds[i] & 0xff;
298 1.1 mrg
299 1.1 mrg if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
300 1.1 mrg continue;
301 1.1 mrg
302 1.1 mrg if (kind == GOMP_MAP_FORCE_ALLOC
303 1.1 mrg || kind == GOMP_MAP_FORCE_PRESENT
304 1.1 mrg || kind == GOMP_MAP_FORCE_TO)
305 1.1 mrg {
306 1.1 mrg data_enter = true;
307 1.1 mrg break;
308 1.1 mrg }
309 1.1 mrg
310 1.1.1.2 mrg if (kind == GOMP_MAP_DELETE
311 1.1 mrg || kind == GOMP_MAP_FORCE_FROM)
312 1.1 mrg break;
313 1.1 mrg
314 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
315 1.1 mrg kind);
316 1.1 mrg }
317 1.1 mrg
318 1.1 mrg if (data_enter)
319 1.1 mrg {
320 1.1 mrg for (i = 0; i < mapnum; i++)
321 1.1 mrg {
322 1.1 mrg unsigned char kind = kinds[i] & 0xff;
323 1.1 mrg
324 1.1 mrg /* Scan for PSETs. */
325 1.1 mrg int psets = find_pset (i, mapnum, kinds);
326 1.1 mrg
327 1.1 mrg if (!psets)
328 1.1 mrg {
329 1.1 mrg switch (kind)
330 1.1 mrg {
331 1.1 mrg case GOMP_MAP_POINTER:
332 1.1 mrg gomp_acc_insert_pointer (1, &hostaddrs[i], &sizes[i],
333 1.1 mrg &kinds[i]);
334 1.1 mrg break;
335 1.1 mrg case GOMP_MAP_FORCE_ALLOC:
336 1.1 mrg acc_create (hostaddrs[i], sizes[i]);
337 1.1 mrg break;
338 1.1 mrg case GOMP_MAP_FORCE_PRESENT:
339 1.1 mrg acc_present_or_copyin (hostaddrs[i], sizes[i]);
340 1.1 mrg break;
341 1.1 mrg case GOMP_MAP_FORCE_TO:
342 1.1 mrg acc_present_or_copyin (hostaddrs[i], sizes[i]);
343 1.1 mrg break;
344 1.1 mrg default:
345 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
346 1.1 mrg kind);
347 1.1 mrg break;
348 1.1 mrg }
349 1.1 mrg }
350 1.1 mrg else
351 1.1 mrg {
352 1.1 mrg gomp_acc_insert_pointer (3, &hostaddrs[i], &sizes[i], &kinds[i]);
353 1.1 mrg /* Increment 'i' by two because OpenACC requires fortran
354 1.1 mrg arrays to be contiguous, so each PSET is associated with
355 1.1 mrg one of MAP_FORCE_ALLOC/MAP_FORCE_PRESET/MAP_FORCE_TO, and
356 1.1 mrg one MAP_POINTER. */
357 1.1 mrg i += 2;
358 1.1 mrg }
359 1.1 mrg }
360 1.1 mrg }
361 1.1 mrg else
362 1.1 mrg for (i = 0; i < mapnum; ++i)
363 1.1 mrg {
364 1.1 mrg unsigned char kind = kinds[i] & 0xff;
365 1.1 mrg
366 1.1 mrg int psets = find_pset (i, mapnum, kinds);
367 1.1 mrg
368 1.1 mrg if (!psets)
369 1.1 mrg {
370 1.1 mrg switch (kind)
371 1.1 mrg {
372 1.1 mrg case GOMP_MAP_POINTER:
373 1.1 mrg gomp_acc_remove_pointer (hostaddrs[i], (kinds[i] & 0xff)
374 1.1 mrg == GOMP_MAP_FORCE_FROM,
375 1.1 mrg async, 1);
376 1.1 mrg break;
377 1.1.1.2 mrg case GOMP_MAP_DELETE:
378 1.1 mrg acc_delete (hostaddrs[i], sizes[i]);
379 1.1 mrg break;
380 1.1 mrg case GOMP_MAP_FORCE_FROM:
381 1.1 mrg acc_copyout (hostaddrs[i], sizes[i]);
382 1.1 mrg break;
383 1.1 mrg default:
384 1.1 mrg gomp_fatal (">>>> GOACC_enter_exit_data UNHANDLED kind 0x%.2x",
385 1.1 mrg kind);
386 1.1 mrg break;
387 1.1 mrg }
388 1.1 mrg }
389 1.1 mrg else
390 1.1 mrg {
391 1.1 mrg gomp_acc_remove_pointer (hostaddrs[i], (kinds[i] & 0xff)
392 1.1 mrg == GOMP_MAP_FORCE_FROM, async, 3);
393 1.1 mrg /* See the above comment. */
394 1.1 mrg i += 2;
395 1.1 mrg }
396 1.1 mrg }
397 1.1 mrg
398 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
399 1.1 mrg }
400 1.1 mrg
401 1.1 mrg static void
402 1.1.1.2 mrg goacc_wait (int async, int num_waits, va_list *ap)
403 1.1 mrg {
404 1.1 mrg struct goacc_thread *thr = goacc_thread ();
405 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
406 1.1 mrg
407 1.1.1.2 mrg while (num_waits--)
408 1.1 mrg {
409 1.1.1.2 mrg int qid = va_arg (*ap, int);
410 1.1.1.2 mrg
411 1.1 mrg if (acc_async_test (qid))
412 1.1 mrg continue;
413 1.1 mrg
414 1.1.1.2 mrg if (async == acc_async_sync)
415 1.1.1.2 mrg acc_wait (qid);
416 1.1.1.2 mrg else if (qid == async)
417 1.1.1.2 mrg ;/* If we're waiting on the same asynchronous queue as we're
418 1.1.1.2 mrg launching on, the queue itself will order work as
419 1.1.1.2 mrg required, so there's no need to wait explicitly. */
420 1.1.1.2 mrg else
421 1.1 mrg acc_dev->openacc.async_wait_async_func (qid, async);
422 1.1 mrg }
423 1.1 mrg }
424 1.1 mrg
425 1.1 mrg void
426 1.1 mrg GOACC_update (int device, size_t mapnum,
427 1.1 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds,
428 1.1 mrg int async, int num_waits, ...)
429 1.1 mrg {
430 1.1 mrg bool host_fallback = device == GOMP_DEVICE_HOST_FALLBACK;
431 1.1 mrg size_t i;
432 1.1 mrg
433 1.1 mrg goacc_lazy_initialize ();
434 1.1 mrg
435 1.1 mrg struct goacc_thread *thr = goacc_thread ();
436 1.1 mrg struct gomp_device_descr *acc_dev = thr->dev;
437 1.1 mrg
438 1.1 mrg if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
439 1.1 mrg || host_fallback)
440 1.1 mrg return;
441 1.1 mrg
442 1.1.1.2 mrg if (num_waits)
443 1.1 mrg {
444 1.1 mrg va_list ap;
445 1.1 mrg
446 1.1 mrg va_start (ap, num_waits);
447 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
448 1.1 mrg va_end (ap);
449 1.1 mrg }
450 1.1 mrg
451 1.1 mrg acc_dev->openacc.async_set_async_func (async);
452 1.1 mrg
453 1.1 mrg for (i = 0; i < mapnum; ++i)
454 1.1 mrg {
455 1.1 mrg unsigned char kind = kinds[i] & 0xff;
456 1.1 mrg
457 1.1 mrg switch (kind)
458 1.1 mrg {
459 1.1 mrg case GOMP_MAP_POINTER:
460 1.1 mrg case GOMP_MAP_TO_PSET:
461 1.1 mrg break;
462 1.1 mrg
463 1.1 mrg case GOMP_MAP_FORCE_TO:
464 1.1 mrg acc_update_device (hostaddrs[i], sizes[i]);
465 1.1 mrg break;
466 1.1 mrg
467 1.1 mrg case GOMP_MAP_FORCE_FROM:
468 1.1 mrg acc_update_self (hostaddrs[i], sizes[i]);
469 1.1 mrg break;
470 1.1 mrg
471 1.1 mrg default:
472 1.1 mrg gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
473 1.1 mrg break;
474 1.1 mrg }
475 1.1 mrg }
476 1.1 mrg
477 1.1 mrg acc_dev->openacc.async_set_async_func (acc_async_sync);
478 1.1 mrg }
479 1.1 mrg
480 1.1 mrg void
481 1.1 mrg GOACC_wait (int async, int num_waits, ...)
482 1.1 mrg {
483 1.1.1.2 mrg if (num_waits)
484 1.1.1.2 mrg {
485 1.1.1.2 mrg va_list ap;
486 1.1 mrg
487 1.1.1.2 mrg va_start (ap, num_waits);
488 1.1.1.2 mrg goacc_wait (async, num_waits, &ap);
489 1.1.1.2 mrg va_end (ap);
490 1.1.1.2 mrg }
491 1.1.1.2 mrg else if (async == acc_async_sync)
492 1.1.1.2 mrg acc_wait_all ();
493 1.1.1.2 mrg else if (async == acc_async_noval)
494 1.1.1.2 mrg goacc_thread ()->dev->openacc.async_wait_all_async_func (acc_async_noval);
495 1.1 mrg }
496 1.1 mrg
497 1.1 mrg int
498 1.1 mrg GOACC_get_num_threads (void)
499 1.1 mrg {
500 1.1 mrg return 1;
501 1.1 mrg }
502 1.1 mrg
503 1.1 mrg int
504 1.1 mrg GOACC_get_thread_num (void)
505 1.1 mrg {
506 1.1 mrg return 0;
507 1.1 mrg }
508 1.1.1.2 mrg
509 1.1.1.2 mrg void
510 1.1.1.2 mrg GOACC_declare (int device, size_t mapnum,
511 1.1.1.2 mrg void **hostaddrs, size_t *sizes, unsigned short *kinds)
512 1.1.1.2 mrg {
513 1.1.1.2 mrg int i;
514 1.1.1.2 mrg
515 1.1.1.2 mrg for (i = 0; i < mapnum; i++)
516 1.1.1.2 mrg {
517 1.1.1.2 mrg unsigned char kind = kinds[i] & 0xff;
518 1.1.1.2 mrg
519 1.1.1.2 mrg if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
520 1.1.1.2 mrg continue;
521 1.1.1.2 mrg
522 1.1.1.2 mrg switch (kind)
523 1.1.1.2 mrg {
524 1.1.1.2 mrg case GOMP_MAP_FORCE_ALLOC:
525 1.1.1.2 mrg case GOMP_MAP_FORCE_FROM:
526 1.1.1.2 mrg case GOMP_MAP_FORCE_TO:
527 1.1.1.2 mrg case GOMP_MAP_POINTER:
528 1.1.1.2 mrg case GOMP_MAP_DELETE:
529 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
530 1.1.1.2 mrg &kinds[i], 0, 0);
531 1.1.1.2 mrg break;
532 1.1.1.2 mrg
533 1.1.1.2 mrg case GOMP_MAP_FORCE_DEVICEPTR:
534 1.1.1.2 mrg break;
535 1.1.1.2 mrg
536 1.1.1.2 mrg case GOMP_MAP_ALLOC:
537 1.1.1.2 mrg if (!acc_is_present (hostaddrs[i], sizes[i]))
538 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
539 1.1.1.2 mrg &kinds[i], 0, 0);
540 1.1.1.2 mrg break;
541 1.1.1.2 mrg
542 1.1.1.2 mrg case GOMP_MAP_TO:
543 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
544 1.1.1.2 mrg &kinds[i], 0, 0);
545 1.1.1.2 mrg
546 1.1.1.2 mrg break;
547 1.1.1.2 mrg
548 1.1.1.2 mrg case GOMP_MAP_FROM:
549 1.1.1.2 mrg kinds[i] = GOMP_MAP_FORCE_FROM;
550 1.1.1.2 mrg GOACC_enter_exit_data (device, 1, &hostaddrs[i], &sizes[i],
551 1.1.1.2 mrg &kinds[i], 0, 0);
552 1.1.1.2 mrg break;
553 1.1.1.2 mrg
554 1.1.1.2 mrg case GOMP_MAP_FORCE_PRESENT:
555 1.1.1.2 mrg if (!acc_is_present (hostaddrs[i], sizes[i]))
556 1.1.1.2 mrg gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
557 1.1.1.2 mrg (unsigned long) sizes[i]);
558 1.1.1.2 mrg break;
559 1.1.1.2 mrg
560 1.1.1.2 mrg default:
561 1.1.1.2 mrg assert (0);
562 1.1.1.2 mrg break;
563 1.1.1.2 mrg }
564 1.1.1.2 mrg }
565 1.1.1.2 mrg }
566