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>
5 This file is part of the GNU Fortran Coarray Runtime Library (libcaf).
7 Libcaf is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libcaf is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 #include <stdio.h> /* For fputs and fprintf. */
28 #include <stdlib.h> /* For exit and malloc. */
29 #include <string.h> /* For memcpy and memset. */
30 #include <stdarg.h> /* For variadic arguments. */
33 /* Define GFC_CAF_CHECK to enable run-time checking. */
34 /* #define GFC_CAF_CHECK 1 */
36 typedef void* single_token_t
;
37 #define TOKEN(X) ((single_token_t) (X))
39 /* Single-image implementation of the CAF library.
40 Note: For performance reasons -fcoarry=single should be used
41 rather than this library. */
43 /* Global variables. */
44 caf_static_t
*caf_static_list
= NULL
;
47 /* Keep in sync with mpi.c. */
49 caf_runtime_error (const char *message
, ...)
52 fprintf (stderr
, "Fortran runtime error: ");
53 va_start (ap
, message
);
54 vfprintf (stderr
, message
, ap
);
56 fprintf (stderr
, "\n");
58 /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */
63 _gfortran_caf_init (int *argc
__attribute__ ((unused
)),
64 char ***argv
__attribute__ ((unused
)))
70 _gfortran_caf_finalize (void)
72 while (caf_static_list
!= NULL
)
74 caf_static_t
*tmp
= caf_static_list
->prev
;
75 free (caf_static_list
->token
);
76 free (caf_static_list
);
77 caf_static_list
= tmp
;
83 _gfortran_caf_this_image (int distance
__attribute__ ((unused
)))
90 _gfortran_caf_num_images (int distance
__attribute__ ((unused
)),
91 int failed
__attribute__ ((unused
)))
98 _gfortran_caf_register (size_t size
, caf_register_t type
, caf_token_t
*token
,
99 int *stat
, char *errmsg
, int errmsg_len
)
103 if (type
== CAF_REGTYPE_LOCK_STATIC
|| type
== CAF_REGTYPE_LOCK_ALLOC
104 || type
== CAF_REGTYPE_CRITICAL
)
105 local
= calloc (size
, sizeof (bool));
107 local
= malloc (size
);
108 *token
= malloc (sizeof (single_token_t
));
110 if (unlikely (local
== NULL
|| token
== NULL
))
112 const char msg
[] = "Failed to allocate coarray";
118 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
119 : (int) sizeof (msg
);
120 memcpy (errmsg
, msg
, len
);
121 if (errmsg_len
> len
)
122 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
127 caf_runtime_error (msg
);
135 if (type
== CAF_REGTYPE_COARRAY_STATIC
|| type
== CAF_REGTYPE_LOCK_STATIC
136 || type
== CAF_REGTYPE_CRITICAL
)
138 caf_static_t
*tmp
= malloc (sizeof (caf_static_t
));
139 tmp
->prev
= caf_static_list
;
141 caf_static_list
= tmp
;
148 _gfortran_caf_deregister (caf_token_t
*token
, int *stat
,
149 char *errmsg
__attribute__ ((unused
)),
150 int errmsg_len
__attribute__ ((unused
)))
152 free (TOKEN(*token
));
160 _gfortran_caf_sync_all (int *stat
,
161 char *errmsg
__attribute__ ((unused
)),
162 int errmsg_len
__attribute__ ((unused
)))
164 __asm__
__volatile__ ("":::"memory");
171 _gfortran_caf_sync_memory (int *stat
,
172 char *errmsg
__attribute__ ((unused
)),
173 int errmsg_len
__attribute__ ((unused
)))
175 __asm__
__volatile__ ("":::"memory");
182 _gfortran_caf_sync_images (int count
__attribute__ ((unused
)),
183 int images
[] __attribute__ ((unused
)),
185 char *errmsg
__attribute__ ((unused
)),
186 int errmsg_len
__attribute__ ((unused
)))
191 for (i
= 0; i
< count
; i
++)
194 fprintf (stderr
, "COARRAY ERROR: Invalid image index %d to SYNC "
195 "IMAGES", images
[i
]);
200 __asm__
__volatile__ ("":::"memory");
207 _gfortran_caf_error_stop_str (const char *string
, int32_t len
)
209 fputs ("ERROR STOP ", stderr
);
211 fputc (*(string
++), stderr
);
212 fputs ("\n", stderr
);
219 _gfortran_caf_error_stop (int32_t error
)
221 fprintf (stderr
, "ERROR STOP %d\n", error
);
227 _gfortran_caf_co_broadcast (gfc_descriptor_t
*a
__attribute__ ((unused
)),
228 int source_image
__attribute__ ((unused
)),
229 int *stat
, char *errmsg
__attribute__ ((unused
)),
230 int errmsg_len
__attribute__ ((unused
)))
237 _gfortran_caf_co_sum (gfc_descriptor_t
*a
__attribute__ ((unused
)),
238 int result_image
__attribute__ ((unused
)),
239 int *stat
, char *errmsg
__attribute__ ((unused
)),
240 int errmsg_len
__attribute__ ((unused
)))
247 _gfortran_caf_co_min (gfc_descriptor_t
*a
__attribute__ ((unused
)),
248 int result_image
__attribute__ ((unused
)),
249 int *stat
, char *errmsg
__attribute__ ((unused
)),
250 int a_len
__attribute__ ((unused
)),
251 int errmsg_len
__attribute__ ((unused
)))
258 _gfortran_caf_co_max (gfc_descriptor_t
*a
__attribute__ ((unused
)),
259 int result_image
__attribute__ ((unused
)),
260 int *stat
, char *errmsg
__attribute__ ((unused
)),
261 int a_len
__attribute__ ((unused
)),
262 int errmsg_len
__attribute__ ((unused
)))
270 _gfortran_caf_co_reduce (gfc_descriptor_t
*a
__attribute__ ((unused
)),
271 void * (*opr
) (void *, void *)
272 __attribute__ ((unused
)),
273 int opr_flags
__attribute__ ((unused
)),
274 int result_image
__attribute__ ((unused
)),
275 int *stat
, char *errmsg
__attribute__ ((unused
)),
276 int a_len
__attribute__ ((unused
)),
277 int errmsg_len
__attribute__ ((unused
)))
285 assign_char4_from_char1 (size_t dst_size
, size_t src_size
, uint32_t *dst
,
289 n
= dst_size
/4 > src_size
? src_size
: dst_size
/4;
290 for (i
= 0; i
< n
; ++i
)
291 dst
[i
] = (int32_t) src
[i
];
292 for (; i
< dst_size
/4; ++i
)
293 dst
[i
] = (int32_t) ' ';
298 assign_char1_from_char4 (size_t dst_size
, size_t src_size
, unsigned char *dst
,
302 n
= dst_size
> src_size
/4 ? src_size
/4 : dst_size
;
303 for (i
= 0; i
< n
; ++i
)
304 dst
[i
] = src
[i
] > UINT8_MAX
? (unsigned char) '?' : (unsigned char) src
[i
];
306 memset(&dst
[n
], ' ', dst_size
- n
);
311 convert_type (void *dst
, int dst_type
, int dst_kind
, void *src
, int src_type
,
314 #ifdef HAVE_GFC_INTEGER_16
315 typedef __int128 int128t
;
317 typedef int64_t int128t
;
320 #if defined(GFC_REAL_16_IS_LONG_DOUBLE)
321 typedef long double real128t
;
322 typedef _Complex
long double complex128t
;
323 #elif defined(HAVE_GFC_REAL_16)
324 typedef _Complex
float __attribute__((mode(TC
))) __complex128
;
325 typedef __float128 real128t
;
326 typedef __complex128 complex128t
;
327 #elif defined(HAVE_GFC_REAL_10)
328 typedef long double real128t
;
329 typedef long double complex128t
;
331 typedef double real128t
;
332 typedef _Complex
double complex128t
;
336 real128t real_val
= 0;
337 complex128t cmpx_val
= 0;
343 int_val
= *(int8_t*) src
;
344 else if (src_kind
== 2)
345 int_val
= *(int16_t*) src
;
346 else if (src_kind
== 4)
347 int_val
= *(int32_t*) src
;
348 else if (src_kind
== 8)
349 int_val
= *(int64_t*) src
;
350 #ifdef HAVE_GFC_INTEGER_16
351 else if (src_kind
== 16)
352 int_val
= *(int128t
*) src
;
359 real_val
= *(float*) src
;
360 else if (src_kind
== 8)
361 real_val
= *(double*) src
;
362 #ifdef HAVE_GFC_REAL_10
363 else if (src_kind
== 10)
364 real_val
= *(long double*) src
;
366 #ifdef HAVE_GFC_REAL_16
367 else if (src_kind
== 16)
368 real_val
= *(real128t
*) src
;
375 cmpx_val
= *(_Complex
float*) src
;
376 else if (src_kind
== 8)
377 cmpx_val
= *(_Complex
double*) src
;
378 #ifdef HAVE_GFC_REAL_10
379 else if (src_kind
== 10)
380 cmpx_val
= *(_Complex
long double*) src
;
382 #ifdef HAVE_GFC_REAL_16
383 else if (src_kind
== 16)
384 cmpx_val
= *(complex128t
*) src
;
396 if (src_type
== BT_INTEGER
)
399 *(int8_t*) dst
= (int8_t) int_val
;
400 else if (dst_kind
== 2)
401 *(int16_t*) dst
= (int16_t) int_val
;
402 else if (dst_kind
== 4)
403 *(int32_t*) dst
= (int32_t) int_val
;
404 else if (dst_kind
== 8)
405 *(int64_t*) dst
= (int64_t) int_val
;
406 #ifdef HAVE_GFC_INTEGER_16
407 else if (dst_kind
== 16)
408 *(int128t
*) dst
= (int128t
) int_val
;
413 else if (src_type
== BT_REAL
)
416 *(int8_t*) dst
= (int8_t) real_val
;
417 else if (dst_kind
== 2)
418 *(int16_t*) dst
= (int16_t) real_val
;
419 else if (dst_kind
== 4)
420 *(int32_t*) dst
= (int32_t) real_val
;
421 else if (dst_kind
== 8)
422 *(int64_t*) dst
= (int64_t) real_val
;
423 #ifdef HAVE_GFC_INTEGER_16
424 else if (dst_kind
== 16)
425 *(int128t
*) dst
= (int128t
) real_val
;
430 else if (src_type
== BT_COMPLEX
)
433 *(int8_t*) dst
= (int8_t) cmpx_val
;
434 else if (dst_kind
== 2)
435 *(int16_t*) dst
= (int16_t) cmpx_val
;
436 else if (dst_kind
== 4)
437 *(int32_t*) dst
= (int32_t) cmpx_val
;
438 else if (dst_kind
== 8)
439 *(int64_t*) dst
= (int64_t) cmpx_val
;
440 #ifdef HAVE_GFC_INTEGER_16
441 else if (dst_kind
== 16)
442 *(int128t
*) dst
= (int128t
) cmpx_val
;
451 if (src_type
== BT_INTEGER
)
454 *(float*) dst
= (float) int_val
;
455 else if (dst_kind
== 8)
456 *(double*) dst
= (double) int_val
;
457 #ifdef HAVE_GFC_REAL_10
458 else if (dst_kind
== 10)
459 *(long double*) dst
= (long double) int_val
;
461 #ifdef HAVE_GFC_REAL_16
462 else if (dst_kind
== 16)
463 *(real128t
*) dst
= (real128t
) int_val
;
468 else if (src_type
== BT_REAL
)
471 *(float*) dst
= (float) real_val
;
472 else if (dst_kind
== 8)
473 *(double*) dst
= (double) real_val
;
474 #ifdef HAVE_GFC_REAL_10
475 else if (dst_kind
== 10)
476 *(long double*) dst
= (long double) real_val
;
478 #ifdef HAVE_GFC_REAL_16
479 else if (dst_kind
== 16)
480 *(real128t
*) dst
= (real128t
) real_val
;
485 else if (src_type
== BT_COMPLEX
)
488 *(float*) dst
= (float) cmpx_val
;
489 else if (dst_kind
== 8)
490 *(double*) dst
= (double) cmpx_val
;
491 #ifdef HAVE_GFC_REAL_10
492 else if (dst_kind
== 10)
493 *(long double*) dst
= (long double) cmpx_val
;
495 #ifdef HAVE_GFC_REAL_16
496 else if (dst_kind
== 16)
497 *(real128t
*) dst
= (real128t
) cmpx_val
;
504 if (src_type
== BT_INTEGER
)
507 *(_Complex
float*) dst
= (_Complex
float) int_val
;
508 else if (dst_kind
== 8)
509 *(_Complex
double*) dst
= (_Complex
double) int_val
;
510 #ifdef HAVE_GFC_REAL_10
511 else if (dst_kind
== 10)
512 *(_Complex
long double*) dst
= (_Complex
long double) int_val
;
514 #ifdef HAVE_GFC_REAL_16
515 else if (dst_kind
== 16)
516 *(complex128t
*) dst
= (complex128t
) int_val
;
521 else if (src_type
== BT_REAL
)
524 *(_Complex
float*) dst
= (_Complex
float) real_val
;
525 else if (dst_kind
== 8)
526 *(_Complex
double*) dst
= (_Complex
double) real_val
;
527 #ifdef HAVE_GFC_REAL_10
528 else if (dst_kind
== 10)
529 *(_Complex
long double*) dst
= (_Complex
long double) real_val
;
531 #ifdef HAVE_GFC_REAL_16
532 else if (dst_kind
== 16)
533 *(complex128t
*) dst
= (complex128t
) real_val
;
538 else if (src_type
== BT_COMPLEX
)
541 *(_Complex
float*) dst
= (_Complex
float) cmpx_val
;
542 else if (dst_kind
== 8)
543 *(_Complex
double*) dst
= (_Complex
double) cmpx_val
;
544 #ifdef HAVE_GFC_REAL_10
545 else if (dst_kind
== 10)
546 *(_Complex
long double*) dst
= (_Complex
long double) cmpx_val
;
548 #ifdef HAVE_GFC_REAL_16
549 else if (dst_kind
== 16)
550 *(complex128t
*) dst
= (complex128t
) cmpx_val
;
563 fprintf (stderr
, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind "
564 "%d to type %d kind %d\n", src_type
, src_kind
, dst_type
, dst_kind
);
570 _gfortran_caf_get (caf_token_t token
, size_t offset
,
571 int image_index
__attribute__ ((unused
)),
572 gfc_descriptor_t
*src
,
573 caf_vector_t
*src_vector
__attribute__ ((unused
)),
574 gfc_descriptor_t
*dest
, int src_kind
, int dst_kind
,
575 bool may_require_tmp
)
577 /* FIXME: Handle vector subscripts. */
580 int rank
= GFC_DESCRIPTOR_RANK (dest
);
581 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
582 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
586 void *sr
= (void *) ((char *) TOKEN (token
) + offset
);
587 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
588 && dst_kind
== src_kind
)
590 memmove (GFC_DESCRIPTOR_DATA (dest
), sr
,
591 dst_size
> src_size
? src_size
: dst_size
);
592 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
595 memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest
) + src_size
,
596 ' ', dst_size
- src_size
);
597 else /* dst_kind == 4. */
598 for (i
= src_size
/4; i
< dst_size
/4; i
++)
599 ((int32_t*) GFC_DESCRIPTOR_DATA (dest
))[i
] = (int32_t) ' ';
602 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
603 assign_char1_from_char4 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
605 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
606 assign_char4_from_char1 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
609 convert_type (GFC_DESCRIPTOR_DATA (dest
), GFC_DESCRIPTOR_TYPE (dest
),
610 dst_kind
, sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
615 for (j
= 0; j
< rank
; j
++)
617 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
628 ptrdiff_t array_offset_sr
, array_offset_dst
;
629 void *tmp
= malloc (size
*src_size
);
631 array_offset_dst
= 0;
632 for (i
= 0; i
< size
; i
++)
634 ptrdiff_t array_offset_sr
= 0;
635 ptrdiff_t stride
= 1;
636 ptrdiff_t extent
= 1;
637 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
639 array_offset_sr
+= ((i
/ (extent
*stride
))
640 % (src
->dim
[j
]._ubound
641 - src
->dim
[j
].lower_bound
+ 1))
642 * src
->dim
[j
]._stride
;
643 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
644 stride
= src
->dim
[j
]._stride
;
646 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
647 void *sr
= (void *)((char *) TOKEN (token
) + offset
648 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
649 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
650 array_offset_dst
+= src_size
;
654 for (i
= 0; i
< size
; i
++)
656 ptrdiff_t array_offset_dst
= 0;
657 ptrdiff_t stride
= 1;
658 ptrdiff_t extent
= 1;
659 for (j
= 0; j
< rank
-1; j
++)
661 array_offset_dst
+= ((i
/ (extent
*stride
))
662 % (dest
->dim
[j
]._ubound
663 - dest
->dim
[j
].lower_bound
+ 1))
664 * dest
->dim
[j
]._stride
;
665 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
666 stride
= dest
->dim
[j
]._stride
;
668 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
669 void *dst
= dest
->base_addr
670 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
671 void *sr
= tmp
+ array_offset_sr
;
673 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
674 && dst_kind
== src_kind
)
676 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
677 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
678 && dst_size
> src_size
)
681 memset ((void*)(char*) dst
+ src_size
, ' ',
683 else /* dst_kind == 4. */
684 for (k
= src_size
/4; k
< dst_size
/4; k
++)
685 ((int32_t*) dst
)[k
] = (int32_t) ' ';
688 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
689 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
690 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
691 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
693 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
694 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
695 array_offset_sr
+= src_size
;
702 for (i
= 0; i
< size
; i
++)
704 ptrdiff_t array_offset_dst
= 0;
705 ptrdiff_t stride
= 1;
706 ptrdiff_t extent
= 1;
707 for (j
= 0; j
< rank
-1; j
++)
709 array_offset_dst
+= ((i
/ (extent
*stride
))
710 % (dest
->dim
[j
]._ubound
711 - dest
->dim
[j
].lower_bound
+ 1))
712 * dest
->dim
[j
]._stride
;
713 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
714 stride
= dest
->dim
[j
]._stride
;
716 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
717 void *dst
= dest
->base_addr
+ array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
719 ptrdiff_t array_offset_sr
= 0;
722 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
724 array_offset_sr
+= ((i
/ (extent
*stride
))
725 % (src
->dim
[j
]._ubound
726 - src
->dim
[j
].lower_bound
+ 1))
727 * src
->dim
[j
]._stride
;
728 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
729 stride
= src
->dim
[j
]._stride
;
731 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
732 void *sr
= (void *)((char *) TOKEN (token
) + offset
733 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
735 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
736 && dst_kind
== src_kind
)
738 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
739 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
742 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
743 else /* dst_kind == 4. */
744 for (k
= src_size
/4; k
< dst_size
/4; k
++)
745 ((int32_t*) dst
)[k
] = (int32_t) ' ';
748 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
749 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
750 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
751 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
753 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
754 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
760 _gfortran_caf_send (caf_token_t token
, size_t offset
,
761 int image_index
__attribute__ ((unused
)),
762 gfc_descriptor_t
*dest
,
763 caf_vector_t
*dst_vector
__attribute__ ((unused
)),
764 gfc_descriptor_t
*src
, int dst_kind
, int src_kind
,
765 bool may_require_tmp
)
767 /* FIXME: Handle vector subscripts. */
770 int rank
= GFC_DESCRIPTOR_RANK (dest
);
771 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
772 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
776 void *dst
= (void *) ((char *) TOKEN (token
) + offset
);
777 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
778 && dst_kind
== src_kind
)
780 memmove (dst
, GFC_DESCRIPTOR_DATA (src
),
781 dst_size
> src_size
? src_size
: dst_size
);
782 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
785 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
786 else /* dst_kind == 4. */
787 for (i
= src_size
/4; i
< dst_size
/4; i
++)
788 ((int32_t*) dst
)[i
] = (int32_t) ' ';
791 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
792 assign_char1_from_char4 (dst_size
, src_size
, dst
,
793 GFC_DESCRIPTOR_DATA (src
));
794 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
795 assign_char4_from_char1 (dst_size
, src_size
, dst
,
796 GFC_DESCRIPTOR_DATA (src
));
798 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
799 GFC_DESCRIPTOR_DATA (src
), GFC_DESCRIPTOR_TYPE (src
),
805 for (j
= 0; j
< rank
; j
++)
807 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
818 ptrdiff_t array_offset_sr
, array_offset_dst
;
821 if (GFC_DESCRIPTOR_RANK (src
) == 0)
823 tmp
= malloc (src_size
);
824 memcpy (tmp
, GFC_DESCRIPTOR_DATA (src
), src_size
);
828 tmp
= malloc (size
*src_size
);
829 array_offset_dst
= 0;
830 for (i
= 0; i
< size
; i
++)
832 ptrdiff_t array_offset_sr
= 0;
833 ptrdiff_t stride
= 1;
834 ptrdiff_t extent
= 1;
835 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
837 array_offset_sr
+= ((i
/ (extent
*stride
))
838 % (src
->dim
[j
]._ubound
839 - src
->dim
[j
].lower_bound
+ 1))
840 * src
->dim
[j
]._stride
;
841 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
842 stride
= src
->dim
[j
]._stride
;
844 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
845 void *sr
= (void *) ((char *) src
->base_addr
846 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
847 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
848 array_offset_dst
+= src_size
;
853 for (i
= 0; i
< size
; i
++)
855 ptrdiff_t array_offset_dst
= 0;
856 ptrdiff_t stride
= 1;
857 ptrdiff_t extent
= 1;
858 for (j
= 0; j
< rank
-1; j
++)
860 array_offset_dst
+= ((i
/ (extent
*stride
))
861 % (dest
->dim
[j
]._ubound
862 - dest
->dim
[j
].lower_bound
+ 1))
863 * dest
->dim
[j
]._stride
;
864 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
865 stride
= dest
->dim
[j
]._stride
;
867 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
868 void *dst
= (void *)((char *) TOKEN (token
) + offset
869 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
870 void *sr
= tmp
+ array_offset_sr
;
871 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
872 && dst_kind
== src_kind
)
875 dst_size
> src_size
? src_size
: dst_size
);
876 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
877 && dst_size
> src_size
)
880 memset ((void*)(char*) dst
+ src_size
, ' ',
882 else /* dst_kind == 4. */
883 for (k
= src_size
/4; k
< dst_size
/4; k
++)
884 ((int32_t*) dst
)[k
] = (int32_t) ' ';
887 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
888 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
889 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
890 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
892 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
893 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
894 if (GFC_DESCRIPTOR_RANK (src
))
895 array_offset_sr
+= src_size
;
901 for (i
= 0; i
< size
; i
++)
903 ptrdiff_t array_offset_dst
= 0;
904 ptrdiff_t stride
= 1;
905 ptrdiff_t extent
= 1;
906 for (j
= 0; j
< rank
-1; j
++)
908 array_offset_dst
+= ((i
/ (extent
*stride
))
909 % (dest
->dim
[j
]._ubound
910 - dest
->dim
[j
].lower_bound
+ 1))
911 * dest
->dim
[j
]._stride
;
912 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
913 stride
= dest
->dim
[j
]._stride
;
915 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
916 void *dst
= (void *)((char *) TOKEN (token
) + offset
917 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
919 if (GFC_DESCRIPTOR_RANK (src
) != 0)
921 ptrdiff_t array_offset_sr
= 0;
924 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
926 array_offset_sr
+= ((i
/ (extent
*stride
))
927 % (src
->dim
[j
]._ubound
928 - src
->dim
[j
].lower_bound
+ 1))
929 * src
->dim
[j
]._stride
;
930 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
931 stride
= src
->dim
[j
]._stride
;
933 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
934 sr
= (void *)((char *) src
->base_addr
935 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
940 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
941 && dst_kind
== src_kind
)
944 dst_size
> src_size
? src_size
: dst_size
);
945 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
948 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
949 else /* dst_kind == 4. */
950 for (k
= src_size
/4; k
< dst_size
/4; k
++)
951 ((int32_t*) dst
)[k
] = (int32_t) ' ';
954 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
955 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
956 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
957 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
959 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
960 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
966 _gfortran_caf_sendget (caf_token_t dst_token
, size_t dst_offset
,
967 int dst_image_index
, gfc_descriptor_t
*dest
,
968 caf_vector_t
*dst_vector
, caf_token_t src_token
,
970 int src_image_index
__attribute__ ((unused
)),
971 gfc_descriptor_t
*src
,
972 caf_vector_t
*src_vector
__attribute__ ((unused
)),
973 int dst_kind
, int src_kind
, bool may_require_tmp
)
975 /* FIXME: Handle vector subscript of 'src_vector'. */
976 /* For a single image, src->base_addr should be the same as src_token + offset
977 but to play save, we do it properly. */
978 void *src_base
= GFC_DESCRIPTOR_DATA (src
);
979 GFC_DESCRIPTOR_DATA (src
) = (void *) ((char *) TOKEN (src_token
) + src_offset
);
980 _gfortran_caf_send (dst_token
, dst_offset
, dst_image_index
, dest
, dst_vector
,
981 src
, dst_kind
, src_kind
, may_require_tmp
);
982 GFC_DESCRIPTOR_DATA (src
) = src_base
;
987 _gfortran_caf_atomic_define (caf_token_t token
, size_t offset
,
988 int image_index
__attribute__ ((unused
)),
989 void *value
, int *stat
,
990 int type
__attribute__ ((unused
)), int kind
)
994 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
996 __atomic_store (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
1003 _gfortran_caf_atomic_ref (caf_token_t token
, size_t offset
,
1004 int image_index
__attribute__ ((unused
)),
1005 void *value
, int *stat
,
1006 int type
__attribute__ ((unused
)), int kind
)
1010 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1012 __atomic_load (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
1020 _gfortran_caf_atomic_cas (caf_token_t token
, size_t offset
,
1021 int image_index
__attribute__ ((unused
)),
1022 void *old
, void *compare
, void *new_val
, int *stat
,
1023 int type
__attribute__ ((unused
)), int kind
)
1027 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1029 *(uint32_t *) old
= *(uint32_t *) compare
;
1030 (void) __atomic_compare_exchange_n (atom
, (uint32_t *) old
,
1031 *(uint32_t *) new_val
, false,
1032 __ATOMIC_RELAXED
, __ATOMIC_RELAXED
);
1039 _gfortran_caf_atomic_op (int op
, caf_token_t token
, size_t offset
,
1040 int image_index
__attribute__ ((unused
)),
1041 void *value
, void *old
, int *stat
,
1042 int type
__attribute__ ((unused
)), int kind
)
1047 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1051 case GFC_CAF_ATOMIC_ADD
:
1052 res
= __atomic_fetch_add (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1054 case GFC_CAF_ATOMIC_AND
:
1055 res
= __atomic_fetch_and (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1057 case GFC_CAF_ATOMIC_OR
:
1058 res
= __atomic_fetch_or (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1060 case GFC_CAF_ATOMIC_XOR
:
1061 res
= __atomic_fetch_xor (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1064 __builtin_unreachable();
1068 *(uint32_t *) old
= res
;
1076 _gfortran_caf_lock (caf_token_t token
, size_t index
,
1077 int image_index
__attribute__ ((unused
)),
1078 int *aquired_lock
, int *stat
, char *errmsg
, int errmsg_len
)
1080 const char *msg
= "Already locked";
1081 bool *lock
= &((bool *) TOKEN (token
))[index
];
1087 *aquired_lock
= (int) true;
1095 *aquired_lock
= (int) false;
1107 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
1108 : (int) sizeof (msg
);
1109 memcpy (errmsg
, msg
, len
);
1110 if (errmsg_len
> len
)
1111 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
1115 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));
1120 _gfortran_caf_unlock (caf_token_t token
, size_t index
,
1121 int image_index
__attribute__ ((unused
)),
1122 int *stat
, char *errmsg
, int errmsg_len
)
1124 const char *msg
= "Variable is not locked";
1125 bool *lock
= &((bool *) TOKEN (token
))[index
];
1140 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
1141 : (int) sizeof (msg
);
1142 memcpy (errmsg
, msg
, len
);
1143 if (errmsg_len
> len
)
1144 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
1148 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));