blob: edfc6067ee915f21e5d8aa5c95586bc1c3c2bd99 [file] [log] [blame]
Jakub Jelinek8d9254f2020-01-01 12:51:42 +01001/* Copyright (C) 2013-2020 Free Software Foundation, Inc.
Thomas Schwinge41dbbb32015-01-15 21:11:12 +01002
3 Contributed by Mentor Embedded.
4
5 This file is part of the GNU Offloading and Multi Processing Library
6 (libgomp).
7
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.
12
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.
17
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.
21
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/>. */
26
27/* This file handles OpenACC constructs. */
28
29#include "openacc.h"
30#include "libgomp.h"
Thomas Schwinge41dbbb32015-01-15 21:11:12 +010031#include "gomp-constants.h"
32#include "oacc-int.h"
Kai Tietz01c0b3b2015-03-25 16:05:02 +010033#ifdef HAVE_INTTYPES_H
34# include <inttypes.h> /* For PRIu64. */
35#endif
Thomas Schwinge41dbbb32015-01-15 21:11:12 +010036#include <string.h>
37#include <stdarg.h>
38#include <assert.h>
Thomas Schwinge41dbbb32015-01-15 21:11:12 +010039
Thomas Schwinge59d59602018-12-28 12:34:14 +010040
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");
48
49
Chung-Lin Tang829c6342018-06-20 16:35:15 +000050/* Handle the mapping pair that are presented when a
51 deviceptr clause is used with Fortran. */
52
53static void
54handle_ftn_pointers (size_t mapnum, void **hostaddrs, size_t *sizes,
55 unsigned short *kinds)
56{
57 int i;
58
59 for (i = 0; i < mapnum; i++)
60 {
61 unsigned short kind1 = kinds[i] & 0xff;
62
63 /* Handle Fortran deviceptr clause. */
64 if (kind1 == GOMP_MAP_FORCE_DEVICEPTR)
65 {
66 unsigned short kind2;
67
68 if (i < (signed)mapnum - 1)
69 kind2 = kinds[i + 1] & 0xff;
70 else
71 kind2 = 0xffff;
72
73 if (sizes[i] == sizeof (void *))
74 continue;
75
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])
84 {
85 kinds[i+1] = kinds[i];
86 sizes[i+1] = sizeof (void *);
87 }
88
89 /* Invalidate the entry. */
90 hostaddrs[i] = NULL;
91 }
92 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +010093}
94
Nathan Sidwell3e32ee12015-09-28 19:37:33 +000095
Thomas Schwinge59d59602018-12-28 12:34:14 +010096/* Launch a possibly offloaded function with FLAGS. FN is the host fn
Nathan Sidwell3e32ee12015-09-28 19:37:33 +000097 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. */
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100100
101void
Thomas Schwinge59d59602018-12-28 12:34:14 +0100102GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000103 size_t mapnum, void **hostaddrs, size_t *sizes,
104 unsigned short *kinds, ...)
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100105{
Thomas Schwinge59d59602018-12-28 12:34:14 +0100106 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
107
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100108 va_list ap;
109 struct goacc_thread *thr;
110 struct gomp_device_descr *acc_dev;
111 struct target_mem_desc *tgt;
112 void **devaddrs;
113 unsigned int i;
114 struct splay_tree_key_s k;
115 splay_tree_key tgt_fn_key;
116 void (*tgt_fn);
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000117 int async = GOMP_ASYNC_SYNC;
118 unsigned dims[GOMP_DIM_MAX];
119 unsigned tag;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100120
Kai Tietz01c0b3b2015-03-25 16:05:02 +0100121#ifdef HAVE_INTTYPES_H
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000122 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
123 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
Kai Tietz01c0b3b2015-03-25 16:05:02 +0100124#else
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000125 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
126 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
Kai Tietz01c0b3b2015-03-25 16:05:02 +0100127#endif
Julian Brownd93bdab2015-04-08 15:58:33 +0000128 goacc_lazy_initialize ();
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100129
130 thr = goacc_thread ();
131 acc_dev = thr->dev;
132
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200133 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
134
135 acc_prof_info prof_info;
136 if (profiling_p)
137 {
138 thr->prof_info = &prof_info;
139
140 prof_info.event_type = acc_ev_compute_construct_start;
141 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
142 prof_info.version = _ACC_PROF_INFO_VERSION;
143 prof_info.device_type = acc_device_type (acc_dev->type);
144 prof_info.device_number = acc_dev->target_id;
145 prof_info.thread_id = -1;
146 prof_info.async = async;
147 prof_info.async_queue = prof_info.async;
148 prof_info.src_file = NULL;
149 prof_info.func_name = NULL;
150 prof_info.line_no = -1;
151 prof_info.end_line_no = -1;
152 prof_info.func_line_no = -1;
153 prof_info.func_end_line_no = -1;
154 }
155 acc_event_info compute_construct_event_info;
156 if (profiling_p)
157 {
158 compute_construct_event_info.other_event.event_type
159 = prof_info.event_type;
160 compute_construct_event_info.other_event.valid_bytes
161 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
162 compute_construct_event_info.other_event.parent_construct
163 = acc_construct_parallel;
164 compute_construct_event_info.other_event.implicit = 0;
165 compute_construct_event_info.other_event.tool_info = NULL;
166 }
167 acc_api_info api_info;
168 if (profiling_p)
169 {
170 thr->api_info = &api_info;
171
172 api_info.device_api = acc_device_api_none;
173 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
174 api_info.device_type = prof_info.device_type;
175 api_info.vendor = -1;
176 api_info.device_handle = NULL;
177 api_info.context_handle = NULL;
178 api_info.async_handle = NULL;
179 }
180
181 if (profiling_p)
182 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
183 &api_info);
184
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000185 handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
186
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100187 /* Host fallback if "if" clause is false or if the current device is set to
188 the host. */
Thomas Schwinge59d59602018-12-28 12:34:14 +0100189 if (flags & GOACC_FLAG_HOST_FALLBACK)
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100190 {
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200191 prof_info.device_type = acc_device_host;
192 api_info.device_type = prof_info.device_type;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100193 goacc_save_and_set_bind (acc_device_host);
194 fn (hostaddrs);
195 goacc_restore_bind ();
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200196 goto out_prof;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100197 }
198 else if (acc_device_type (acc_dev->type) == acc_device_host)
199 {
200 fn (hostaddrs);
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200201 goto out_prof;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100202 }
203
Thomas Schwingef99c3552016-02-23 16:07:54 +0100204 /* Default: let the runtime choose. */
205 for (i = 0; i != GOMP_DIM_MAX; i++)
206 dims[i] = 0;
207
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000208 va_start (ap, kinds);
209 /* TODO: This will need amending when device_type is implemented. */
210 while ((tag = va_arg (ap, unsigned)) != 0)
Nathan Sidwella0911182015-07-20 17:31:46 +0000211 {
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000212 if (GOMP_LAUNCH_DEVICE (tag))
213 gomp_fatal ("device_type '%d' offload parameters, libgomp is too old",
214 GOMP_LAUNCH_DEVICE (tag));
215
216 switch (GOMP_LAUNCH_CODE (tag))
217 {
218 case GOMP_LAUNCH_DIM:
219 {
220 unsigned mask = GOMP_LAUNCH_OP (tag);
221
222 for (i = 0; i != GOMP_DIM_MAX; i++)
223 if (mask & GOMP_DIM_MASK (i))
224 dims[i] = va_arg (ap, unsigned);
225 }
226 break;
227
228 case GOMP_LAUNCH_ASYNC:
229 {
230 /* Small constant values are encoded in the operand. */
231 async = GOMP_LAUNCH_OP (tag);
232
233 if (async == GOMP_LAUNCH_OP_MAX)
234 async = va_arg (ap, unsigned);
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200235
236 if (profiling_p)
237 {
238 prof_info.async = async;
239 prof_info.async_queue = prof_info.async;
240 }
241
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000242 break;
243 }
244
245 case GOMP_LAUNCH_WAIT:
246 {
247 unsigned num_waits = GOMP_LAUNCH_OP (tag);
Chung-Lin Tang19695f42019-02-19 14:10:15 +0000248 goacc_wait (async, num_waits, &ap);
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000249 break;
250 }
251
252 default:
253 gomp_fatal ("unrecognized offload code '%d',"
254 " libgomp is too old", GOMP_LAUNCH_CODE (tag));
255 }
Nathan Sidwella0911182015-07-20 17:31:46 +0000256 }
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000257 va_end (ap);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100258
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100259 if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
260 {
261 k.host_start = (uintptr_t) fn;
262 k.host_end = k.host_start + 1;
Ilya Verbina51df542015-04-06 12:40:28 +0000263 gomp_mutex_lock (&acc_dev->lock);
264 tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k);
265 gomp_mutex_unlock (&acc_dev->lock);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100266
267 if (tgt_fn_key == NULL)
268 gomp_fatal ("target function wasn't mapped");
269
Julian Brownd93bdab2015-04-08 15:58:33 +0000270 tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100271 }
272 else
273 tgt_fn = (void (*)) fn;
274
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200275 acc_event_info enter_exit_data_event_info;
276 if (profiling_p)
277 {
278 prof_info.event_type = acc_ev_enter_data_start;
279 enter_exit_data_event_info.other_event.event_type
280 = prof_info.event_type;
281 enter_exit_data_event_info.other_event.valid_bytes
282 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
283 enter_exit_data_event_info.other_event.parent_construct
284 = compute_construct_event_info.other_event.parent_construct;
285 enter_exit_data_event_info.other_event.implicit = 1;
286 enter_exit_data_event_info.other_event.tool_info = NULL;
287 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
288 &api_info);
289 }
290
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000291 goacc_aq aq = get_goacc_asyncqueue (async);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100292
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000293 tgt = gomp_map_vars_async (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, kinds,
294 true, GOMP_MAP_VARS_OPENACC);
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200295 if (profiling_p)
296 {
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);
302 }
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000303
Thomas Schwinge6e361142015-01-16 21:05:21 +0100304 devaddrs = gomp_alloca (sizeof (void *) * mapnum);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100305 for (i = 0; i < mapnum; i++)
Julian Brown5bcd4702019-12-20 01:20:19 +0000306 devaddrs[i] = (void *) gomp_map_val (tgt, hostaddrs, i);
307
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000308 if (aq == NULL)
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200309 acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
310 tgt);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100311 else
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200312 acc_dev->openacc.async.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
313 dims, tgt, aq);
314
315 if (profiling_p)
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000316 {
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200317 prof_info.event_type = acc_ev_exit_data_start;
318 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
319 enter_exit_data_event_info.other_event.tool_info = NULL;
320 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
321 &api_info);
322 }
323
324 /* If running synchronously, unmap immediately. */
325 if (aq == NULL)
326 gomp_unmap_vars (tgt, true);
327 else
328 gomp_unmap_vars_async (tgt, true, aq);
329
330 if (profiling_p)
331 {
332 prof_info.event_type = acc_ev_exit_data_end;
333 enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
334 goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
335 &api_info);
336 }
337
338 out_prof:
339 if (profiling_p)
340 {
341 prof_info.event_type = acc_ev_compute_construct_end;
342 compute_construct_event_info.other_event.event_type
343 = prof_info.event_type;
344 goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
345 &api_info);
346
347 thr->prof_info = NULL;
348 thr->api_info = NULL;
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000349 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100350}
351
Thomas Schwinge2bbbfa42019-05-06 10:49:55 +0200352/* Legacy entry point (GCC 5). Only provide host fallback execution. */
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000353
354void
Thomas Schwinge59d59602018-12-28 12:34:14 +0100355GOACC_parallel (int flags_m, void (*fn) (void *),
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000356 size_t mapnum, void **hostaddrs, size_t *sizes,
357 unsigned short *kinds,
358 int num_gangs, int num_workers, int vector_length,
359 int async, int num_waits, ...)
360{
361 goacc_save_and_set_bind (acc_device_host);
362 fn (hostaddrs);
363 goacc_restore_bind ();
364}
365
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100366void
Thomas Schwinge59d59602018-12-28 12:34:14 +0100367GOACC_data_start (int flags_m, size_t mapnum,
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100368 void **hostaddrs, size_t *sizes, unsigned short *kinds)
369{
Thomas Schwinge59d59602018-12-28 12:34:14 +0100370 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
371
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100372 struct target_mem_desc *tgt;
373
Kai Tietz01c0b3b2015-03-25 16:05:02 +0100374#ifdef HAVE_INTTYPES_H
375 gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
376 __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
377#else
378 gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
379 __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
380#endif
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100381
Julian Brownd93bdab2015-04-08 15:58:33 +0000382 goacc_lazy_initialize ();
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100383
384 struct goacc_thread *thr = goacc_thread ();
385 struct gomp_device_descr *acc_dev = thr->dev;
386
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200387 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
388
389 acc_prof_info prof_info;
390 if (profiling_p)
391 {
392 thr->prof_info = &prof_info;
393
394 prof_info.event_type = acc_ev_enter_data_start;
395 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
396 prof_info.version = _ACC_PROF_INFO_VERSION;
397 prof_info.device_type = acc_device_type (acc_dev->type);
398 prof_info.device_number = acc_dev->target_id;
399 prof_info.thread_id = -1;
400 prof_info.async = acc_async_sync; /* Always synchronous. */
401 prof_info.async_queue = prof_info.async;
402 prof_info.src_file = NULL;
403 prof_info.func_name = NULL;
404 prof_info.line_no = -1;
405 prof_info.end_line_no = -1;
406 prof_info.func_line_no = -1;
407 prof_info.func_end_line_no = -1;
408 }
409 acc_event_info enter_data_event_info;
410 if (profiling_p)
411 {
412 enter_data_event_info.other_event.event_type
413 = prof_info.event_type;
414 enter_data_event_info.other_event.valid_bytes
415 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
416 enter_data_event_info.other_event.parent_construct = acc_construct_data;
417 for (int i = 0; i < mapnum; ++i)
418 if ((kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR)
419 {
420 /* If there is one such data mapping kind, then this is actually an
421 OpenACC 'host_data' construct. (GCC maps the OpenACC
422 'host_data' construct to the OpenACC 'data' construct.) Apart
423 from artificial test cases (such as an OpenACC 'host_data'
424 construct's (implicit) device initialization when there hasn't
425 been any device data be set up before...), there can't really
426 any meaningful events be generated from OpenACC 'host_data'
427 constructs, though. */
428 enter_data_event_info.other_event.parent_construct
429 = acc_construct_host_data;
430 break;
431 }
432 enter_data_event_info.other_event.implicit = 0;
433 enter_data_event_info.other_event.tool_info = NULL;
434 }
435 acc_api_info api_info;
436 if (profiling_p)
437 {
438 thr->api_info = &api_info;
439
440 api_info.device_api = acc_device_api_none;
441 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
442 api_info.device_type = prof_info.device_type;
443 api_info.vendor = -1;
444 api_info.device_handle = NULL;
445 api_info.context_handle = NULL;
446 api_info.async_handle = NULL;
447 }
448
449 if (profiling_p)
450 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
451
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100452 /* Host fallback or 'do nothing'. */
453 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
Thomas Schwinge59d59602018-12-28 12:34:14 +0100454 || (flags & GOACC_FLAG_HOST_FALLBACK))
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100455 {
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200456 prof_info.device_type = acc_device_host;
457 api_info.device_type = prof_info.device_type;
Jakub Jelinekd9a6bd32015-10-13 21:06:23 +0200458 tgt = gomp_map_vars (NULL, 0, NULL, NULL, NULL, NULL, true,
459 GOMP_MAP_VARS_OPENACC);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100460 tgt->prev = thr->mapped_data;
461 thr->mapped_data = tgt;
462
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200463 goto out_prof;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100464 }
465
466 gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
467 tgt = gomp_map_vars (acc_dev, mapnum, hostaddrs, NULL, sizes, kinds, true,
Jakub Jelinekd9a6bd32015-10-13 21:06:23 +0200468 GOMP_MAP_VARS_OPENACC);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100469 gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
470 tgt->prev = thr->mapped_data;
471 thr->mapped_data = tgt;
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200472
473 out_prof:
474 if (profiling_p)
475 {
476 prof_info.event_type = acc_ev_enter_data_end;
477 enter_data_event_info.other_event.event_type = prof_info.event_type;
478 goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
479
480 thr->prof_info = NULL;
481 thr->api_info = NULL;
482 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100483}
484
485void
486GOACC_data_end (void)
487{
488 struct goacc_thread *thr = goacc_thread ();
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200489 struct gomp_device_descr *acc_dev = thr->dev;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100490 struct target_mem_desc *tgt = thr->mapped_data;
491
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200492 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
493
494 acc_prof_info prof_info;
495 if (profiling_p)
496 {
497 thr->prof_info = &prof_info;
498
499 prof_info.event_type = acc_ev_exit_data_start;
500 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
501 prof_info.version = _ACC_PROF_INFO_VERSION;
502 prof_info.device_type = acc_device_type (acc_dev->type);
503 prof_info.device_number = acc_dev->target_id;
504 prof_info.thread_id = -1;
505 prof_info.async = acc_async_sync; /* Always synchronous. */
506 prof_info.async_queue = prof_info.async;
507 prof_info.src_file = NULL;
508 prof_info.func_name = NULL;
509 prof_info.line_no = -1;
510 prof_info.end_line_no = -1;
511 prof_info.func_line_no = -1;
512 prof_info.func_end_line_no = -1;
513 }
514 acc_event_info exit_data_event_info;
515 if (profiling_p)
516 {
517 exit_data_event_info.other_event.event_type
518 = prof_info.event_type;
519 exit_data_event_info.other_event.valid_bytes
520 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
521 exit_data_event_info.other_event.parent_construct = acc_construct_data;
522 exit_data_event_info.other_event.implicit = 0;
523 exit_data_event_info.other_event.tool_info = NULL;
524 }
525 acc_api_info api_info;
526 if (profiling_p)
527 {
528 thr->api_info = &api_info;
529
530 api_info.device_api = acc_device_api_none;
531 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
532 api_info.device_type = prof_info.device_type;
533 api_info.vendor = -1;
534 api_info.device_handle = NULL;
535 api_info.context_handle = NULL;
536 api_info.async_handle = NULL;
537 }
538
539 if (profiling_p)
540 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
541
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100542 gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
543 thr->mapped_data = tgt->prev;
544 gomp_unmap_vars (tgt, true);
545 gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200546
547 if (profiling_p)
548 {
549 prof_info.event_type = acc_ev_exit_data_end;
550 exit_data_event_info.other_event.event_type = prof_info.event_type;
551 goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
552
553 thr->prof_info = NULL;
554 thr->api_info = NULL;
555 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100556}
557
558void
Thomas Schwinge59d59602018-12-28 12:34:14 +0100559GOACC_update (int flags_m, size_t mapnum,
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100560 void **hostaddrs, size_t *sizes, unsigned short *kinds,
561 int async, int num_waits, ...)
562{
Thomas Schwinge59d59602018-12-28 12:34:14 +0100563 int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
564
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100565 size_t i;
566
Julian Brownd93bdab2015-04-08 15:58:33 +0000567 goacc_lazy_initialize ();
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100568
569 struct goacc_thread *thr = goacc_thread ();
570 struct gomp_device_descr *acc_dev = thr->dev;
571
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200572 bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
573
574 acc_prof_info prof_info;
575 if (profiling_p)
576 {
577 thr->prof_info = &prof_info;
578
579 prof_info.event_type = acc_ev_update_start;
580 prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
581 prof_info.version = _ACC_PROF_INFO_VERSION;
582 prof_info.device_type = acc_device_type (acc_dev->type);
583 prof_info.device_number = acc_dev->target_id;
584 prof_info.thread_id = -1;
585 prof_info.async = async;
586 prof_info.async_queue = prof_info.async;
587 prof_info.src_file = NULL;
588 prof_info.func_name = NULL;
589 prof_info.line_no = -1;
590 prof_info.end_line_no = -1;
591 prof_info.func_line_no = -1;
592 prof_info.func_end_line_no = -1;
593 }
594 acc_event_info update_event_info;
595 if (profiling_p)
596 {
597 update_event_info.other_event.event_type
598 = prof_info.event_type;
599 update_event_info.other_event.valid_bytes
600 = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
601 update_event_info.other_event.parent_construct = acc_construct_update;
602 update_event_info.other_event.implicit = 0;
603 update_event_info.other_event.tool_info = NULL;
604 }
605 acc_api_info api_info;
606 if (profiling_p)
607 {
608 thr->api_info = &api_info;
609
610 api_info.device_api = acc_device_api_none;
611 api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
612 api_info.device_type = prof_info.device_type;
613 api_info.vendor = -1;
614 api_info.device_handle = NULL;
615 api_info.context_handle = NULL;
616 api_info.async_handle = NULL;
617 }
618
619 if (profiling_p)
620 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
621
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100622 if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
Thomas Schwinge59d59602018-12-28 12:34:14 +0100623 || (flags & GOACC_FLAG_HOST_FALLBACK))
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200624 {
625 prof_info.device_type = acc_device_host;
626 api_info.device_type = prof_info.device_type;
627
628 goto out_prof;
629 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100630
Nathan Sidwella0911182015-07-20 17:31:46 +0000631 if (num_waits)
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100632 {
633 va_list ap;
634
635 va_start (ap, num_waits);
Nathan Sidwell3e32ee12015-09-28 19:37:33 +0000636 goacc_wait (async, num_waits, &ap);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100637 va_end (ap);
638 }
639
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000640 bool update_device = false;
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100641 for (i = 0; i < mapnum; ++i)
642 {
643 unsigned char kind = kinds[i] & 0xff;
644
645 switch (kind)
646 {
647 case GOMP_MAP_POINTER:
648 case GOMP_MAP_TO_PSET:
649 break;
650
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000651 case GOMP_MAP_ALWAYS_POINTER:
652 if (update_device)
653 {
654 /* Save the contents of the host pointer. */
655 void *dptr = acc_deviceptr (hostaddrs[i-1]);
656 uintptr_t t = *(uintptr_t *) hostaddrs[i];
657
658 /* Update the contents of the host pointer to reflect
659 the value of the allocated device memory in the
660 previous pointer. */
661 *(uintptr_t *) hostaddrs[i] = (uintptr_t)dptr;
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000662 /* TODO: verify that we really cannot use acc_update_device_async
663 here. */
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000664 acc_update_device (hostaddrs[i], sizeof (uintptr_t));
665
666 /* Restore the host pointer. */
667 *(uintptr_t *) hostaddrs[i] = t;
668 update_device = false;
669 }
670 break;
671
672 case GOMP_MAP_TO:
673 if (!acc_is_present (hostaddrs[i], sizes[i]))
674 {
675 update_device = false;
676 break;
677 }
678 /* Fallthru */
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100679 case GOMP_MAP_FORCE_TO:
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000680 update_device = true;
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000681 acc_update_device_async (hostaddrs[i], sizes[i], async);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100682 break;
683
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000684 case GOMP_MAP_FROM:
685 if (!acc_is_present (hostaddrs[i], sizes[i]))
686 {
687 update_device = false;
688 break;
689 }
690 /* Fallthru */
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100691 case GOMP_MAP_FORCE_FROM:
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000692 update_device = false;
Chung-Lin Tang1f4c5b92019-05-13 13:32:00 +0000693 acc_update_self_async (hostaddrs[i], sizes[i], async);
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100694 break;
695
696 default:
697 gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
698 break;
699 }
700 }
Thomas Schwinge5fae0492019-05-17 21:13:36 +0200701
702 out_prof:
703 if (profiling_p)
704 {
705 prof_info.event_type = acc_ev_update_end;
706 update_event_info.other_event.event_type = prof_info.event_type;
707 goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
708
709 thr->prof_info = NULL;
710 thr->api_info = NULL;
711 }
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100712}
713
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100714
Thomas Schwinge2bbbfa42019-05-06 10:49:55 +0200715/* Legacy entry point (GCC 5). */
716
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100717int
718GOACC_get_num_threads (void)
719{
720 return 1;
721}
722
Thomas Schwinge2bbbfa42019-05-06 10:49:55 +0200723/* Legacy entry point (GCC 5). */
724
Thomas Schwinge41dbbb32015-01-15 21:11:12 +0100725int
726GOACC_get_thread_num (void)
727{
728 return 0;
729}
James Norris6e232ba2015-11-12 22:20:41 +0000730
731void
Thomas Schwinge59d59602018-12-28 12:34:14 +0100732GOACC_declare (int flags_m, size_t mapnum,
James Norris6e232ba2015-11-12 22:20:41 +0000733 void **hostaddrs, size_t *sizes, unsigned short *kinds)
734{
735 int i;
736
737 for (i = 0; i < mapnum; i++)
738 {
739 unsigned char kind = kinds[i] & 0xff;
740
741 if (kind == GOMP_MAP_POINTER || kind == GOMP_MAP_TO_PSET)
742 continue;
743
744 switch (kind)
745 {
746 case GOMP_MAP_FORCE_ALLOC:
James Norris6e232ba2015-11-12 22:20:41 +0000747 case GOMP_MAP_FORCE_FROM:
748 case GOMP_MAP_FORCE_TO:
749 case GOMP_MAP_POINTER:
Chung-Lin Tang829c6342018-06-20 16:35:15 +0000750 case GOMP_MAP_RELEASE:
Thomas Schwinge91106e82016-03-17 16:07:54 +0100751 case GOMP_MAP_DELETE:
Thomas Schwinge59d59602018-12-28 12:34:14 +0100752 GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
Tom de Vriesf5ad16f2018-05-09 16:01:30 +0000753 &kinds[i], GOMP_ASYNC_SYNC, 0);
James Norris6e232ba2015-11-12 22:20:41 +0000754 break;
755
756 case GOMP_MAP_FORCE_DEVICEPTR:
757 break;
758
759 case GOMP_MAP_ALLOC:
760 if (!acc_is_present (hostaddrs[i], sizes[i]))
Thomas Schwinge59d59602018-12-28 12:34:14 +0100761 GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
Tom de Vriesf5ad16f2018-05-09 16:01:30 +0000762 &kinds[i], GOMP_ASYNC_SYNC, 0);
James Norris6e232ba2015-11-12 22:20:41 +0000763 break;
764
765 case GOMP_MAP_TO:
Thomas Schwinge59d59602018-12-28 12:34:14 +0100766 GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
Tom de Vriesf5ad16f2018-05-09 16:01:30 +0000767 &kinds[i], GOMP_ASYNC_SYNC, 0);
James Norris6e232ba2015-11-12 22:20:41 +0000768
769 break;
770
771 case GOMP_MAP_FROM:
Thomas Schwinge59d59602018-12-28 12:34:14 +0100772 GOACC_enter_exit_data (flags_m, 1, &hostaddrs[i], &sizes[i],
Tom de Vriesf5ad16f2018-05-09 16:01:30 +0000773 &kinds[i], GOMP_ASYNC_SYNC, 0);
James Norris6e232ba2015-11-12 22:20:41 +0000774 break;
775
776 case GOMP_MAP_FORCE_PRESENT:
777 if (!acc_is_present (hostaddrs[i], sizes[i]))
778 gomp_fatal ("[%p,%ld] is not mapped", hostaddrs[i],
779 (unsigned long) sizes[i]);
780 break;
781
782 default:
783 assert (0);
784 break;
785 }
786 }
787}