single.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /* Single-image implementation of GNU Fortran Coarray Library
  2. Copyright (C) 2011-2015 Free Software Foundation, Inc.
  3. Contributed by Tobias Burnus <burnus@net-b.de>
  4. This file is part of the GNU Fortran Coarray Runtime Library (libcaf).
  5. Libcaf is free software; you can redistribute it and/or modify
  6. it 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. Libcaf is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for 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. #include "libcaf.h"
  21. #include <stdio.h> /* For fputs and fprintf. */
  22. #include <stdlib.h> /* For exit and malloc. */
  23. #include <string.h> /* For memcpy and memset. */
  24. #include <stdarg.h> /* For variadic arguments. */
  25. #include <assert.h>
  26. /* Define GFC_CAF_CHECK to enable run-time checking. */
  27. /* #define GFC_CAF_CHECK 1 */
  28. typedef void* single_token_t;
  29. #define TOKEN(X) ((single_token_t) (X))
  30. /* Single-image implementation of the CAF library.
  31. Note: For performance reasons -fcoarry=single should be used
  32. rather than this library. */
  33. /* Global variables. */
  34. caf_static_t *caf_static_list = NULL;
  35. /* Keep in sync with mpi.c. */
  36. static void
  37. caf_runtime_error (const char *message, ...)
  38. {
  39. va_list ap;
  40. fprintf (stderr, "Fortran runtime error: ");
  41. va_start (ap, message);
  42. vfprintf (stderr, message, ap);
  43. va_end (ap);
  44. fprintf (stderr, "\n");
  45. /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */
  46. exit (EXIT_FAILURE);
  47. }
  48. void
  49. _gfortran_caf_init (int *argc __attribute__ ((unused)),
  50. char ***argv __attribute__ ((unused)))
  51. {
  52. }
  53. void
  54. _gfortran_caf_finalize (void)
  55. {
  56. while (caf_static_list != NULL)
  57. {
  58. caf_static_t *tmp = caf_static_list->prev;
  59. free (caf_static_list->token);
  60. free (caf_static_list);
  61. caf_static_list = tmp;
  62. }
  63. }
  64. int
  65. _gfortran_caf_this_image (int distance __attribute__ ((unused)))
  66. {
  67. return 1;
  68. }
  69. int
  70. _gfortran_caf_num_images (int distance __attribute__ ((unused)),
  71. int failed __attribute__ ((unused)))
  72. {
  73. return 1;
  74. }
  75. void *
  76. _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token,
  77. int *stat, char *errmsg, int errmsg_len)
  78. {
  79. void *local;
  80. if (type == CAF_REGTYPE_LOCK_STATIC || type == CAF_REGTYPE_LOCK_ALLOC
  81. || type == CAF_REGTYPE_CRITICAL)
  82. local = calloc (size, sizeof (bool));
  83. else
  84. local = malloc (size);
  85. *token = malloc (sizeof (single_token_t));
  86. if (unlikely (local == NULL || token == NULL))
  87. {
  88. const char msg[] = "Failed to allocate coarray";
  89. if (stat)
  90. {
  91. *stat = 1;
  92. if (errmsg_len > 0)
  93. {
  94. int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len
  95. : (int) sizeof (msg);
  96. memcpy (errmsg, msg, len);
  97. if (errmsg_len > len)
  98. memset (&errmsg[len], ' ', errmsg_len-len);
  99. }
  100. return NULL;
  101. }
  102. else
  103. caf_runtime_error (msg);
  104. }
  105. *token = local;
  106. if (stat)
  107. *stat = 0;
  108. if (type == CAF_REGTYPE_COARRAY_STATIC || type == CAF_REGTYPE_LOCK_STATIC
  109. || type == CAF_REGTYPE_CRITICAL)
  110. {
  111. caf_static_t *tmp = malloc (sizeof (caf_static_t));
  112. tmp->prev = caf_static_list;
  113. tmp->token = *token;
  114. caf_static_list = tmp;
  115. }
  116. return local;
  117. }
  118. void
  119. _gfortran_caf_deregister (caf_token_t *token, int *stat,
  120. char *errmsg __attribute__ ((unused)),
  121. int errmsg_len __attribute__ ((unused)))
  122. {
  123. free (TOKEN(*token));
  124. if (stat)
  125. *stat = 0;
  126. }
  127. void
  128. _gfortran_caf_sync_all (int *stat,
  129. char *errmsg __attribute__ ((unused)),
  130. int errmsg_len __attribute__ ((unused)))
  131. {
  132. __asm__ __volatile__ ("":::"memory");
  133. if (stat)
  134. *stat = 0;
  135. }
  136. void
  137. _gfortran_caf_sync_memory (int *stat,
  138. char *errmsg __attribute__ ((unused)),
  139. int errmsg_len __attribute__ ((unused)))
  140. {
  141. __asm__ __volatile__ ("":::"memory");
  142. if (stat)
  143. *stat = 0;
  144. }
  145. void
  146. _gfortran_caf_sync_images (int count __attribute__ ((unused)),
  147. int images[] __attribute__ ((unused)),
  148. int *stat,
  149. char *errmsg __attribute__ ((unused)),
  150. int errmsg_len __attribute__ ((unused)))
  151. {
  152. #ifdef GFC_CAF_CHECK
  153. int i;
  154. for (i = 0; i < count; i++)
  155. if (images[i] != 1)
  156. {
  157. fprintf (stderr, "COARRAY ERROR: Invalid image index %d to SYNC "
  158. "IMAGES", images[i]);
  159. exit (EXIT_FAILURE);
  160. }
  161. #endif
  162. __asm__ __volatile__ ("":::"memory");
  163. if (stat)
  164. *stat = 0;
  165. }
  166. void
  167. _gfortran_caf_error_stop_str (const char *string, int32_t len)
  168. {
  169. fputs ("ERROR STOP ", stderr);
  170. while (len--)
  171. fputc (*(string++), stderr);
  172. fputs ("\n", stderr);
  173. exit (1);
  174. }
  175. void
  176. _gfortran_caf_error_stop (int32_t error)
  177. {
  178. fprintf (stderr, "ERROR STOP %d\n", error);
  179. exit (error);
  180. }
  181. void
  182. _gfortran_caf_co_broadcast (gfc_descriptor_t *a __attribute__ ((unused)),
  183. int source_image __attribute__ ((unused)),
  184. int *stat, char *errmsg __attribute__ ((unused)),
  185. int errmsg_len __attribute__ ((unused)))
  186. {
  187. if (stat)
  188. *stat = 0;
  189. }
  190. void
  191. _gfortran_caf_co_sum (gfc_descriptor_t *a __attribute__ ((unused)),
  192. int result_image __attribute__ ((unused)),
  193. int *stat, char *errmsg __attribute__ ((unused)),
  194. int errmsg_len __attribute__ ((unused)))
  195. {
  196. if (stat)
  197. *stat = 0;
  198. }
  199. void
  200. _gfortran_caf_co_min (gfc_descriptor_t *a __attribute__ ((unused)),
  201. int result_image __attribute__ ((unused)),
  202. int *stat, char *errmsg __attribute__ ((unused)),
  203. int a_len __attribute__ ((unused)),
  204. int errmsg_len __attribute__ ((unused)))
  205. {
  206. if (stat)
  207. *stat = 0;
  208. }
  209. void
  210. _gfortran_caf_co_max (gfc_descriptor_t *a __attribute__ ((unused)),
  211. int result_image __attribute__ ((unused)),
  212. int *stat, char *errmsg __attribute__ ((unused)),
  213. int a_len __attribute__ ((unused)),
  214. int errmsg_len __attribute__ ((unused)))
  215. {
  216. if (stat)
  217. *stat = 0;
  218. }
  219. void
  220. _gfortran_caf_co_reduce (gfc_descriptor_t *a __attribute__ ((unused)),
  221. void * (*opr) (void *, void *)
  222. __attribute__ ((unused)),
  223. int opr_flags __attribute__ ((unused)),
  224. int result_image __attribute__ ((unused)),
  225. int *stat, char *errmsg __attribute__ ((unused)),
  226. int a_len __attribute__ ((unused)),
  227. int errmsg_len __attribute__ ((unused)))
  228. {
  229. if (stat)
  230. *stat = 0;
  231. }
  232. static void
  233. assign_char4_from_char1 (size_t dst_size, size_t src_size, uint32_t *dst,
  234. unsigned char *src)
  235. {
  236. size_t i, n;
  237. n = dst_size/4 > src_size ? src_size : dst_size/4;
  238. for (i = 0; i < n; ++i)
  239. dst[i] = (int32_t) src[i];
  240. for (; i < dst_size/4; ++i)
  241. dst[i] = (int32_t) ' ';
  242. }
  243. static void
  244. assign_char1_from_char4 (size_t dst_size, size_t src_size, unsigned char *dst,
  245. uint32_t *src)
  246. {
  247. size_t i, n;
  248. n = dst_size > src_size/4 ? src_size/4 : dst_size;
  249. for (i = 0; i < n; ++i)
  250. dst[i] = src[i] > UINT8_MAX ? (unsigned char) '?' : (unsigned char) src[i];
  251. if (dst_size > n)
  252. memset(&dst[n], ' ', dst_size - n);
  253. }
  254. static void
  255. convert_type (void *dst, int dst_type, int dst_kind, void *src, int src_type,
  256. int src_kind)
  257. {
  258. #ifdef HAVE_GFC_INTEGER_16
  259. typedef __int128 int128t;
  260. #else
  261. typedef int64_t int128t;
  262. #endif
  263. #if defined(GFC_REAL_16_IS_LONG_DOUBLE)
  264. typedef long double real128t;
  265. typedef _Complex long double complex128t;
  266. #elif defined(HAVE_GFC_REAL_16)
  267. typedef _Complex float __attribute__((mode(TC))) __complex128;
  268. typedef __float128 real128t;
  269. typedef __complex128 complex128t;
  270. #elif defined(HAVE_GFC_REAL_10)
  271. typedef long double real128t;
  272. typedef long double complex128t;
  273. #else
  274. typedef double real128t;
  275. typedef _Complex double complex128t;
  276. #endif
  277. int128t int_val = 0;
  278. real128t real_val = 0;
  279. complex128t cmpx_val = 0;
  280. switch (src_type)
  281. {
  282. case BT_INTEGER:
  283. if (src_kind == 1)
  284. int_val = *(int8_t*) src;
  285. else if (src_kind == 2)
  286. int_val = *(int16_t*) src;
  287. else if (src_kind == 4)
  288. int_val = *(int32_t*) src;
  289. else if (src_kind == 8)
  290. int_val = *(int64_t*) src;
  291. #ifdef HAVE_GFC_INTEGER_16
  292. else if (src_kind == 16)
  293. int_val = *(int128t*) src;
  294. #endif
  295. else
  296. goto error;
  297. break;
  298. case BT_REAL:
  299. if (src_kind == 4)
  300. real_val = *(float*) src;
  301. else if (src_kind == 8)
  302. real_val = *(double*) src;
  303. #ifdef HAVE_GFC_REAL_10
  304. else if (src_kind == 10)
  305. real_val = *(long double*) src;
  306. #endif
  307. #ifdef HAVE_GFC_REAL_16
  308. else if (src_kind == 16)
  309. real_val = *(real128t*) src;
  310. #endif
  311. else
  312. goto error;
  313. break;
  314. case BT_COMPLEX:
  315. if (src_kind == 4)
  316. cmpx_val = *(_Complex float*) src;
  317. else if (src_kind == 8)
  318. cmpx_val = *(_Complex double*) src;
  319. #ifdef HAVE_GFC_REAL_10
  320. else if (src_kind == 10)
  321. cmpx_val = *(_Complex long double*) src;
  322. #endif
  323. #ifdef HAVE_GFC_REAL_16
  324. else if (src_kind == 16)
  325. cmpx_val = *(complex128t*) src;
  326. #endif
  327. else
  328. goto error;
  329. break;
  330. default:
  331. goto error;
  332. }
  333. switch (dst_type)
  334. {
  335. case BT_INTEGER:
  336. if (src_type == BT_INTEGER)
  337. {
  338. if (dst_kind == 1)
  339. *(int8_t*) dst = (int8_t) int_val;
  340. else if (dst_kind == 2)
  341. *(int16_t*) dst = (int16_t) int_val;
  342. else if (dst_kind == 4)
  343. *(int32_t*) dst = (int32_t) int_val;
  344. else if (dst_kind == 8)
  345. *(int64_t*) dst = (int64_t) int_val;
  346. #ifdef HAVE_GFC_INTEGER_16
  347. else if (dst_kind == 16)
  348. *(int128t*) dst = (int128t) int_val;
  349. #endif
  350. else
  351. goto error;
  352. }
  353. else if (src_type == BT_REAL)
  354. {
  355. if (dst_kind == 1)
  356. *(int8_t*) dst = (int8_t) real_val;
  357. else if (dst_kind == 2)
  358. *(int16_t*) dst = (int16_t) real_val;
  359. else if (dst_kind == 4)
  360. *(int32_t*) dst = (int32_t) real_val;
  361. else if (dst_kind == 8)
  362. *(int64_t*) dst = (int64_t) real_val;
  363. #ifdef HAVE_GFC_INTEGER_16
  364. else if (dst_kind == 16)
  365. *(int128t*) dst = (int128t) real_val;
  366. #endif
  367. else
  368. goto error;
  369. }
  370. else if (src_type == BT_COMPLEX)
  371. {
  372. if (dst_kind == 1)
  373. *(int8_t*) dst = (int8_t) cmpx_val;
  374. else if (dst_kind == 2)
  375. *(int16_t*) dst = (int16_t) cmpx_val;
  376. else if (dst_kind == 4)
  377. *(int32_t*) dst = (int32_t) cmpx_val;
  378. else if (dst_kind == 8)
  379. *(int64_t*) dst = (int64_t) cmpx_val;
  380. #ifdef HAVE_GFC_INTEGER_16
  381. else if (dst_kind == 16)
  382. *(int128t*) dst = (int128t) cmpx_val;
  383. #endif
  384. else
  385. goto error;
  386. }
  387. else
  388. goto error;
  389. break;
  390. case BT_REAL:
  391. if (src_type == BT_INTEGER)
  392. {
  393. if (dst_kind == 4)
  394. *(float*) dst = (float) int_val;
  395. else if (dst_kind == 8)
  396. *(double*) dst = (double) int_val;
  397. #ifdef HAVE_GFC_REAL_10
  398. else if (dst_kind == 10)
  399. *(long double*) dst = (long double) int_val;
  400. #endif
  401. #ifdef HAVE_GFC_REAL_16
  402. else if (dst_kind == 16)
  403. *(real128t*) dst = (real128t) int_val;
  404. #endif
  405. else
  406. goto error;
  407. }
  408. else if (src_type == BT_REAL)
  409. {
  410. if (dst_kind == 4)
  411. *(float*) dst = (float) real_val;
  412. else if (dst_kind == 8)
  413. *(double*) dst = (double) real_val;
  414. #ifdef HAVE_GFC_REAL_10
  415. else if (dst_kind == 10)
  416. *(long double*) dst = (long double) real_val;
  417. #endif
  418. #ifdef HAVE_GFC_REAL_16
  419. else if (dst_kind == 16)
  420. *(real128t*) dst = (real128t) real_val;
  421. #endif
  422. else
  423. goto error;
  424. }
  425. else if (src_type == BT_COMPLEX)
  426. {
  427. if (dst_kind == 4)
  428. *(float*) dst = (float) cmpx_val;
  429. else if (dst_kind == 8)
  430. *(double*) dst = (double) cmpx_val;
  431. #ifdef HAVE_GFC_REAL_10
  432. else if (dst_kind == 10)
  433. *(long double*) dst = (long double) cmpx_val;
  434. #endif
  435. #ifdef HAVE_GFC_REAL_16
  436. else if (dst_kind == 16)
  437. *(real128t*) dst = (real128t) cmpx_val;
  438. #endif
  439. else
  440. goto error;
  441. }
  442. break;
  443. case BT_COMPLEX:
  444. if (src_type == BT_INTEGER)
  445. {
  446. if (dst_kind == 4)
  447. *(_Complex float*) dst = (_Complex float) int_val;
  448. else if (dst_kind == 8)
  449. *(_Complex double*) dst = (_Complex double) int_val;
  450. #ifdef HAVE_GFC_REAL_10
  451. else if (dst_kind == 10)
  452. *(_Complex long double*) dst = (_Complex long double) int_val;
  453. #endif
  454. #ifdef HAVE_GFC_REAL_16
  455. else if (dst_kind == 16)
  456. *(complex128t*) dst = (complex128t) int_val;
  457. #endif
  458. else
  459. goto error;
  460. }
  461. else if (src_type == BT_REAL)
  462. {
  463. if (dst_kind == 4)
  464. *(_Complex float*) dst = (_Complex float) real_val;
  465. else if (dst_kind == 8)
  466. *(_Complex double*) dst = (_Complex double) real_val;
  467. #ifdef HAVE_GFC_REAL_10
  468. else if (dst_kind == 10)
  469. *(_Complex long double*) dst = (_Complex long double) real_val;
  470. #endif
  471. #ifdef HAVE_GFC_REAL_16
  472. else if (dst_kind == 16)
  473. *(complex128t*) dst = (complex128t) real_val;
  474. #endif
  475. else
  476. goto error;
  477. }
  478. else if (src_type == BT_COMPLEX)
  479. {
  480. if (dst_kind == 4)
  481. *(_Complex float*) dst = (_Complex float) cmpx_val;
  482. else if (dst_kind == 8)
  483. *(_Complex double*) dst = (_Complex double) cmpx_val;
  484. #ifdef HAVE_GFC_REAL_10
  485. else if (dst_kind == 10)
  486. *(_Complex long double*) dst = (_Complex long double) cmpx_val;
  487. #endif
  488. #ifdef HAVE_GFC_REAL_16
  489. else if (dst_kind == 16)
  490. *(complex128t*) dst = (complex128t) cmpx_val;
  491. #endif
  492. else
  493. goto error;
  494. }
  495. else
  496. goto error;
  497. break;
  498. default:
  499. goto error;
  500. }
  501. error:
  502. fprintf (stderr, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind "
  503. "%d to type %d kind %d\n", src_type, src_kind, dst_type, dst_kind);
  504. abort();
  505. }
  506. void
  507. _gfortran_caf_get (caf_token_t token, size_t offset,
  508. int image_index __attribute__ ((unused)),
  509. gfc_descriptor_t *src,
  510. caf_vector_t *src_vector __attribute__ ((unused)),
  511. gfc_descriptor_t *dest, int src_kind, int dst_kind,
  512. bool may_require_tmp)
  513. {
  514. /* FIXME: Handle vector subscripts. */
  515. size_t i, k, size;
  516. int j;
  517. int rank = GFC_DESCRIPTOR_RANK (dest);
  518. size_t src_size = GFC_DESCRIPTOR_SIZE (src);
  519. size_t dst_size = GFC_DESCRIPTOR_SIZE (dest);
  520. if (rank == 0)
  521. {
  522. void *sr = (void *) ((char *) TOKEN (token) + offset);
  523. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  524. && dst_kind == src_kind)
  525. {
  526. memmove (GFC_DESCRIPTOR_DATA (dest), sr,
  527. dst_size > src_size ? src_size : dst_size);
  528. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size)
  529. {
  530. if (dst_kind == 1)
  531. memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest) + src_size,
  532. ' ', dst_size - src_size);
  533. else /* dst_kind == 4. */
  534. for (i = src_size/4; i < dst_size/4; i++)
  535. ((int32_t*) GFC_DESCRIPTOR_DATA (dest))[i] = (int32_t) ' ';
  536. }
  537. }
  538. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  539. assign_char1_from_char4 (dst_size, src_size, GFC_DESCRIPTOR_DATA (dest),
  540. sr);
  541. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  542. assign_char4_from_char1 (dst_size, src_size, GFC_DESCRIPTOR_DATA (dest),
  543. sr);
  544. else
  545. convert_type (GFC_DESCRIPTOR_DATA (dest), GFC_DESCRIPTOR_TYPE (dest),
  546. dst_kind, sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
  547. return;
  548. }
  549. size = 1;
  550. for (j = 0; j < rank; j++)
  551. {
  552. ptrdiff_t dimextent = dest->dim[j]._ubound - dest->dim[j].lower_bound + 1;
  553. if (dimextent < 0)
  554. dimextent = 0;
  555. size *= dimextent;
  556. }
  557. if (size == 0)
  558. return;
  559. if (may_require_tmp)
  560. {
  561. ptrdiff_t array_offset_sr, array_offset_dst;
  562. void *tmp = malloc (size*src_size);
  563. array_offset_dst = 0;
  564. for (i = 0; i < size; i++)
  565. {
  566. ptrdiff_t array_offset_sr = 0;
  567. ptrdiff_t stride = 1;
  568. ptrdiff_t extent = 1;
  569. for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
  570. {
  571. array_offset_sr += ((i / (extent*stride))
  572. % (src->dim[j]._ubound
  573. - src->dim[j].lower_bound + 1))
  574. * src->dim[j]._stride;
  575. extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
  576. stride = src->dim[j]._stride;
  577. }
  578. array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
  579. void *sr = (void *)((char *) TOKEN (token) + offset
  580. + array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
  581. memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size);
  582. array_offset_dst += src_size;
  583. }
  584. array_offset_sr = 0;
  585. for (i = 0; i < size; i++)
  586. {
  587. ptrdiff_t array_offset_dst = 0;
  588. ptrdiff_t stride = 1;
  589. ptrdiff_t extent = 1;
  590. for (j = 0; j < rank-1; j++)
  591. {
  592. array_offset_dst += ((i / (extent*stride))
  593. % (dest->dim[j]._ubound
  594. - dest->dim[j].lower_bound + 1))
  595. * dest->dim[j]._stride;
  596. extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
  597. stride = dest->dim[j]._stride;
  598. }
  599. array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
  600. void *dst = dest->base_addr
  601. + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest);
  602. void *sr = tmp + array_offset_sr;
  603. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  604. && dst_kind == src_kind)
  605. {
  606. memmove (dst, sr, dst_size > src_size ? src_size : dst_size);
  607. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER
  608. && dst_size > src_size)
  609. {
  610. if (dst_kind == 1)
  611. memset ((void*)(char*) dst + src_size, ' ',
  612. dst_size-src_size);
  613. else /* dst_kind == 4. */
  614. for (k = src_size/4; k < dst_size/4; k++)
  615. ((int32_t*) dst)[k] = (int32_t) ' ';
  616. }
  617. }
  618. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  619. assign_char1_from_char4 (dst_size, src_size, dst, sr);
  620. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  621. assign_char4_from_char1 (dst_size, src_size, dst, sr);
  622. else
  623. convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
  624. sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
  625. array_offset_sr += src_size;
  626. }
  627. free (tmp);
  628. return;
  629. }
  630. for (i = 0; i < size; i++)
  631. {
  632. ptrdiff_t array_offset_dst = 0;
  633. ptrdiff_t stride = 1;
  634. ptrdiff_t extent = 1;
  635. for (j = 0; j < rank-1; j++)
  636. {
  637. array_offset_dst += ((i / (extent*stride))
  638. % (dest->dim[j]._ubound
  639. - dest->dim[j].lower_bound + 1))
  640. * dest->dim[j]._stride;
  641. extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
  642. stride = dest->dim[j]._stride;
  643. }
  644. array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
  645. void *dst = dest->base_addr + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest);
  646. ptrdiff_t array_offset_sr = 0;
  647. stride = 1;
  648. extent = 1;
  649. for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
  650. {
  651. array_offset_sr += ((i / (extent*stride))
  652. % (src->dim[j]._ubound
  653. - src->dim[j].lower_bound + 1))
  654. * src->dim[j]._stride;
  655. extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
  656. stride = src->dim[j]._stride;
  657. }
  658. array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
  659. void *sr = (void *)((char *) TOKEN (token) + offset
  660. + array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
  661. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  662. && dst_kind == src_kind)
  663. {
  664. memmove (dst, sr, dst_size > src_size ? src_size : dst_size);
  665. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size)
  666. {
  667. if (dst_kind == 1)
  668. memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size);
  669. else /* dst_kind == 4. */
  670. for (k = src_size/4; k < dst_size/4; k++)
  671. ((int32_t*) dst)[k] = (int32_t) ' ';
  672. }
  673. }
  674. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  675. assign_char1_from_char4 (dst_size, src_size, dst, sr);
  676. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  677. assign_char4_from_char1 (dst_size, src_size, dst, sr);
  678. else
  679. convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
  680. sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
  681. }
  682. }
  683. void
  684. _gfortran_caf_send (caf_token_t token, size_t offset,
  685. int image_index __attribute__ ((unused)),
  686. gfc_descriptor_t *dest,
  687. caf_vector_t *dst_vector __attribute__ ((unused)),
  688. gfc_descriptor_t *src, int dst_kind, int src_kind,
  689. bool may_require_tmp)
  690. {
  691. /* FIXME: Handle vector subscripts. */
  692. size_t i, k, size;
  693. int j;
  694. int rank = GFC_DESCRIPTOR_RANK (dest);
  695. size_t src_size = GFC_DESCRIPTOR_SIZE (src);
  696. size_t dst_size = GFC_DESCRIPTOR_SIZE (dest);
  697. if (rank == 0)
  698. {
  699. void *dst = (void *) ((char *) TOKEN (token) + offset);
  700. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  701. && dst_kind == src_kind)
  702. {
  703. memmove (dst, GFC_DESCRIPTOR_DATA (src),
  704. dst_size > src_size ? src_size : dst_size);
  705. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size)
  706. {
  707. if (dst_kind == 1)
  708. memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size);
  709. else /* dst_kind == 4. */
  710. for (i = src_size/4; i < dst_size/4; i++)
  711. ((int32_t*) dst)[i] = (int32_t) ' ';
  712. }
  713. }
  714. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  715. assign_char1_from_char4 (dst_size, src_size, dst,
  716. GFC_DESCRIPTOR_DATA (src));
  717. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  718. assign_char4_from_char1 (dst_size, src_size, dst,
  719. GFC_DESCRIPTOR_DATA (src));
  720. else
  721. convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
  722. GFC_DESCRIPTOR_DATA (src), GFC_DESCRIPTOR_TYPE (src),
  723. src_kind);
  724. return;
  725. }
  726. size = 1;
  727. for (j = 0; j < rank; j++)
  728. {
  729. ptrdiff_t dimextent = dest->dim[j]._ubound - dest->dim[j].lower_bound + 1;
  730. if (dimextent < 0)
  731. dimextent = 0;
  732. size *= dimextent;
  733. }
  734. if (size == 0)
  735. return;
  736. if (may_require_tmp)
  737. {
  738. ptrdiff_t array_offset_sr, array_offset_dst;
  739. void *tmp;
  740. if (GFC_DESCRIPTOR_RANK (src) == 0)
  741. {
  742. tmp = malloc (src_size);
  743. memcpy (tmp, GFC_DESCRIPTOR_DATA (src), src_size);
  744. }
  745. else
  746. {
  747. tmp = malloc (size*src_size);
  748. array_offset_dst = 0;
  749. for (i = 0; i < size; i++)
  750. {
  751. ptrdiff_t array_offset_sr = 0;
  752. ptrdiff_t stride = 1;
  753. ptrdiff_t extent = 1;
  754. for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
  755. {
  756. array_offset_sr += ((i / (extent*stride))
  757. % (src->dim[j]._ubound
  758. - src->dim[j].lower_bound + 1))
  759. * src->dim[j]._stride;
  760. extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
  761. stride = src->dim[j]._stride;
  762. }
  763. array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
  764. void *sr = (void *) ((char *) src->base_addr
  765. + array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
  766. memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size);
  767. array_offset_dst += src_size;
  768. }
  769. }
  770. array_offset_sr = 0;
  771. for (i = 0; i < size; i++)
  772. {
  773. ptrdiff_t array_offset_dst = 0;
  774. ptrdiff_t stride = 1;
  775. ptrdiff_t extent = 1;
  776. for (j = 0; j < rank-1; j++)
  777. {
  778. array_offset_dst += ((i / (extent*stride))
  779. % (dest->dim[j]._ubound
  780. - dest->dim[j].lower_bound + 1))
  781. * dest->dim[j]._stride;
  782. extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
  783. stride = dest->dim[j]._stride;
  784. }
  785. array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
  786. void *dst = (void *)((char *) TOKEN (token) + offset
  787. + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest));
  788. void *sr = tmp + array_offset_sr;
  789. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  790. && dst_kind == src_kind)
  791. {
  792. memmove (dst, sr,
  793. dst_size > src_size ? src_size : dst_size);
  794. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER
  795. && dst_size > src_size)
  796. {
  797. if (dst_kind == 1)
  798. memset ((void*)(char*) dst + src_size, ' ',
  799. dst_size-src_size);
  800. else /* dst_kind == 4. */
  801. for (k = src_size/4; k < dst_size/4; k++)
  802. ((int32_t*) dst)[k] = (int32_t) ' ';
  803. }
  804. }
  805. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  806. assign_char1_from_char4 (dst_size, src_size, dst, sr);
  807. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  808. assign_char4_from_char1 (dst_size, src_size, dst, sr);
  809. else
  810. convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
  811. sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
  812. if (GFC_DESCRIPTOR_RANK (src))
  813. array_offset_sr += src_size;
  814. }
  815. free (tmp);
  816. return;
  817. }
  818. for (i = 0; i < size; i++)
  819. {
  820. ptrdiff_t array_offset_dst = 0;
  821. ptrdiff_t stride = 1;
  822. ptrdiff_t extent = 1;
  823. for (j = 0; j < rank-1; j++)
  824. {
  825. array_offset_dst += ((i / (extent*stride))
  826. % (dest->dim[j]._ubound
  827. - dest->dim[j].lower_bound + 1))
  828. * dest->dim[j]._stride;
  829. extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1);
  830. stride = dest->dim[j]._stride;
  831. }
  832. array_offset_dst += (i / extent) * dest->dim[rank-1]._stride;
  833. void *dst = (void *)((char *) TOKEN (token) + offset
  834. + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest));
  835. void *sr;
  836. if (GFC_DESCRIPTOR_RANK (src) != 0)
  837. {
  838. ptrdiff_t array_offset_sr = 0;
  839. stride = 1;
  840. extent = 1;
  841. for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++)
  842. {
  843. array_offset_sr += ((i / (extent*stride))
  844. % (src->dim[j]._ubound
  845. - src->dim[j].lower_bound + 1))
  846. * src->dim[j]._stride;
  847. extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1);
  848. stride = src->dim[j]._stride;
  849. }
  850. array_offset_sr += (i / extent) * src->dim[rank-1]._stride;
  851. sr = (void *)((char *) src->base_addr
  852. + array_offset_sr*GFC_DESCRIPTOR_SIZE (src));
  853. }
  854. else
  855. sr = src->base_addr;
  856. if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src)
  857. && dst_kind == src_kind)
  858. {
  859. memmove (dst, sr,
  860. dst_size > src_size ? src_size : dst_size);
  861. if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size)
  862. {
  863. if (dst_kind == 1)
  864. memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size);
  865. else /* dst_kind == 4. */
  866. for (k = src_size/4; k < dst_size/4; k++)
  867. ((int32_t*) dst)[k] = (int32_t) ' ';
  868. }
  869. }
  870. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1)
  871. assign_char1_from_char4 (dst_size, src_size, dst, sr);
  872. else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER)
  873. assign_char4_from_char1 (dst_size, src_size, dst, sr);
  874. else
  875. convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind,
  876. sr, GFC_DESCRIPTOR_TYPE (src), src_kind);
  877. }
  878. }
  879. void
  880. _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset,
  881. int dst_image_index, gfc_descriptor_t *dest,
  882. caf_vector_t *dst_vector, caf_token_t src_token,
  883. size_t src_offset,
  884. int src_image_index __attribute__ ((unused)),
  885. gfc_descriptor_t *src,
  886. caf_vector_t *src_vector __attribute__ ((unused)),
  887. int dst_kind, int src_kind, bool may_require_tmp)
  888. {
  889. /* FIXME: Handle vector subscript of 'src_vector'. */
  890. /* For a single image, src->base_addr should be the same as src_token + offset
  891. but to play save, we do it properly. */
  892. void *src_base = GFC_DESCRIPTOR_DATA (src);
  893. GFC_DESCRIPTOR_DATA (src) = (void *) ((char *) TOKEN (src_token) + src_offset);
  894. _gfortran_caf_send (dst_token, dst_offset, dst_image_index, dest, dst_vector,
  895. src, dst_kind, src_kind, may_require_tmp);
  896. GFC_DESCRIPTOR_DATA (src) = src_base;
  897. }
  898. void
  899. _gfortran_caf_atomic_define (caf_token_t token, size_t offset,
  900. int image_index __attribute__ ((unused)),
  901. void *value, int *stat,
  902. int type __attribute__ ((unused)), int kind)
  903. {
  904. assert(kind == 4);
  905. uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset);
  906. __atomic_store (atom, (uint32_t *) value, __ATOMIC_RELAXED);
  907. if (stat)
  908. *stat = 0;
  909. }
  910. void
  911. _gfortran_caf_atomic_ref (caf_token_t token, size_t offset,
  912. int image_index __attribute__ ((unused)),
  913. void *value, int *stat,
  914. int type __attribute__ ((unused)), int kind)
  915. {
  916. assert(kind == 4);
  917. uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset);
  918. __atomic_load (atom, (uint32_t *) value, __ATOMIC_RELAXED);
  919. if (stat)
  920. *stat = 0;
  921. }
  922. void
  923. _gfortran_caf_atomic_cas (caf_token_t token, size_t offset,
  924. int image_index __attribute__ ((unused)),
  925. void *old, void *compare, void *new_val, int *stat,
  926. int type __attribute__ ((unused)), int kind)
  927. {
  928. assert(kind == 4);
  929. uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset);
  930. *(uint32_t *) old = *(uint32_t *) compare;
  931. (void) __atomic_compare_exchange_n (atom, (uint32_t *) old,
  932. *(uint32_t *) new_val, false,
  933. __ATOMIC_RELAXED, __ATOMIC_RELAXED);
  934. if (stat)
  935. *stat = 0;
  936. }
  937. void
  938. _gfortran_caf_atomic_op (int op, caf_token_t token, size_t offset,
  939. int image_index __attribute__ ((unused)),
  940. void *value, void *old, int *stat,
  941. int type __attribute__ ((unused)), int kind)
  942. {
  943. assert(kind == 4);
  944. uint32_t res;
  945. uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset);
  946. switch (op)
  947. {
  948. case GFC_CAF_ATOMIC_ADD:
  949. res = __atomic_fetch_add (atom, *(uint32_t *) value, __ATOMIC_RELAXED);
  950. break;
  951. case GFC_CAF_ATOMIC_AND:
  952. res = __atomic_fetch_and (atom, *(uint32_t *) value, __ATOMIC_RELAXED);
  953. break;
  954. case GFC_CAF_ATOMIC_OR:
  955. res = __atomic_fetch_or (atom, *(uint32_t *) value, __ATOMIC_RELAXED);
  956. break;
  957. case GFC_CAF_ATOMIC_XOR:
  958. res = __atomic_fetch_xor (atom, *(uint32_t *) value, __ATOMIC_RELAXED);
  959. break;
  960. default:
  961. __builtin_unreachable();
  962. }
  963. if (old)
  964. *(uint32_t *) old = res;
  965. if (stat)
  966. *stat = 0;
  967. }
  968. void
  969. _gfortran_caf_lock (caf_token_t token, size_t index,
  970. int image_index __attribute__ ((unused)),
  971. int *aquired_lock, int *stat, char *errmsg, int errmsg_len)
  972. {
  973. const char *msg = "Already locked";
  974. bool *lock = &((bool *) TOKEN (token))[index];
  975. if (!*lock)
  976. {
  977. *lock = true;
  978. if (aquired_lock)
  979. *aquired_lock = (int) true;
  980. if (stat)
  981. *stat = 0;
  982. return;
  983. }
  984. if (aquired_lock)
  985. {
  986. *aquired_lock = (int) false;
  987. if (stat)
  988. *stat = 0;
  989. return;
  990. }
  991. if (stat)
  992. {
  993. *stat = 1;
  994. if (errmsg_len > 0)
  995. {
  996. int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len
  997. : (int) sizeof (msg);
  998. memcpy (errmsg, msg, len);
  999. if (errmsg_len > len)
  1000. memset (&errmsg[len], ' ', errmsg_len-len);
  1001. }
  1002. return;
  1003. }
  1004. _gfortran_caf_error_stop_str (msg, (int32_t) strlen (msg));
  1005. }
  1006. void
  1007. _gfortran_caf_unlock (caf_token_t token, size_t index,
  1008. int image_index __attribute__ ((unused)),
  1009. int *stat, char *errmsg, int errmsg_len)
  1010. {
  1011. const char *msg = "Variable is not locked";
  1012. bool *lock = &((bool *) TOKEN (token))[index];
  1013. if (*lock)
  1014. {
  1015. *lock = false;
  1016. if (stat)
  1017. *stat = 0;
  1018. return;
  1019. }
  1020. if (stat)
  1021. {
  1022. *stat = 1;
  1023. if (errmsg_len > 0)
  1024. {
  1025. int len = ((int) sizeof (msg) > errmsg_len) ? errmsg_len
  1026. : (int) sizeof (msg);
  1027. memcpy (errmsg, msg, len);
  1028. if (errmsg_len > len)
  1029. memset (&errmsg[len], ' ', errmsg_len-len);
  1030. }
  1031. return;
  1032. }
  1033. _gfortran_caf_error_stop_str (msg, (int32_t) strlen (msg));
  1034. }