1 /* Single-image implementation of GNU Fortran Coarray Library
2 Copyright (C) 2011-2016 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
|| type
== CAF_REGTYPE_EVENT_STATIC
105 || type
== CAF_REGTYPE_EVENT_ALLOC
)
106 local
= calloc (size
, sizeof (bool));
108 local
= malloc (size
);
109 *token
= malloc (sizeof (single_token_t
));
111 if (unlikely (local
== NULL
|| token
== NULL
))
113 const char msg
[] = "Failed to allocate coarray";
119 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
120 : (int) sizeof (msg
);
121 memcpy (errmsg
, msg
, len
);
122 if (errmsg_len
> len
)
123 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
128 caf_runtime_error (msg
);
136 if (type
== CAF_REGTYPE_COARRAY_STATIC
|| type
== CAF_REGTYPE_LOCK_STATIC
137 || type
== CAF_REGTYPE_CRITICAL
|| type
== CAF_REGTYPE_EVENT_STATIC
138 || type
== CAF_REGTYPE_EVENT_ALLOC
)
140 caf_static_t
*tmp
= malloc (sizeof (caf_static_t
));
141 tmp
->prev
= caf_static_list
;
143 caf_static_list
= tmp
;
150 _gfortran_caf_deregister (caf_token_t
*token
, int *stat
,
151 char *errmsg
__attribute__ ((unused
)),
152 int errmsg_len
__attribute__ ((unused
)))
154 free (TOKEN(*token
));
162 _gfortran_caf_sync_all (int *stat
,
163 char *errmsg
__attribute__ ((unused
)),
164 int errmsg_len
__attribute__ ((unused
)))
166 __asm__
__volatile__ ("":::"memory");
173 _gfortran_caf_sync_memory (int *stat
,
174 char *errmsg
__attribute__ ((unused
)),
175 int errmsg_len
__attribute__ ((unused
)))
177 __asm__
__volatile__ ("":::"memory");
184 _gfortran_caf_sync_images (int count
__attribute__ ((unused
)),
185 int images
[] __attribute__ ((unused
)),
187 char *errmsg
__attribute__ ((unused
)),
188 int errmsg_len
__attribute__ ((unused
)))
193 for (i
= 0; i
< count
; i
++)
196 fprintf (stderr
, "COARRAY ERROR: Invalid image index %d to SYNC "
197 "IMAGES", images
[i
]);
202 __asm__
__volatile__ ("":::"memory");
208 _gfortran_caf_stop_numeric(int32_t stop_code
)
210 fprintf (stderr
, "STOP %d\n", stop_code
);
215 _gfortran_caf_stop_str(const char *string
, int32_t len
)
217 fputs ("STOP ", stderr
);
219 fputc (*(string
++), stderr
);
220 fputs ("\n", stderr
);
226 _gfortran_caf_error_stop_str (const char *string
, int32_t len
)
228 fputs ("ERROR STOP ", stderr
);
230 fputc (*(string
++), stderr
);
231 fputs ("\n", stderr
);
238 _gfortran_caf_error_stop (int32_t error
)
240 fprintf (stderr
, "ERROR STOP %d\n", error
);
246 _gfortran_caf_co_broadcast (gfc_descriptor_t
*a
__attribute__ ((unused
)),
247 int source_image
__attribute__ ((unused
)),
248 int *stat
, char *errmsg
__attribute__ ((unused
)),
249 int errmsg_len
__attribute__ ((unused
)))
256 _gfortran_caf_co_sum (gfc_descriptor_t
*a
__attribute__ ((unused
)),
257 int result_image
__attribute__ ((unused
)),
258 int *stat
, char *errmsg
__attribute__ ((unused
)),
259 int errmsg_len
__attribute__ ((unused
)))
266 _gfortran_caf_co_min (gfc_descriptor_t
*a
__attribute__ ((unused
)),
267 int result_image
__attribute__ ((unused
)),
268 int *stat
, char *errmsg
__attribute__ ((unused
)),
269 int a_len
__attribute__ ((unused
)),
270 int errmsg_len
__attribute__ ((unused
)))
277 _gfortran_caf_co_max (gfc_descriptor_t
*a
__attribute__ ((unused
)),
278 int result_image
__attribute__ ((unused
)),
279 int *stat
, char *errmsg
__attribute__ ((unused
)),
280 int a_len
__attribute__ ((unused
)),
281 int errmsg_len
__attribute__ ((unused
)))
289 _gfortran_caf_co_reduce (gfc_descriptor_t
*a
__attribute__ ((unused
)),
290 void * (*opr
) (void *, void *)
291 __attribute__ ((unused
)),
292 int opr_flags
__attribute__ ((unused
)),
293 int result_image
__attribute__ ((unused
)),
294 int *stat
, char *errmsg
__attribute__ ((unused
)),
295 int a_len
__attribute__ ((unused
)),
296 int errmsg_len
__attribute__ ((unused
)))
304 assign_char4_from_char1 (size_t dst_size
, size_t src_size
, uint32_t *dst
,
308 n
= dst_size
/4 > src_size
? src_size
: dst_size
/4;
309 for (i
= 0; i
< n
; ++i
)
310 dst
[i
] = (int32_t) src
[i
];
311 for (; i
< dst_size
/4; ++i
)
312 dst
[i
] = (int32_t) ' ';
317 assign_char1_from_char4 (size_t dst_size
, size_t src_size
, unsigned char *dst
,
321 n
= dst_size
> src_size
/4 ? src_size
/4 : dst_size
;
322 for (i
= 0; i
< n
; ++i
)
323 dst
[i
] = src
[i
] > UINT8_MAX
? (unsigned char) '?' : (unsigned char) src
[i
];
325 memset(&dst
[n
], ' ', dst_size
- n
);
330 convert_type (void *dst
, int dst_type
, int dst_kind
, void *src
, int src_type
,
331 int src_kind
, int *stat
)
333 #ifdef HAVE_GFC_INTEGER_16
334 typedef __int128 int128t
;
336 typedef int64_t int128t
;
339 #if defined(GFC_REAL_16_IS_LONG_DOUBLE)
340 typedef long double real128t
;
341 typedef _Complex
long double complex128t
;
342 #elif defined(HAVE_GFC_REAL_16)
343 typedef _Complex
float __attribute__((mode(TC
))) __complex128
;
344 typedef __float128 real128t
;
345 typedef __complex128 complex128t
;
346 #elif defined(HAVE_GFC_REAL_10)
347 typedef long double real128t
;
348 typedef long double complex128t
;
350 typedef double real128t
;
351 typedef _Complex
double complex128t
;
355 real128t real_val
= 0;
356 complex128t cmpx_val
= 0;
362 int_val
= *(int8_t*) src
;
363 else if (src_kind
== 2)
364 int_val
= *(int16_t*) src
;
365 else if (src_kind
== 4)
366 int_val
= *(int32_t*) src
;
367 else if (src_kind
== 8)
368 int_val
= *(int64_t*) src
;
369 #ifdef HAVE_GFC_INTEGER_16
370 else if (src_kind
== 16)
371 int_val
= *(int128t
*) src
;
378 real_val
= *(float*) src
;
379 else if (src_kind
== 8)
380 real_val
= *(double*) src
;
381 #ifdef HAVE_GFC_REAL_10
382 else if (src_kind
== 10)
383 real_val
= *(long double*) src
;
385 #ifdef HAVE_GFC_REAL_16
386 else if (src_kind
== 16)
387 real_val
= *(real128t
*) src
;
394 cmpx_val
= *(_Complex
float*) src
;
395 else if (src_kind
== 8)
396 cmpx_val
= *(_Complex
double*) src
;
397 #ifdef HAVE_GFC_REAL_10
398 else if (src_kind
== 10)
399 cmpx_val
= *(_Complex
long double*) src
;
401 #ifdef HAVE_GFC_REAL_16
402 else if (src_kind
== 16)
403 cmpx_val
= *(complex128t
*) src
;
415 if (src_type
== BT_INTEGER
)
418 *(int8_t*) dst
= (int8_t) int_val
;
419 else if (dst_kind
== 2)
420 *(int16_t*) dst
= (int16_t) int_val
;
421 else if (dst_kind
== 4)
422 *(int32_t*) dst
= (int32_t) int_val
;
423 else if (dst_kind
== 8)
424 *(int64_t*) dst
= (int64_t) int_val
;
425 #ifdef HAVE_GFC_INTEGER_16
426 else if (dst_kind
== 16)
427 *(int128t
*) dst
= (int128t
) int_val
;
432 else if (src_type
== BT_REAL
)
435 *(int8_t*) dst
= (int8_t) real_val
;
436 else if (dst_kind
== 2)
437 *(int16_t*) dst
= (int16_t) real_val
;
438 else if (dst_kind
== 4)
439 *(int32_t*) dst
= (int32_t) real_val
;
440 else if (dst_kind
== 8)
441 *(int64_t*) dst
= (int64_t) real_val
;
442 #ifdef HAVE_GFC_INTEGER_16
443 else if (dst_kind
== 16)
444 *(int128t
*) dst
= (int128t
) real_val
;
449 else if (src_type
== BT_COMPLEX
)
452 *(int8_t*) dst
= (int8_t) cmpx_val
;
453 else if (dst_kind
== 2)
454 *(int16_t*) dst
= (int16_t) cmpx_val
;
455 else if (dst_kind
== 4)
456 *(int32_t*) dst
= (int32_t) cmpx_val
;
457 else if (dst_kind
== 8)
458 *(int64_t*) dst
= (int64_t) cmpx_val
;
459 #ifdef HAVE_GFC_INTEGER_16
460 else if (dst_kind
== 16)
461 *(int128t
*) dst
= (int128t
) cmpx_val
;
470 if (src_type
== BT_INTEGER
)
473 *(float*) dst
= (float) int_val
;
474 else if (dst_kind
== 8)
475 *(double*) dst
= (double) int_val
;
476 #ifdef HAVE_GFC_REAL_10
477 else if (dst_kind
== 10)
478 *(long double*) dst
= (long double) int_val
;
480 #ifdef HAVE_GFC_REAL_16
481 else if (dst_kind
== 16)
482 *(real128t
*) dst
= (real128t
) int_val
;
487 else if (src_type
== BT_REAL
)
490 *(float*) dst
= (float) real_val
;
491 else if (dst_kind
== 8)
492 *(double*) dst
= (double) real_val
;
493 #ifdef HAVE_GFC_REAL_10
494 else if (dst_kind
== 10)
495 *(long double*) dst
= (long double) real_val
;
497 #ifdef HAVE_GFC_REAL_16
498 else if (dst_kind
== 16)
499 *(real128t
*) dst
= (real128t
) real_val
;
504 else if (src_type
== BT_COMPLEX
)
507 *(float*) dst
= (float) cmpx_val
;
508 else if (dst_kind
== 8)
509 *(double*) dst
= (double) cmpx_val
;
510 #ifdef HAVE_GFC_REAL_10
511 else if (dst_kind
== 10)
512 *(long double*) dst
= (long double) cmpx_val
;
514 #ifdef HAVE_GFC_REAL_16
515 else if (dst_kind
== 16)
516 *(real128t
*) dst
= (real128t
) cmpx_val
;
523 if (src_type
== BT_INTEGER
)
526 *(_Complex
float*) dst
= (_Complex
float) int_val
;
527 else if (dst_kind
== 8)
528 *(_Complex
double*) dst
= (_Complex
double) int_val
;
529 #ifdef HAVE_GFC_REAL_10
530 else if (dst_kind
== 10)
531 *(_Complex
long double*) dst
= (_Complex
long double) int_val
;
533 #ifdef HAVE_GFC_REAL_16
534 else if (dst_kind
== 16)
535 *(complex128t
*) dst
= (complex128t
) int_val
;
540 else if (src_type
== BT_REAL
)
543 *(_Complex
float*) dst
= (_Complex
float) real_val
;
544 else if (dst_kind
== 8)
545 *(_Complex
double*) dst
= (_Complex
double) real_val
;
546 #ifdef HAVE_GFC_REAL_10
547 else if (dst_kind
== 10)
548 *(_Complex
long double*) dst
= (_Complex
long double) real_val
;
550 #ifdef HAVE_GFC_REAL_16
551 else if (dst_kind
== 16)
552 *(complex128t
*) dst
= (complex128t
) real_val
;
557 else if (src_type
== BT_COMPLEX
)
560 *(_Complex
float*) dst
= (_Complex
float) cmpx_val
;
561 else if (dst_kind
== 8)
562 *(_Complex
double*) dst
= (_Complex
double) cmpx_val
;
563 #ifdef HAVE_GFC_REAL_10
564 else if (dst_kind
== 10)
565 *(_Complex
long double*) dst
= (_Complex
long double) cmpx_val
;
567 #ifdef HAVE_GFC_REAL_16
568 else if (dst_kind
== 16)
569 *(complex128t
*) dst
= (complex128t
) cmpx_val
;
582 fprintf (stderr
, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind "
583 "%d to type %d kind %d\n", src_type
, src_kind
, dst_type
, dst_kind
);
592 _gfortran_caf_get (caf_token_t token
, size_t offset
,
593 int image_index
__attribute__ ((unused
)),
594 gfc_descriptor_t
*src
,
595 caf_vector_t
*src_vector
__attribute__ ((unused
)),
596 gfc_descriptor_t
*dest
, int src_kind
, int dst_kind
,
597 bool may_require_tmp
, int *stat
)
599 /* FIXME: Handle vector subscripts. */
602 int rank
= GFC_DESCRIPTOR_RANK (dest
);
603 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
604 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
611 void *sr
= (void *) ((char *) TOKEN (token
) + offset
);
612 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
613 && dst_kind
== src_kind
)
615 memmove (GFC_DESCRIPTOR_DATA (dest
), sr
,
616 dst_size
> src_size
? src_size
: dst_size
);
617 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
620 memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest
) + src_size
,
621 ' ', dst_size
- src_size
);
622 else /* dst_kind == 4. */
623 for (i
= src_size
/4; i
< dst_size
/4; i
++)
624 ((int32_t*) GFC_DESCRIPTOR_DATA (dest
))[i
] = (int32_t) ' ';
627 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
628 assign_char1_from_char4 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
630 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
631 assign_char4_from_char1 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
634 convert_type (GFC_DESCRIPTOR_DATA (dest
), GFC_DESCRIPTOR_TYPE (dest
),
635 dst_kind
, sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
640 for (j
= 0; j
< rank
; j
++)
642 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
653 ptrdiff_t array_offset_sr
, array_offset_dst
;
654 void *tmp
= malloc (size
*src_size
);
656 array_offset_dst
= 0;
657 for (i
= 0; i
< size
; i
++)
659 ptrdiff_t array_offset_sr
= 0;
660 ptrdiff_t stride
= 1;
661 ptrdiff_t extent
= 1;
662 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
664 array_offset_sr
+= ((i
/ (extent
*stride
))
665 % (src
->dim
[j
]._ubound
666 - src
->dim
[j
].lower_bound
+ 1))
667 * src
->dim
[j
]._stride
;
668 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
669 stride
= src
->dim
[j
]._stride
;
671 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
672 void *sr
= (void *)((char *) TOKEN (token
) + offset
673 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
674 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
675 array_offset_dst
+= src_size
;
679 for (i
= 0; i
< size
; i
++)
681 ptrdiff_t array_offset_dst
= 0;
682 ptrdiff_t stride
= 1;
683 ptrdiff_t extent
= 1;
684 for (j
= 0; j
< rank
-1; j
++)
686 array_offset_dst
+= ((i
/ (extent
*stride
))
687 % (dest
->dim
[j
]._ubound
688 - dest
->dim
[j
].lower_bound
+ 1))
689 * dest
->dim
[j
]._stride
;
690 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
691 stride
= dest
->dim
[j
]._stride
;
693 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
694 void *dst
= dest
->base_addr
695 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
696 void *sr
= tmp
+ array_offset_sr
;
698 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
699 && dst_kind
== src_kind
)
701 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
702 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
703 && dst_size
> src_size
)
706 memset ((void*)(char*) dst
+ src_size
, ' ',
708 else /* dst_kind == 4. */
709 for (k
= src_size
/4; k
< dst_size
/4; k
++)
710 ((int32_t*) dst
)[k
] = (int32_t) ' ';
713 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
714 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
715 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
716 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
718 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
719 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
720 array_offset_sr
+= src_size
;
727 for (i
= 0; i
< size
; i
++)
729 ptrdiff_t array_offset_dst
= 0;
730 ptrdiff_t stride
= 1;
731 ptrdiff_t extent
= 1;
732 for (j
= 0; j
< rank
-1; j
++)
734 array_offset_dst
+= ((i
/ (extent
*stride
))
735 % (dest
->dim
[j
]._ubound
736 - dest
->dim
[j
].lower_bound
+ 1))
737 * dest
->dim
[j
]._stride
;
738 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
739 stride
= dest
->dim
[j
]._stride
;
741 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
742 void *dst
= dest
->base_addr
+ array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
744 ptrdiff_t array_offset_sr
= 0;
747 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
749 array_offset_sr
+= ((i
/ (extent
*stride
))
750 % (src
->dim
[j
]._ubound
751 - src
->dim
[j
].lower_bound
+ 1))
752 * src
->dim
[j
]._stride
;
753 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
754 stride
= src
->dim
[j
]._stride
;
756 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
757 void *sr
= (void *)((char *) TOKEN (token
) + offset
758 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
760 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
761 && dst_kind
== src_kind
)
763 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
764 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
767 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
768 else /* dst_kind == 4. */
769 for (k
= src_size
/4; k
< dst_size
/4; k
++)
770 ((int32_t*) dst
)[k
] = (int32_t) ' ';
773 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
774 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
775 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
776 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
778 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
779 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
785 _gfortran_caf_send (caf_token_t token
, size_t offset
,
786 int image_index
__attribute__ ((unused
)),
787 gfc_descriptor_t
*dest
,
788 caf_vector_t
*dst_vector
__attribute__ ((unused
)),
789 gfc_descriptor_t
*src
, int dst_kind
, int src_kind
,
790 bool may_require_tmp
, int *stat
)
792 /* FIXME: Handle vector subscripts. */
795 int rank
= GFC_DESCRIPTOR_RANK (dest
);
796 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
797 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
804 void *dst
= (void *) ((char *) TOKEN (token
) + offset
);
805 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
806 && dst_kind
== src_kind
)
808 memmove (dst
, GFC_DESCRIPTOR_DATA (src
),
809 dst_size
> src_size
? src_size
: dst_size
);
810 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
813 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
814 else /* dst_kind == 4. */
815 for (i
= src_size
/4; i
< dst_size
/4; i
++)
816 ((int32_t*) dst
)[i
] = (int32_t) ' ';
819 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
820 assign_char1_from_char4 (dst_size
, src_size
, dst
,
821 GFC_DESCRIPTOR_DATA (src
));
822 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
823 assign_char4_from_char1 (dst_size
, src_size
, dst
,
824 GFC_DESCRIPTOR_DATA (src
));
826 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
827 GFC_DESCRIPTOR_DATA (src
), GFC_DESCRIPTOR_TYPE (src
),
833 for (j
= 0; j
< rank
; j
++)
835 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
846 ptrdiff_t array_offset_sr
, array_offset_dst
;
849 if (GFC_DESCRIPTOR_RANK (src
) == 0)
851 tmp
= malloc (src_size
);
852 memcpy (tmp
, GFC_DESCRIPTOR_DATA (src
), src_size
);
856 tmp
= malloc (size
*src_size
);
857 array_offset_dst
= 0;
858 for (i
= 0; i
< size
; i
++)
860 ptrdiff_t array_offset_sr
= 0;
861 ptrdiff_t stride
= 1;
862 ptrdiff_t extent
= 1;
863 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
865 array_offset_sr
+= ((i
/ (extent
*stride
))
866 % (src
->dim
[j
]._ubound
867 - src
->dim
[j
].lower_bound
+ 1))
868 * src
->dim
[j
]._stride
;
869 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
870 stride
= src
->dim
[j
]._stride
;
872 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
873 void *sr
= (void *) ((char *) src
->base_addr
874 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
875 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
876 array_offset_dst
+= src_size
;
881 for (i
= 0; i
< size
; i
++)
883 ptrdiff_t array_offset_dst
= 0;
884 ptrdiff_t stride
= 1;
885 ptrdiff_t extent
= 1;
886 for (j
= 0; j
< rank
-1; j
++)
888 array_offset_dst
+= ((i
/ (extent
*stride
))
889 % (dest
->dim
[j
]._ubound
890 - dest
->dim
[j
].lower_bound
+ 1))
891 * dest
->dim
[j
]._stride
;
892 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
893 stride
= dest
->dim
[j
]._stride
;
895 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
896 void *dst
= (void *)((char *) TOKEN (token
) + offset
897 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
898 void *sr
= tmp
+ array_offset_sr
;
899 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
900 && dst_kind
== src_kind
)
903 dst_size
> src_size
? src_size
: dst_size
);
904 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
905 && dst_size
> src_size
)
908 memset ((void*)(char*) dst
+ src_size
, ' ',
910 else /* dst_kind == 4. */
911 for (k
= src_size
/4; k
< dst_size
/4; k
++)
912 ((int32_t*) dst
)[k
] = (int32_t) ' ';
915 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
916 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
917 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
918 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
920 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
921 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
922 if (GFC_DESCRIPTOR_RANK (src
))
923 array_offset_sr
+= src_size
;
929 for (i
= 0; i
< size
; i
++)
931 ptrdiff_t array_offset_dst
= 0;
932 ptrdiff_t stride
= 1;
933 ptrdiff_t extent
= 1;
934 for (j
= 0; j
< rank
-1; j
++)
936 array_offset_dst
+= ((i
/ (extent
*stride
))
937 % (dest
->dim
[j
]._ubound
938 - dest
->dim
[j
].lower_bound
+ 1))
939 * dest
->dim
[j
]._stride
;
940 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
941 stride
= dest
->dim
[j
]._stride
;
943 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
944 void *dst
= (void *)((char *) TOKEN (token
) + offset
945 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
947 if (GFC_DESCRIPTOR_RANK (src
) != 0)
949 ptrdiff_t array_offset_sr
= 0;
952 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
954 array_offset_sr
+= ((i
/ (extent
*stride
))
955 % (src
->dim
[j
]._ubound
956 - src
->dim
[j
].lower_bound
+ 1))
957 * src
->dim
[j
]._stride
;
958 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
959 stride
= src
->dim
[j
]._stride
;
961 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
962 sr
= (void *)((char *) src
->base_addr
963 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
968 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
969 && dst_kind
== src_kind
)
972 dst_size
> src_size
? src_size
: dst_size
);
973 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
976 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
977 else /* dst_kind == 4. */
978 for (k
= src_size
/4; k
< dst_size
/4; k
++)
979 ((int32_t*) dst
)[k
] = (int32_t) ' ';
982 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
983 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
984 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
985 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
987 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
988 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
994 _gfortran_caf_sendget (caf_token_t dst_token
, size_t dst_offset
,
995 int dst_image_index
, gfc_descriptor_t
*dest
,
996 caf_vector_t
*dst_vector
, caf_token_t src_token
,
998 int src_image_index
__attribute__ ((unused
)),
999 gfc_descriptor_t
*src
,
1000 caf_vector_t
*src_vector
__attribute__ ((unused
)),
1001 int dst_kind
, int src_kind
, bool may_require_tmp
)
1003 /* FIXME: Handle vector subscript of 'src_vector'. */
1004 /* For a single image, src->base_addr should be the same as src_token + offset
1005 but to play save, we do it properly. */
1006 void *src_base
= GFC_DESCRIPTOR_DATA (src
);
1007 GFC_DESCRIPTOR_DATA (src
) = (void *) ((char *) TOKEN (src_token
) + src_offset
);
1008 _gfortran_caf_send (dst_token
, dst_offset
, dst_image_index
, dest
, dst_vector
,
1009 src
, dst_kind
, src_kind
, may_require_tmp
, NULL
);
1010 GFC_DESCRIPTOR_DATA (src
) = src_base
;
1015 _gfortran_caf_atomic_define (caf_token_t token
, size_t offset
,
1016 int image_index
__attribute__ ((unused
)),
1017 void *value
, int *stat
,
1018 int type
__attribute__ ((unused
)), int kind
)
1022 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1024 __atomic_store (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
1031 _gfortran_caf_atomic_ref (caf_token_t token
, size_t offset
,
1032 int image_index
__attribute__ ((unused
)),
1033 void *value
, int *stat
,
1034 int type
__attribute__ ((unused
)), int kind
)
1038 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1040 __atomic_load (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
1048 _gfortran_caf_atomic_cas (caf_token_t token
, size_t offset
,
1049 int image_index
__attribute__ ((unused
)),
1050 void *old
, void *compare
, void *new_val
, int *stat
,
1051 int type
__attribute__ ((unused
)), int kind
)
1055 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1057 *(uint32_t *) old
= *(uint32_t *) compare
;
1058 (void) __atomic_compare_exchange_n (atom
, (uint32_t *) old
,
1059 *(uint32_t *) new_val
, false,
1060 __ATOMIC_RELAXED
, __ATOMIC_RELAXED
);
1067 _gfortran_caf_atomic_op (int op
, caf_token_t token
, size_t offset
,
1068 int image_index
__attribute__ ((unused
)),
1069 void *value
, void *old
, int *stat
,
1070 int type
__attribute__ ((unused
)), int kind
)
1075 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
1079 case GFC_CAF_ATOMIC_ADD
:
1080 res
= __atomic_fetch_add (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1082 case GFC_CAF_ATOMIC_AND
:
1083 res
= __atomic_fetch_and (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1085 case GFC_CAF_ATOMIC_OR
:
1086 res
= __atomic_fetch_or (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1088 case GFC_CAF_ATOMIC_XOR
:
1089 res
= __atomic_fetch_xor (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
1092 __builtin_unreachable();
1096 *(uint32_t *) old
= res
;
1103 _gfortran_caf_event_post (caf_token_t token
, size_t index
,
1104 int image_index
__attribute__ ((unused
)),
1105 int *stat
, char *errmsg
__attribute__ ((unused
)),
1106 int errmsg_len
__attribute__ ((unused
)))
1109 uint32_t *event
= (uint32_t *) ((char *) TOKEN (token
) + index
*sizeof(uint32_t));
1110 __atomic_fetch_add (event
, (uint32_t) value
, __ATOMIC_RELAXED
);
1117 _gfortran_caf_event_wait (caf_token_t token
, size_t index
,
1118 int until_count
, int *stat
,
1119 char *errmsg
__attribute__ ((unused
)),
1120 int errmsg_len
__attribute__ ((unused
)))
1122 uint32_t *event
= (uint32_t *) ((char *) TOKEN (token
) + index
*sizeof(uint32_t));
1123 uint32_t value
= (uint32_t)-until_count
;
1124 __atomic_fetch_add (event
, (uint32_t) value
, __ATOMIC_RELAXED
);
1131 _gfortran_caf_event_query (caf_token_t token
, size_t index
,
1132 int image_index
__attribute__ ((unused
)),
1133 int *count
, int *stat
)
1135 uint32_t *event
= (uint32_t *) ((char *) TOKEN (token
) + index
*sizeof(uint32_t));
1136 __atomic_load (event
, (uint32_t *) count
, __ATOMIC_RELAXED
);
1143 _gfortran_caf_lock (caf_token_t token
, size_t index
,
1144 int image_index
__attribute__ ((unused
)),
1145 int *aquired_lock
, int *stat
, char *errmsg
, int errmsg_len
)
1147 const char *msg
= "Already locked";
1148 bool *lock
= &((bool *) TOKEN (token
))[index
];
1154 *aquired_lock
= (int) true;
1162 *aquired_lock
= (int) false;
1174 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
1175 : (int) sizeof (msg
);
1176 memcpy (errmsg
, msg
, len
);
1177 if (errmsg_len
> len
)
1178 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
1182 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));
1187 _gfortran_caf_unlock (caf_token_t token
, size_t index
,
1188 int image_index
__attribute__ ((unused
)),
1189 int *stat
, char *errmsg
, int errmsg_len
)
1191 const char *msg
= "Variable is not locked";
1192 bool *lock
= &((bool *) TOKEN (token
))[index
];
1207 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
1208 : (int) sizeof (msg
);
1209 memcpy (errmsg
, msg
, len
);
1210 if (errmsg_len
> len
)
1211 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
1215 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));