oacc-parallel.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /* Copyright (C) 2013-2022 Free Software Foundation, Inc.
  2. Contributed by Mentor Embedded.
  3. This file is part of the GNU Offloading and Multi Processing Library
  4. (libgomp).
  5. Libgomp is free software; you can redistribute it and/or modify it
  6. under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 3, or (at your option)
  8. any later version.
  9. Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  11. FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. more details.
  13. Under Section 7 of GPL version 3, you are granted additional
  14. permissions described in the GCC Runtime Library Exception, version
  15. 3.1, as published by the Free Software Foundation.
  16. You should have received a copy of the GNU General Public License and
  17. a copy of the GCC Runtime Library Exception along with this program;
  18. see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. <http://www.gnu.org/licenses/>. */
  20. /* This file handles OpenACC constructs. */
  21. #include "openacc.h"
  22. #include "libgomp.h"
  23. #include "gomp-constants.h"
  24. #include "oacc-int.h"
  25. #ifdef HAVE_INTTYPES_H
  26. # include <inttypes.h> /* For PRIu64. */
  27. #endif
  28. #include <string.h>
  29. #include <stdarg.h>
  30. #include <assert.h>
  31. /* In the ABI, the GOACC_FLAGs are encoded as an inverted bitmask, so that we
  32. continue to support the following two legacy values. */
  33. _Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_ICV) == 0,
  34. "legacy GOMP_DEVICE_ICV broken");
  35. _Static_assert (GOACC_FLAGS_UNMARSHAL (GOMP_DEVICE_HOST_FALLBACK)
  36. == GOACC_FLAG_HOST_FALLBACK,
  37. "legacy GOMP_DEVICE_HOST_FALLBACK broken");
  38. /* Handle the mapping pair that are presented when a
  39. deviceptr clause is used with Fortran. */
  40. static void
  41. handle_ftn_pointers (size_t mapnum, void **hostaddrs, size_t *sizes,
  42. unsigned short *kinds)
  43. {
  44. int i;
  45. for (i = 0; i < mapnum; i++)
  46. {
  47. unsigned short kind1 = kinds[i] & 0xff;
  48. /* Handle Fortran deviceptr clause. */
  49. if (kind1 == GOMP_MAP_FORCE_DEVICEPTR)
  50. {
  51. unsigned short kind2;
  52. if (i < (signed)mapnum - 1)
  53. kind2 = kinds[i + 1] & 0xff;
  54. else
  55. kind2 = 0xffff;
  56. if (sizes[i] == sizeof (void *))
  57. continue;
  58. /* At this point, we're dealing with a Fortran deviceptr.
  59. If the next element is not what we're expecting, then
  60. this is an instance of where the deviceptr variable was
  61. not used within the region and the pointer was removed
  62. by the gimplifier. */
  63. if (kind2 == GOMP_MAP_POINTER
  64. && sizes[i + 1] == 0
  65. && hostaddrs[i] == *(void **)hostaddrs[i + 1])
  66. {
  67. kinds[i+1] = kinds[i];
  68. sizes[i+1] = sizeof (void *);
  69. }
  70. /* Invalidate the entry. */
  71. hostaddrs[i] = NULL;
  72. }
  73. }
  74. }
  75. /* Launch a possibly offloaded function with FLAGS. FN is the host fn
  76. address. MAPNUM, HOSTADDRS, SIZES & KINDS describe the memory
  77. blocks to be copied to/from the device. Varadic arguments are
  78. keyed optional parameters terminated with a zero. */
  79. void
  80. GOACC_parallel_keyed (int flags_m, void (*fn) (void *),
  81. size_t mapnum, void **hostaddrs, size_t *sizes,
  82. unsigned short *kinds, ...)
  83. {
  84. int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
  85. va_list ap;
  86. struct goacc_thread *thr;
  87. struct gomp_device_descr *acc_dev;
  88. struct target_mem_desc *tgt;
  89. void **devaddrs;
  90. unsigned int i;
  91. struct splay_tree_key_s k;
  92. splay_tree_key tgt_fn_key;
  93. void (*tgt_fn);
  94. int async = GOMP_ASYNC_SYNC;
  95. unsigned dims[GOMP_DIM_MAX];
  96. unsigned tag;
  97. #ifdef HAVE_INTTYPES_H
  98. gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
  99. __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
  100. #else
  101. gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
  102. __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
  103. #endif
  104. goacc_lazy_initialize ();
  105. thr = goacc_thread ();
  106. acc_dev = thr->dev;
  107. bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
  108. acc_prof_info prof_info;
  109. if (profiling_p)
  110. {
  111. thr->prof_info = &prof_info;
  112. prof_info.event_type = acc_ev_compute_construct_start;
  113. prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
  114. prof_info.version = _ACC_PROF_INFO_VERSION;
  115. prof_info.device_type = acc_device_type (acc_dev->type);
  116. prof_info.device_number = acc_dev->target_id;
  117. prof_info.thread_id = -1;
  118. prof_info.async = async;
  119. prof_info.async_queue = prof_info.async;
  120. prof_info.src_file = NULL;
  121. prof_info.func_name = NULL;
  122. prof_info.line_no = -1;
  123. prof_info.end_line_no = -1;
  124. prof_info.func_line_no = -1;
  125. prof_info.func_end_line_no = -1;
  126. }
  127. acc_event_info compute_construct_event_info;
  128. if (profiling_p)
  129. {
  130. compute_construct_event_info.other_event.event_type
  131. = prof_info.event_type;
  132. compute_construct_event_info.other_event.valid_bytes
  133. = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
  134. compute_construct_event_info.other_event.parent_construct
  135. = acc_construct_parallel;
  136. compute_construct_event_info.other_event.implicit = 0;
  137. compute_construct_event_info.other_event.tool_info = NULL;
  138. }
  139. acc_api_info api_info;
  140. if (profiling_p)
  141. {
  142. thr->api_info = &api_info;
  143. api_info.device_api = acc_device_api_none;
  144. api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
  145. api_info.device_type = prof_info.device_type;
  146. api_info.vendor = -1;
  147. api_info.device_handle = NULL;
  148. api_info.context_handle = NULL;
  149. api_info.async_handle = NULL;
  150. }
  151. if (profiling_p)
  152. goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
  153. &api_info);
  154. handle_ftn_pointers (mapnum, hostaddrs, sizes, kinds);
  155. /* Host fallback if "if" clause is false or if the current device is set to
  156. the host. */
  157. if (flags & GOACC_FLAG_HOST_FALLBACK)
  158. {
  159. prof_info.device_type = acc_device_host;
  160. api_info.device_type = prof_info.device_type;
  161. goacc_save_and_set_bind (acc_device_host);
  162. fn (hostaddrs);
  163. goacc_restore_bind ();
  164. goto out_prof;
  165. }
  166. else if (acc_device_type (acc_dev->type) == acc_device_host)
  167. {
  168. fn (hostaddrs);
  169. goto out_prof;
  170. }
  171. /* Default: let the runtime choose. */
  172. for (i = 0; i != GOMP_DIM_MAX; i++)
  173. dims[i] = 0;
  174. va_start (ap, kinds);
  175. /* TODO: This will need amending when device_type is implemented. */
  176. while ((tag = va_arg (ap, unsigned)) != 0)
  177. {
  178. if (GOMP_LAUNCH_DEVICE (tag))
  179. gomp_fatal ("device_type '%d' offload parameters, libgomp is too old",
  180. GOMP_LAUNCH_DEVICE (tag));
  181. switch (GOMP_LAUNCH_CODE (tag))
  182. {
  183. case GOMP_LAUNCH_DIM:
  184. {
  185. unsigned mask = GOMP_LAUNCH_OP (tag);
  186. for (i = 0; i != GOMP_DIM_MAX; i++)
  187. if (mask & GOMP_DIM_MASK (i))
  188. dims[i] = va_arg (ap, unsigned);
  189. }
  190. break;
  191. case GOMP_LAUNCH_ASYNC:
  192. {
  193. /* Small constant values are encoded in the operand. */
  194. async = GOMP_LAUNCH_OP (tag);
  195. if (async == GOMP_LAUNCH_OP_MAX)
  196. async = va_arg (ap, unsigned);
  197. if (profiling_p)
  198. {
  199. prof_info.async = async;
  200. prof_info.async_queue = prof_info.async;
  201. }
  202. break;
  203. }
  204. case GOMP_LAUNCH_WAIT:
  205. {
  206. unsigned num_waits = GOMP_LAUNCH_OP (tag);
  207. goacc_wait (async, num_waits, &ap);
  208. break;
  209. }
  210. default:
  211. gomp_fatal ("unrecognized offload code '%d',"
  212. " libgomp is too old", GOMP_LAUNCH_CODE (tag));
  213. }
  214. }
  215. va_end (ap);
  216. if (!(acc_dev->capabilities & GOMP_OFFLOAD_CAP_NATIVE_EXEC))
  217. {
  218. k.host_start = (uintptr_t) fn;
  219. k.host_end = k.host_start + 1;
  220. gomp_mutex_lock (&acc_dev->lock);
  221. tgt_fn_key = splay_tree_lookup (&acc_dev->mem_map, &k);
  222. gomp_mutex_unlock (&acc_dev->lock);
  223. if (tgt_fn_key == NULL)
  224. gomp_fatal ("target function wasn't mapped");
  225. tgt_fn = (void (*)) tgt_fn_key->tgt_offset;
  226. }
  227. else
  228. tgt_fn = (void (*)) fn;
  229. acc_event_info enter_exit_data_event_info;
  230. if (profiling_p)
  231. {
  232. prof_info.event_type = acc_ev_enter_data_start;
  233. enter_exit_data_event_info.other_event.event_type
  234. = prof_info.event_type;
  235. enter_exit_data_event_info.other_event.valid_bytes
  236. = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
  237. enter_exit_data_event_info.other_event.parent_construct
  238. = compute_construct_event_info.other_event.parent_construct;
  239. enter_exit_data_event_info.other_event.implicit = 1;
  240. enter_exit_data_event_info.other_event.tool_info = NULL;
  241. goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
  242. &api_info);
  243. }
  244. goacc_aq aq = get_goacc_asyncqueue (async);
  245. tgt = goacc_map_vars (acc_dev, aq, mapnum, hostaddrs, NULL, sizes, kinds,
  246. true, 0);
  247. if (profiling_p)
  248. {
  249. prof_info.event_type = acc_ev_enter_data_end;
  250. enter_exit_data_event_info.other_event.event_type
  251. = prof_info.event_type;
  252. goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
  253. &api_info);
  254. }
  255. devaddrs = gomp_alloca (sizeof (void *) * mapnum);
  256. for (i = 0; i < mapnum; i++)
  257. devaddrs[i] = (void *) gomp_map_val (tgt, hostaddrs, i);
  258. if (aq == NULL)
  259. acc_dev->openacc.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs, dims,
  260. tgt);
  261. else
  262. acc_dev->openacc.async.exec_func (tgt_fn, mapnum, hostaddrs, devaddrs,
  263. dims, tgt, aq);
  264. if (profiling_p)
  265. {
  266. prof_info.event_type = acc_ev_exit_data_start;
  267. enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
  268. enter_exit_data_event_info.other_event.tool_info = NULL;
  269. goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
  270. &api_info);
  271. }
  272. /* If running synchronously (aq == NULL), this will unmap immediately. */
  273. goacc_unmap_vars (tgt, true, aq);
  274. if (profiling_p)
  275. {
  276. prof_info.event_type = acc_ev_exit_data_end;
  277. enter_exit_data_event_info.other_event.event_type = prof_info.event_type;
  278. goacc_profiling_dispatch (&prof_info, &enter_exit_data_event_info,
  279. &api_info);
  280. }
  281. out_prof:
  282. if (profiling_p)
  283. {
  284. prof_info.event_type = acc_ev_compute_construct_end;
  285. compute_construct_event_info.other_event.event_type
  286. = prof_info.event_type;
  287. goacc_profiling_dispatch (&prof_info, &compute_construct_event_info,
  288. &api_info);
  289. thr->prof_info = NULL;
  290. thr->api_info = NULL;
  291. }
  292. }
  293. /* Legacy entry point (GCC 5). Only provide host fallback execution. */
  294. void
  295. GOACC_parallel (int flags_m, void (*fn) (void *),
  296. size_t mapnum, void **hostaddrs, size_t *sizes,
  297. unsigned short *kinds,
  298. int num_gangs, int num_workers, int vector_length,
  299. int async, int num_waits, ...)
  300. {
  301. goacc_save_and_set_bind (acc_device_host);
  302. fn (hostaddrs);
  303. goacc_restore_bind ();
  304. }
  305. void
  306. GOACC_data_start (int flags_m, size_t mapnum,
  307. void **hostaddrs, size_t *sizes, unsigned short *kinds)
  308. {
  309. int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
  310. struct target_mem_desc *tgt;
  311. #ifdef HAVE_INTTYPES_H
  312. gomp_debug (0, "%s: mapnum=%"PRIu64", hostaddrs=%p, size=%p, kinds=%p\n",
  313. __FUNCTION__, (uint64_t) mapnum, hostaddrs, sizes, kinds);
  314. #else
  315. gomp_debug (0, "%s: mapnum=%lu, hostaddrs=%p, sizes=%p, kinds=%p\n",
  316. __FUNCTION__, (unsigned long) mapnum, hostaddrs, sizes, kinds);
  317. #endif
  318. goacc_lazy_initialize ();
  319. struct goacc_thread *thr = goacc_thread ();
  320. struct gomp_device_descr *acc_dev = thr->dev;
  321. bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
  322. acc_prof_info prof_info;
  323. if (profiling_p)
  324. {
  325. thr->prof_info = &prof_info;
  326. prof_info.event_type = acc_ev_enter_data_start;
  327. prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
  328. prof_info.version = _ACC_PROF_INFO_VERSION;
  329. prof_info.device_type = acc_device_type (acc_dev->type);
  330. prof_info.device_number = acc_dev->target_id;
  331. prof_info.thread_id = -1;
  332. prof_info.async = acc_async_sync; /* Always synchronous. */
  333. prof_info.async_queue = prof_info.async;
  334. prof_info.src_file = NULL;
  335. prof_info.func_name = NULL;
  336. prof_info.line_no = -1;
  337. prof_info.end_line_no = -1;
  338. prof_info.func_line_no = -1;
  339. prof_info.func_end_line_no = -1;
  340. }
  341. acc_event_info enter_data_event_info;
  342. if (profiling_p)
  343. {
  344. enter_data_event_info.other_event.event_type
  345. = prof_info.event_type;
  346. enter_data_event_info.other_event.valid_bytes
  347. = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
  348. enter_data_event_info.other_event.parent_construct = acc_construct_data;
  349. for (int i = 0; i < mapnum; ++i)
  350. if ((kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR
  351. || (kinds[i] & 0xff) == GOMP_MAP_USE_DEVICE_PTR_IF_PRESENT)
  352. {
  353. /* If there is one such data mapping kind, then this is actually an
  354. OpenACC 'host_data' construct. (GCC maps the OpenACC
  355. 'host_data' construct to the OpenACC 'data' construct.) Apart
  356. from artificial test cases (such as an OpenACC 'host_data'
  357. construct's (implicit) device initialization when there hasn't
  358. been any device data be set up before...), there can't really
  359. any meaningful events be generated from OpenACC 'host_data'
  360. constructs, though. */
  361. enter_data_event_info.other_event.parent_construct
  362. = acc_construct_host_data;
  363. break;
  364. }
  365. enter_data_event_info.other_event.implicit = 0;
  366. enter_data_event_info.other_event.tool_info = NULL;
  367. }
  368. acc_api_info api_info;
  369. if (profiling_p)
  370. {
  371. thr->api_info = &api_info;
  372. api_info.device_api = acc_device_api_none;
  373. api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
  374. api_info.device_type = prof_info.device_type;
  375. api_info.vendor = -1;
  376. api_info.device_handle = NULL;
  377. api_info.context_handle = NULL;
  378. api_info.async_handle = NULL;
  379. }
  380. if (profiling_p)
  381. goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
  382. /* Host fallback or 'do nothing'. */
  383. if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
  384. || (flags & GOACC_FLAG_HOST_FALLBACK))
  385. {
  386. prof_info.device_type = acc_device_host;
  387. api_info.device_type = prof_info.device_type;
  388. tgt = goacc_map_vars (NULL, NULL, 0, NULL, NULL, NULL, NULL, true, 0);
  389. tgt->prev = thr->mapped_data;
  390. thr->mapped_data = tgt;
  391. goto out_prof;
  392. }
  393. gomp_debug (0, " %s: prepare mappings\n", __FUNCTION__);
  394. tgt = goacc_map_vars (acc_dev, NULL, mapnum, hostaddrs, NULL, sizes, kinds,
  395. true, 0);
  396. gomp_debug (0, " %s: mappings prepared\n", __FUNCTION__);
  397. tgt->prev = thr->mapped_data;
  398. thr->mapped_data = tgt;
  399. out_prof:
  400. if (profiling_p)
  401. {
  402. prof_info.event_type = acc_ev_enter_data_end;
  403. enter_data_event_info.other_event.event_type = prof_info.event_type;
  404. goacc_profiling_dispatch (&prof_info, &enter_data_event_info, &api_info);
  405. thr->prof_info = NULL;
  406. thr->api_info = NULL;
  407. }
  408. }
  409. void
  410. GOACC_data_end (void)
  411. {
  412. struct goacc_thread *thr = goacc_thread ();
  413. struct gomp_device_descr *acc_dev = thr->dev;
  414. struct target_mem_desc *tgt = thr->mapped_data;
  415. bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
  416. acc_prof_info prof_info;
  417. if (profiling_p)
  418. {
  419. thr->prof_info = &prof_info;
  420. prof_info.event_type = acc_ev_exit_data_start;
  421. prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
  422. prof_info.version = _ACC_PROF_INFO_VERSION;
  423. prof_info.device_type = acc_device_type (acc_dev->type);
  424. prof_info.device_number = acc_dev->target_id;
  425. prof_info.thread_id = -1;
  426. prof_info.async = acc_async_sync; /* Always synchronous. */
  427. prof_info.async_queue = prof_info.async;
  428. prof_info.src_file = NULL;
  429. prof_info.func_name = NULL;
  430. prof_info.line_no = -1;
  431. prof_info.end_line_no = -1;
  432. prof_info.func_line_no = -1;
  433. prof_info.func_end_line_no = -1;
  434. }
  435. acc_event_info exit_data_event_info;
  436. if (profiling_p)
  437. {
  438. exit_data_event_info.other_event.event_type
  439. = prof_info.event_type;
  440. exit_data_event_info.other_event.valid_bytes
  441. = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
  442. exit_data_event_info.other_event.parent_construct = acc_construct_data;
  443. exit_data_event_info.other_event.implicit = 0;
  444. exit_data_event_info.other_event.tool_info = NULL;
  445. }
  446. acc_api_info api_info;
  447. if (profiling_p)
  448. {
  449. thr->api_info = &api_info;
  450. api_info.device_api = acc_device_api_none;
  451. api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
  452. api_info.device_type = prof_info.device_type;
  453. api_info.vendor = -1;
  454. api_info.device_handle = NULL;
  455. api_info.context_handle = NULL;
  456. api_info.async_handle = NULL;
  457. }
  458. if (profiling_p)
  459. goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
  460. gomp_debug (0, " %s: restore mappings\n", __FUNCTION__);
  461. thr->mapped_data = tgt->prev;
  462. goacc_unmap_vars (tgt, true, NULL);
  463. gomp_debug (0, " %s: mappings restored\n", __FUNCTION__);
  464. if (profiling_p)
  465. {
  466. prof_info.event_type = acc_ev_exit_data_end;
  467. exit_data_event_info.other_event.event_type = prof_info.event_type;
  468. goacc_profiling_dispatch (&prof_info, &exit_data_event_info, &api_info);
  469. thr->prof_info = NULL;
  470. thr->api_info = NULL;
  471. }
  472. }
  473. void
  474. GOACC_update (int flags_m, size_t mapnum,
  475. void **hostaddrs, size_t *sizes, unsigned short *kinds,
  476. int async, int num_waits, ...)
  477. {
  478. int flags = GOACC_FLAGS_UNMARSHAL (flags_m);
  479. size_t i;
  480. goacc_lazy_initialize ();
  481. struct goacc_thread *thr = goacc_thread ();
  482. struct gomp_device_descr *acc_dev = thr->dev;
  483. bool profiling_p = GOACC_PROFILING_DISPATCH_P (true);
  484. acc_prof_info prof_info;
  485. if (profiling_p)
  486. {
  487. thr->prof_info = &prof_info;
  488. prof_info.event_type = acc_ev_update_start;
  489. prof_info.valid_bytes = _ACC_PROF_INFO_VALID_BYTES;
  490. prof_info.version = _ACC_PROF_INFO_VERSION;
  491. prof_info.device_type = acc_device_type (acc_dev->type);
  492. prof_info.device_number = acc_dev->target_id;
  493. prof_info.thread_id = -1;
  494. prof_info.async = async;
  495. prof_info.async_queue = prof_info.async;
  496. prof_info.src_file = NULL;
  497. prof_info.func_name = NULL;
  498. prof_info.line_no = -1;
  499. prof_info.end_line_no = -1;
  500. prof_info.func_line_no = -1;
  501. prof_info.func_end_line_no = -1;
  502. }
  503. acc_event_info update_event_info;
  504. if (profiling_p)
  505. {
  506. update_event_info.other_event.event_type
  507. = prof_info.event_type;
  508. update_event_info.other_event.valid_bytes
  509. = _ACC_OTHER_EVENT_INFO_VALID_BYTES;
  510. update_event_info.other_event.parent_construct = acc_construct_update;
  511. update_event_info.other_event.implicit = 0;
  512. update_event_info.other_event.tool_info = NULL;
  513. }
  514. acc_api_info api_info;
  515. if (profiling_p)
  516. {
  517. thr->api_info = &api_info;
  518. api_info.device_api = acc_device_api_none;
  519. api_info.valid_bytes = _ACC_API_INFO_VALID_BYTES;
  520. api_info.device_type = prof_info.device_type;
  521. api_info.vendor = -1;
  522. api_info.device_handle = NULL;
  523. api_info.context_handle = NULL;
  524. api_info.async_handle = NULL;
  525. }
  526. if (profiling_p)
  527. goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
  528. if ((acc_dev->capabilities & GOMP_OFFLOAD_CAP_SHARED_MEM)
  529. || (flags & GOACC_FLAG_HOST_FALLBACK))
  530. {
  531. prof_info.device_type = acc_device_host;
  532. api_info.device_type = prof_info.device_type;
  533. goto out_prof;
  534. }
  535. if (num_waits)
  536. {
  537. va_list ap;
  538. va_start (ap, num_waits);
  539. goacc_wait (async, num_waits, &ap);
  540. va_end (ap);
  541. }
  542. bool update_device = false;
  543. for (i = 0; i < mapnum; ++i)
  544. {
  545. unsigned char kind = kinds[i] & 0xff;
  546. switch (kind)
  547. {
  548. case GOMP_MAP_POINTER:
  549. case GOMP_MAP_TO_PSET:
  550. break;
  551. case GOMP_MAP_ALWAYS_POINTER:
  552. if (update_device)
  553. {
  554. /* Save the contents of the host pointer. */
  555. void *dptr = acc_deviceptr (hostaddrs[i-1]);
  556. uintptr_t t = *(uintptr_t *) hostaddrs[i];
  557. /* Update the contents of the host pointer to reflect
  558. the value of the allocated device memory in the
  559. previous pointer. */
  560. *(uintptr_t *) hostaddrs[i] = (uintptr_t)dptr;
  561. /* TODO: verify that we really cannot use acc_update_device_async
  562. here. */
  563. acc_update_device (hostaddrs[i], sizeof (uintptr_t));
  564. /* Restore the host pointer. */
  565. *(uintptr_t *) hostaddrs[i] = t;
  566. update_device = false;
  567. }
  568. break;
  569. case GOMP_MAP_TO:
  570. if (!acc_is_present (hostaddrs[i], sizes[i]))
  571. {
  572. update_device = false;
  573. break;
  574. }
  575. /* Fallthru */
  576. case GOMP_MAP_FORCE_TO:
  577. update_device = true;
  578. acc_update_device_async (hostaddrs[i], sizes[i], async);
  579. break;
  580. case GOMP_MAP_FROM:
  581. if (!acc_is_present (hostaddrs[i], sizes[i]))
  582. {
  583. update_device = false;
  584. break;
  585. }
  586. /* Fallthru */
  587. case GOMP_MAP_FORCE_FROM:
  588. update_device = false;
  589. acc_update_self_async (hostaddrs[i], sizes[i], async);
  590. break;
  591. default:
  592. gomp_fatal (">>>> GOACC_update UNHANDLED kind 0x%.2x", kind);
  593. break;
  594. }
  595. }
  596. out_prof:
  597. if (profiling_p)
  598. {
  599. prof_info.event_type = acc_ev_update_end;
  600. update_event_info.other_event.event_type = prof_info.event_type;
  601. goacc_profiling_dispatch (&prof_info, &update_event_info, &api_info);
  602. thr->prof_info = NULL;
  603. thr->api_info = NULL;
  604. }
  605. }
  606. /* Legacy entry point (GCC 5). */
  607. int
  608. GOACC_get_num_threads (void)
  609. {
  610. return 1;
  611. }
  612. /* Legacy entry point (GCC 5). */
  613. int
  614. GOACC_get_thread_num (void)
  615. {
  616. return 0;
  617. }