ada: Fix infinite loop with multiple limited with clauses
[official-gcc.git] / libgomp / oacc-parallel.c
blob363e6656982584bf269921be2c0f957182aa8ac9
1 /* Copyright (C) 2013-2023 Free Software Foundation, Inc.
3 Contributed by Mentor Embedded.
5 This file is part of the GNU Offloading and Multi Processing Library
6 (libgomp).
8 Libgomp is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
13 Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 more details.
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25 <http://www.gnu.org/licenses/>. */
27 /* This file handles OpenACC constructs. */
29 #include "openacc.h"
30 #include "libgomp.h"
31 #include "gomp-constants.h"
32 #include "oacc-int.h"
33 #ifdef HAVE_INTTYPES_H
34 # include <inttypes.h> /* For PRIu64. */
35 #endif
36 #include <string.h>
37 #include <stdarg.h>
38 #include <assert.h>
41 /* In the ABI, the GOACC_FLAGs are encoded as an inverted bitmask, so that we
42 continue to support the following two legacy values. */
43 _Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_ICV) == 0,
44 "legacy GOMP_DEVICE_ICV broken");
45 _Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_HOST_FALLBACK)
46 == GOACC_FLAG_HOST_FALLBACK,
47 "legacy GOMP_DEVICE_HOST_FALLBACK broken");
50 /* Handle the mapping pair that are presented when a
51 deviceptr clause is used with Fortran. */
53 static void
54 handle_ftn_pointers (size_t mapnum, void **hostaddrs, size_t *sizes,
55 unsigned short *kinds)
57 int i;
59 for (i = 0; i < mapnum; i++)
61 unsigned short kind1 = kinds[i] & 0xff;
63 /* Handle Fortran deviceptr clause. */
64 if (kind1 == GOMP_MAP_FORCE_DEVICEPTR)
66 unsigned short kind2;
68 if (i < (signed)mapnum - 1)
69 kind2 = kinds[i + 1] & 0xff;
70 else
71 kind2 = 0xffff;
73 if (sizes[i] == sizeof (void *))
74 continue;
76 /* At this point, we're dealing with a Fortran deviceptr.
77 If the next element is not what we're expecting, then
78 this is an instance of where the deviceptr variable was
79 not used within the region and the pointer was removed
80 by the gimplifier. */
81 if (kind2 == GOMP_MAP_POINTER
82 && sizes[i + 1] == 0
83 && hostaddrs[i] == *(void **)hostaddrs[i + 1])
85 kinds[i+1] = kinds[i];
86 sizes[i+1] = sizeof (void *);
89 /* Invalidate the entry. */
90 hostaddrs[i] = NULL;
96 /* Launch a possibly offloaded function with FLAGS. FN is the host fn
97 address. MAPNUM, HOSTADDRS, SIZES & KINDS describe the memory
98 blocks to be copied to/from the device. Varadic arguments are
99 keyed optional parameters terminated with a zero. */
101 void
102 GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
103 size_t mapnum, void **hostaddrs, size_t *sizes,
104 unsigned short *kinds, ...)
106 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
108 va_list ap;
109 struct goacc_thread *thr;
110 struct gomp_device_descr *acc_dev;
111 unsigned int i;
112 struct splay_tree_key_s k;
113 splay_tree_key tgt_fn_key;
114 void (*tgt_fn);
115 int async = GOMP_ASYNC_SYNC;
116 unsigned dims[GOMP_DIM_MAX];
117 unsigned tag;
119 #ifdef HAVE_INTTYPES_H
120 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
121 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
122 #else
123 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
124 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
125 #endif
126 goacc_lazy_initialize ();
128 thr = goacc_thread ();
129 acc_dev = thr->dev;
131 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
133 acc_prof_info prof_info;
134 if (profiling_p)
136 thr->prof_info = &prof_info;
138 prof_info.event_type = acc_ev_compute_construct_start;
139 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
140 prof_info.version = _ACC_PROF_INFO_VERSION;
141 prof_info.device_type = acc_device_type (acc_dev->type);
142 prof_info.device_number = acc_dev->target_id;
143 prof_info.thread_id = -1;
144 prof_info.async = async;
145 prof_info.async_queue = prof_info.async;
146 prof_info.src_file = NULL;
147 prof_info.func_name = NULL;
148 prof_info.line_no = -1;
149 prof_info.end_line_no = -1;
150 prof_info.func_line_no = -1;
151 prof_info.func_end_line_no = -1;
153 acc_event_info compute_construct_event_info;
154 if (profiling_p)
156 compute_construct_event_info.other_event.event_type
157 = prof_info.event_type;
158 compute_construct_event_info.other_event.valid_bytes
159 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
160 compute_construct_event_info.other_event.parent_construct
161 = acc_construct_parallel;
162 compute_construct_event_info.other_event.implicit = 0;
163 compute_construct_event_info.other_event.tool_info = NULL;
165 acc_api_info api_info;
166 if (profiling_p)
168 thr->api_info = &api_info;
170 api_info.device_api = acc_device_api_none;
171 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
172 api_info.device_type = prof_info.device_type;
173 api_info.vendor = -1;
174 api_info.device_handle = NULL;
175 api_info.context_handle = NULL;
176 api_info.async_handle = NULL;
179 if (profiling_p)
180 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
181 &api_info);
183 handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
185 /* Host fallback if "if" clause is false or if the current device is set to
186 the host. */
187 if (flags & GOACC_FLAG_HOST_FALLBACK)
189 prof_info.device_type = acc_device_host;
190 api_info.device_type = prof_info.device_type;
191 goacc_save_and_set_bind (acc_device_host);
192 fn (hostaddrs);
193 goacc_restore_bind ();
194 goto out_prof;
196 else if (acc_device_type (acc_dev->type) == acc_device_host)
198 fn (hostaddrs);
199 goto out_prof;
202 /* Default: let the runtime choose. */
203 for (i = 0; i != GOMP_DIM_MAX; i++)
204 dims[i] = 0;
206 va_start (ap, kinds);
207 /* TODO: This will need amending when device_type is implemented. */
208 while ((tag = va_arg (ap, unsigned)) != 0)
210 if (GOMP_LAUNCH_DEVICE (tag))
211 gomp_fatal ("device_type '%d' offload parameters, libgomp is too old",
212 GOMP_LAUNCH_DEVICE (tag));
214 switch (GOMP_LAUNCH_CODE (tag))
216 case GOMP_LAUNCH_DIM:
218 unsigned mask = GOMP_LAUNCH_OP (tag);
220 for (i = 0; i != GOMP_DIM_MAX; i++)
221 if (mask & GOMP_DIM_MASK (i))
222 dims[i] = va_arg (ap, unsigned);
224 break;
226 case GOMP_LAUNCH_ASYNC:
228 /* Small constant values are encoded in the operand. */
229 async = GOMP_LAUNCH_OP (tag);
231 if (async == GOMP_LAUNCH_OP_MAX)
232 async = va_arg (ap, unsigned);
234 if (profiling_p)
236 prof_info.async = async;
237 prof_info.async_queue = prof_info.async;
240 break;
243 case GOMP_LAUNCH_WAIT:
245 unsigned num_waits = GOMP_LAUNCH_OP (tag);
246 goacc_wait (async, num_waits, &ap);
247 break;
250 default:
251 gomp_fatal ("unrecognized offload code '%d',"
252 " libgomp is too old", GOMP_LAUNCH_CODE (tag));
255 va_end (ap);
257 if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
259 k.host_start = (uintptr_t) fn;
260 k.host_end = k.host_start + 1;
261 gomp_mutex_lock (&acc_dev->lock);
262 tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k);
263 gomp_mutex_unlock (&acc_dev->lock);
265 if (tgt_fn_key == NULL)
266 gomp_fatal ("target function wasn't mapped");
268 tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
270 else
271 tgt_fn = (void (*)) fn;
273 acc_event_info enter_exit_data_event_info;
274 if (profiling_p)
276 prof_info.event_type = acc_ev_enter_data_start;
277 enter_exit_data_event_info.other_event.event_type
278 = prof_info.event_type;
279 enter_exit_data_event_info.other_event.valid_bytes
280 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
281 enter_exit_data_event_info.other_event.parent_construct
282 = compute_construct_event_info.other_event.parent_construct;
283 enter_exit_data_event_info.other_event.implicit = 1;
284 enter_exit_data_event_info.other_event.tool_info = NULL;
285 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
286 &api_info);
289 goacc_aq aq = get_goacc_asyncqueue (async);
291 struct target_mem_desc *tgt
292 = goacc_map_vars (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, kinds, true,
293 GOMP_MAP_VARS_TARGET);
295 if (profiling_p)
297 prof_info.event_type = acc_ev_enter_data_end;
298 enter_exit_data_event_info.other_event.event_type
299 = prof_info.event_type;
300 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
301 &api_info);
304 void **devaddrs = (void **) tgt->tgt_start;
305 if (aq == NULL)
306 acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
307 tgt);
308 else
309 acc_dev->openacc.async.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
310 dims, tgt, aq);
312 if (profiling_p)
314 prof_info.event_type = acc_ev_exit_data_start;
315 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
316 enter_exit_data_event_info.other_event.tool_info = NULL;
317 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
318 &api_info);
321 /* If running synchronously (aq == NULL), this will unmap immediately. */
322 goacc_unmap_vars (tgt, true, aq);
324 if (profiling_p)
326 prof_info.event_type = acc_ev_exit_data_end;
327 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
328 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
329 &api_info);
332 out_prof:
333 if (profiling_p)
335 prof_info.event_type = acc_ev_compute_construct_end;
336 compute_construct_event_info.other_event.event_type
337 = prof_info.event_type;
338 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
339 &api_info);
341 thr->prof_info = NULL;
342 thr->api_info = NULL;
346 /* Legacy entry point (GCC 5). Only provide host fallback execution. */
348 void
349 GOACC_parallel (int flags_m, void (*fn) (void *),
350 size_t mapnum, void **hostaddrs, size_t *sizes,
351 unsigned short *kinds,
352 int num_gangs, int num_workers, int vector_length,
353 int async, int num_waits, ...)
355 goacc_save_and_set_bind (acc_device_host);
356 fn (hostaddrs);
357 goacc_restore_bind ();
360 void
361 GOACC_data_start (int flags_m, size_t mapnum,
362 void **hostaddrs, size_t *sizes, unsigned short *kinds)
364 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
366 struct target_mem_desc *tgt;
368 #ifdef HAVE_INTTYPES_H
369 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
370 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
371 #else
372 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
373 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
374 #endif
376 goacc_lazy_initialize ();
378 struct goacc_thread *thr = goacc_thread ();
379 struct gomp_device_descr *acc_dev = thr->dev;
381 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
383 acc_prof_info prof_info;
384 if (profiling_p)
386 thr->prof_info = &prof_info;
388 prof_info.event_type = acc_ev_enter_data_start;
389 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
390 prof_info.version = _ACC_PROF_INFO_VERSION;
391 prof_info.device_type = acc_device_type (acc_dev->type);
392 prof_info.device_number = acc_dev->target_id;
393 prof_info.thread_id = -1;
394 prof_info.async = acc_async_sync; /* Always synchronous. */
395 prof_info.async_queue = prof_info.async;
396 prof_info.src_file = NULL;
397 prof_info.func_name = NULL;
398 prof_info.line_no = -1;
399 prof_info.end_line_no = -1;
400 prof_info.func_line_no = -1;
401 prof_info.func_end_line_no = -1;
403 acc_event_info enter_data_event_info;
404 if (profiling_p)
406 enter_data_event_info.other_event.event_type
407 = prof_info.event_type;
408 enter_data_event_info.other_event.valid_bytes
409 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
410 enter_data_event_info.other_event.parent_construct = acc_construct_data;
411 for (int i = 0; i < mapnum; ++i)
412 if ((kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR
413 || (kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
415 /* If there is one such data mapping kind, then this is actually an
416 OpenACC 'host_data' construct. (GCC maps the OpenACC
417 'host_data' construct to the OpenACC 'data' construct.) Apart
418 from artificial test cases (such as an OpenACC 'host_data'
419 construct's (implicit) device initialization when there hasn't
420 been any device data be set up before...), there can't really
421 any meaningful events be generated from OpenACC 'host_data'
422 constructs, though. */
423 enter_data_event_info.other_event.parent_construct
424 = acc_construct_host_data;
425 break;
427 enter_data_event_info.other_event.implicit = 0;
428 enter_data_event_info.other_event.tool_info = NULL;
430 acc_api_info api_info;
431 if (profiling_p)
433 thr->api_info = &api_info;
435 api_info.device_api = acc_device_api_none;
436 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
437 api_info.device_type = prof_info.device_type;
438 api_info.vendor = -1;
439 api_info.device_handle = NULL;
440 api_info.context_handle = NULL;
441 api_info.async_handle = NULL;
444 if (profiling_p)
445 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
447 /* Host fallback or 'do nothing'. */
448 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
449 || (flags & GOACC_FLAG_HOST_FALLBACK))
451 prof_info.device_type = acc_device_host;
452 api_info.device_type = prof_info.device_type;
453 tgt = goacc_map_vars (NULL, NULL, 0, NULL, NULL, NULL, NULL, true, 0);
454 tgt->prev = thr->mapped_data;
455 thr->mapped_data = tgt;
457 goto out_prof;
460 gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
461 tgt = goacc_map_vars (acc_dev, NULL, mapnum, hostaddrs, NULL, sizes, kinds,
462 true, 0);
463 gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
464 tgt->prev = thr->mapped_data;
465 thr->mapped_data = tgt;
467 out_prof:
468 if (profiling_p)
470 prof_info.event_type = acc_ev_enter_data_end;
471 enter_data_event_info.other_event.event_type = prof_info.event_type;
472 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
474 thr->prof_info = NULL;
475 thr->api_info = NULL;
479 void
480 GOACC_data_end (void)
482 struct goacc_thread *thr = goacc_thread ();
483 struct gomp_device_descr *acc_dev = thr->dev;
484 struct target_mem_desc *tgt = thr->mapped_data;
486 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
488 acc_prof_info prof_info;
489 if (profiling_p)
491 thr->prof_info = &prof_info;
493 prof_info.event_type = acc_ev_exit_data_start;
494 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
495 prof_info.version = _ACC_PROF_INFO_VERSION;
496 prof_info.device_type = acc_device_type (acc_dev->type);
497 prof_info.device_number = acc_dev->target_id;
498 prof_info.thread_id = -1;
499 prof_info.async = acc_async_sync; /* Always synchronous. */
500 prof_info.async_queue = prof_info.async;
501 prof_info.src_file = NULL;
502 prof_info.func_name = NULL;
503 prof_info.line_no = -1;
504 prof_info.end_line_no = -1;
505 prof_info.func_line_no = -1;
506 prof_info.func_end_line_no = -1;
508 acc_event_info exit_data_event_info;
509 if (profiling_p)
511 exit_data_event_info.other_event.event_type
512 = prof_info.event_type;
513 exit_data_event_info.other_event.valid_bytes
514 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
515 exit_data_event_info.other_event.parent_construct = acc_construct_data;
516 exit_data_event_info.other_event.implicit = 0;
517 exit_data_event_info.other_event.tool_info = NULL;
519 acc_api_info api_info;
520 if (profiling_p)
522 thr->api_info = &api_info;
524 api_info.device_api = acc_device_api_none;
525 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
526 api_info.device_type = prof_info.device_type;
527 api_info.vendor = -1;
528 api_info.device_handle = NULL;
529 api_info.context_handle = NULL;
530 api_info.async_handle = NULL;
533 if (profiling_p)
534 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
536 gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
537 thr->mapped_data = tgt->prev;
538 goacc_unmap_vars (tgt, true, NULL);
539 gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
541 if (profiling_p)
543 prof_info.event_type = acc_ev_exit_data_end;
544 exit_data_event_info.other_event.event_type = prof_info.event_type;
545 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
547 thr->prof_info = NULL;
548 thr->api_info = NULL;
552 void
553 GOACC_update (int flags_m, size_t mapnum,
554 void **hostaddrs, size_t *sizes, unsigned short *kinds,
555 int async, int num_waits, ...)
557 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
559 size_t i;
561 goacc_lazy_initialize ();
563 struct goacc_thread *thr = goacc_thread ();
564 struct gomp_device_descr *acc_dev = thr->dev;
566 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
568 acc_prof_info prof_info;
569 if (profiling_p)
571 thr->prof_info = &prof_info;
573 prof_info.event_type = acc_ev_update_start;
574 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
575 prof_info.version = _ACC_PROF_INFO_VERSION;
576 prof_info.device_type = acc_device_type (acc_dev->type);
577 prof_info.device_number = acc_dev->target_id;
578 prof_info.thread_id = -1;
579 prof_info.async = async;
580 prof_info.async_queue = prof_info.async;
581 prof_info.src_file = NULL;
582 prof_info.func_name = NULL;
583 prof_info.line_no = -1;
584 prof_info.end_line_no = -1;
585 prof_info.func_line_no = -1;
586 prof_info.func_end_line_no = -1;
588 acc_event_info update_event_info;
589 if (profiling_p)
591 update_event_info.other_event.event_type
592 = prof_info.event_type;
593 update_event_info.other_event.valid_bytes
594 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
595 update_event_info.other_event.parent_construct = acc_construct_update;
596 update_event_info.other_event.implicit = 0;
597 update_event_info.other_event.tool_info = NULL;
599 acc_api_info api_info;
600 if (profiling_p)
602 thr->api_info = &api_info;
604 api_info.device_api = acc_device_api_none;
605 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
606 api_info.device_type = prof_info.device_type;
607 api_info.vendor = -1;
608 api_info.device_handle = NULL;
609 api_info.context_handle = NULL;
610 api_info.async_handle = NULL;
613 if (profiling_p)
614 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
616 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
617 || (flags & GOACC_FLAG_HOST_FALLBACK))
619 prof_info.device_type = acc_device_host;
620 api_info.device_type = prof_info.device_type;
622 goto out_prof;
625 if (num_waits)
627 va_list ap;
629 va_start (ap, num_waits);
630 goacc_wait (async, num_waits, &ap);
631 va_end (ap);
634 bool update_device = false;
635 for (i = 0; i < mapnum; ++i)
637 unsigned char kind = kinds[i] & 0xff;
639 switch (kind)
641 case GOMP_MAP_POINTER:
642 case GOMP_MAP_TO_PSET:
643 break;
645 case GOMP_MAP_ALWAYS_POINTER:
646 if (update_device)
648 /* Save the contents of the host pointer. */
649 void *dptr = acc_deviceptr (hostaddrs[i-1]);
650 uintptr_t t = *(uintptr_t *) hostaddrs[i];
652 /* Update the contents of the host pointer to reflect
653 the value of the allocated device memory in the
654 previous pointer. */
655 *(uintptr_t *) hostaddrs[i] = (uintptr_t)dptr;
656 /* TODO: verify that we really cannot use acc_update_device_async
657 here. */
658 acc_update_device (hostaddrs[i], sizeof (uintptr_t));
660 /* Restore the host pointer. */
661 *(uintptr_t *) hostaddrs[i] = t;
662 update_device = false;
664 break;
666 case GOMP_MAP_TO:
667 if (!acc_is_present (hostaddrs[i], sizes[i]))
669 update_device = false;
670 break;
672 /* Fallthru */
673 case GOMP_MAP_FORCE_TO:
674 update_device = true;
675 acc_update_device_async (hostaddrs[i], sizes[i], async);
676 break;
678 case GOMP_MAP_FROM:
679 if (!acc_is_present (hostaddrs[i], sizes[i]))
681 update_device = false;
682 break;
684 /* Fallthru */
685 case GOMP_MAP_FORCE_FROM:
686 update_device = false;
687 acc_update_self_async (hostaddrs[i], sizes[i], async);
688 break;
690 default:
691 gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
692 break;
696 out_prof:
697 if (profiling_p)
699 prof_info.event_type = acc_ev_update_end;
700 update_event_info.other_event.event_type = prof_info.event_type;
701 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
703 thr->prof_info = NULL;
704 thr->api_info = NULL;
709 /* Legacy entry point (GCC 5). */
712 GOACC_get_num_threads (void)
714 return 1;
717 /* Legacy entry point (GCC 5). */
720 GOACC_get_thread_num (void)
722 return 0;