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 struct caf_single_token
38 /* The pointer to the memory registered. For arrays this is the data member
39 in the descriptor. For components it's the pure data pointer. */
41 /* The descriptor when this token is associated to an allocatable array. */
42 gfc_descriptor_t
*desc
;
43 /* Set when the caf lib has allocated the memory in memptr and is responsible
44 for freeing it on deregister. */
47 typedef struct caf_single_token
*caf_single_token_t
;
49 #define TOKEN(X) ((caf_single_token_t) (X))
50 #define MEMTOK(X) ((caf_single_token_t) (X))->memptr
52 /* Single-image implementation of the CAF library.
53 Note: For performance reasons -fcoarry=single should be used
54 rather than this library. */
56 /* Global variables. */
57 caf_static_t
*caf_static_list
= NULL
;
59 /* Keep in sync with mpi.c. */
61 caf_runtime_error (const char *message
, ...)
64 fprintf (stderr
, "Fortran runtime error: ");
65 va_start (ap
, message
);
66 vfprintf (stderr
, message
, ap
);
68 fprintf (stderr
, "\n");
70 /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */
74 /* Error handling is similar everytime. */
76 caf_internal_error (const char *msg
, int *stat
, char *errmsg
,
80 va_start (args
, errmsg_len
);
86 size_t len
= snprintf (errmsg
, errmsg_len
, msg
, args
);
87 if ((size_t)errmsg_len
> len
)
88 memset (&errmsg
[len
], ' ', errmsg_len
- len
);
93 caf_runtime_error (msg
, args
);
99 _gfortran_caf_init (int *argc
__attribute__ ((unused
)),
100 char ***argv
__attribute__ ((unused
)))
106 _gfortran_caf_finalize (void)
108 while (caf_static_list
!= NULL
)
110 caf_static_t
*tmp
= caf_static_list
->prev
;
111 free (caf_static_list
->token
);
112 free (caf_static_list
);
113 caf_static_list
= tmp
;
119 _gfortran_caf_this_image (int distance
__attribute__ ((unused
)))
126 _gfortran_caf_num_images (int distance
__attribute__ ((unused
)),
127 int failed
__attribute__ ((unused
)))
134 _gfortran_caf_register (size_t size
, caf_register_t type
, caf_token_t
*token
,
135 gfc_descriptor_t
*data
, int *stat
, char *errmsg
,
138 const char alloc_fail_msg
[] = "Failed to allocate coarray";
140 caf_single_token_t single_token
;
142 if (type
== CAF_REGTYPE_LOCK_STATIC
|| type
== CAF_REGTYPE_LOCK_ALLOC
143 || type
== CAF_REGTYPE_CRITICAL
|| type
== CAF_REGTYPE_EVENT_STATIC
144 || type
== CAF_REGTYPE_EVENT_ALLOC
)
145 local
= calloc (size
, sizeof (bool));
147 local
= malloc (size
);
148 *token
= malloc (sizeof (struct caf_single_token
));
150 if (unlikely (local
== NULL
|| *token
== NULL
))
152 caf_internal_error (alloc_fail_msg
, stat
, errmsg
, errmsg_len
);
156 single_token
= TOKEN (*token
);
157 single_token
->memptr
= local
;
158 single_token
->owning_memory
= true;
159 single_token
->desc
= GFC_DESCRIPTOR_RANK (data
) > 0 ? data
: NULL
;
165 if (type
== CAF_REGTYPE_COARRAY_STATIC
|| type
== CAF_REGTYPE_LOCK_STATIC
166 || type
== CAF_REGTYPE_CRITICAL
|| type
== CAF_REGTYPE_EVENT_STATIC
167 || type
== CAF_REGTYPE_EVENT_ALLOC
)
169 caf_static_t
*tmp
= malloc (sizeof (caf_static_t
));
170 tmp
->prev
= caf_static_list
;
172 caf_static_list
= tmp
;
174 GFC_DESCRIPTOR_DATA (data
) = local
;
179 _gfortran_caf_deregister (caf_token_t
*token
, int *stat
,
180 char *errmsg
__attribute__ ((unused
)),
181 int errmsg_len
__attribute__ ((unused
)))
183 caf_single_token_t single_token
= TOKEN (*token
);
185 if (single_token
->owning_memory
&& single_token
->memptr
)
186 free (single_token
->memptr
);
188 free (TOKEN (*token
));
196 _gfortran_caf_sync_all (int *stat
,
197 char *errmsg
__attribute__ ((unused
)),
198 int errmsg_len
__attribute__ ((unused
)))
200 __asm__
__volatile__ ("":::"memory");
207 _gfortran_caf_sync_memory (int *stat
,
208 char *errmsg
__attribute__ ((unused
)),
209 int errmsg_len
__attribute__ ((unused
)))
211 __asm__
__volatile__ ("":::"memory");
218 _gfortran_caf_sync_images (int count
__attribute__ ((unused
)),
219 int images
[] __attribute__ ((unused
)),
221 char *errmsg
__attribute__ ((unused
)),
222 int errmsg_len
__attribute__ ((unused
)))
227 for (i
= 0; i
< count
; i
++)
230 fprintf (stderr
, "COARRAY ERROR: Invalid image index %d to SYNC "
231 "IMAGES", images
[i
]);
236 __asm__
__volatile__ ("":::"memory");
242 _gfortran_caf_stop_numeric(int32_t stop_code
)
244 fprintf (stderr
, "STOP %d\n", stop_code
);
249 _gfortran_caf_stop_str(const char *string
, int32_t len
)
251 fputs ("STOP ", stderr
);
253 fputc (*(string
++), stderr
);
254 fputs ("\n", stderr
);
260 _gfortran_caf_error_stop_str (const char *string
, int32_t len
)
262 fputs ("ERROR STOP ", stderr
);
264 fputc (*(string
++), stderr
);
265 fputs ("\n", stderr
);
272 _gfortran_caf_error_stop (int32_t error
)
274 fprintf (stderr
, "ERROR STOP %d\n", error
);
280 _gfortran_caf_co_broadcast (gfc_descriptor_t
*a
__attribute__ ((unused
)),
281 int source_image
__attribute__ ((unused
)),
282 int *stat
, char *errmsg
__attribute__ ((unused
)),
283 int errmsg_len
__attribute__ ((unused
)))
290 _gfortran_caf_co_sum (gfc_descriptor_t
*a
__attribute__ ((unused
)),
291 int result_image
__attribute__ ((unused
)),
292 int *stat
, char *errmsg
__attribute__ ((unused
)),
293 int errmsg_len
__attribute__ ((unused
)))
300 _gfortran_caf_co_min (gfc_descriptor_t
*a
__attribute__ ((unused
)),
301 int result_image
__attribute__ ((unused
)),
302 int *stat
, char *errmsg
__attribute__ ((unused
)),
303 int a_len
__attribute__ ((unused
)),
304 int errmsg_len
__attribute__ ((unused
)))
311 _gfortran_caf_co_max (gfc_descriptor_t
*a
__attribute__ ((unused
)),
312 int result_image
__attribute__ ((unused
)),
313 int *stat
, char *errmsg
__attribute__ ((unused
)),
314 int a_len
__attribute__ ((unused
)),
315 int errmsg_len
__attribute__ ((unused
)))
323 _gfortran_caf_co_reduce (gfc_descriptor_t
*a
__attribute__ ((unused
)),
324 void * (*opr
) (void *, void *)
325 __attribute__ ((unused
)),
326 int opr_flags
__attribute__ ((unused
)),
327 int result_image
__attribute__ ((unused
)),
328 int *stat
, char *errmsg
__attribute__ ((unused
)),
329 int a_len
__attribute__ ((unused
)),
330 int errmsg_len
__attribute__ ((unused
)))
338 assign_char4_from_char1 (size_t dst_size
, size_t src_size
, uint32_t *dst
,
342 n
= dst_size
/4 > src_size
? src_size
: dst_size
/4;
343 for (i
= 0; i
< n
; ++i
)
344 dst
[i
] = (int32_t) src
[i
];
345 for (; i
< dst_size
/4; ++i
)
346 dst
[i
] = (int32_t) ' ';
351 assign_char1_from_char4 (size_t dst_size
, size_t src_size
, unsigned char *dst
,
355 n
= dst_size
> src_size
/4 ? src_size
/4 : dst_size
;
356 for (i
= 0; i
< n
; ++i
)
357 dst
[i
] = src
[i
] > UINT8_MAX
? (unsigned char) '?' : (unsigned char) src
[i
];
359 memset (&dst
[n
], ' ', dst_size
- n
);
364 convert_type (void *dst
, int dst_type
, int dst_kind
, void *src
, int src_type
,
365 int src_kind
, int *stat
)
367 #ifdef HAVE_GFC_INTEGER_16
368 typedef __int128 int128t
;
370 typedef int64_t int128t
;
373 #if defined(GFC_REAL_16_IS_LONG_DOUBLE)
374 typedef long double real128t
;
375 typedef _Complex
long double complex128t
;
376 #elif defined(HAVE_GFC_REAL_16)
377 typedef _Complex
float __attribute__((mode(TC
))) __complex128
;
378 typedef __float128 real128t
;
379 typedef __complex128 complex128t
;
380 #elif defined(HAVE_GFC_REAL_10)
381 typedef long double real128t
;
382 typedef long double complex128t
;
384 typedef double real128t
;
385 typedef _Complex
double complex128t
;
389 real128t real_val
= 0;
390 complex128t cmpx_val
= 0;
396 int_val
= *(int8_t*) src
;
397 else if (src_kind
== 2)
398 int_val
= *(int16_t*) src
;
399 else if (src_kind
== 4)
400 int_val
= *(int32_t*) src
;
401 else if (src_kind
== 8)
402 int_val
= *(int64_t*) src
;
403 #ifdef HAVE_GFC_INTEGER_16
404 else if (src_kind
== 16)
405 int_val
= *(int128t
*) src
;
412 real_val
= *(float*) src
;
413 else if (src_kind
== 8)
414 real_val
= *(double*) src
;
415 #ifdef HAVE_GFC_REAL_10
416 else if (src_kind
== 10)
417 real_val
= *(long double*) src
;
419 #ifdef HAVE_GFC_REAL_16
420 else if (src_kind
== 16)
421 real_val
= *(real128t
*) src
;
428 cmpx_val
= *(_Complex
float*) src
;
429 else if (src_kind
== 8)
430 cmpx_val
= *(_Complex
double*) src
;
431 #ifdef HAVE_GFC_REAL_10
432 else if (src_kind
== 10)
433 cmpx_val
= *(_Complex
long double*) src
;
435 #ifdef HAVE_GFC_REAL_16
436 else if (src_kind
== 16)
437 cmpx_val
= *(complex128t
*) src
;
449 if (src_type
== BT_INTEGER
)
452 *(int8_t*) dst
= (int8_t) int_val
;
453 else if (dst_kind
== 2)
454 *(int16_t*) dst
= (int16_t) int_val
;
455 else if (dst_kind
== 4)
456 *(int32_t*) dst
= (int32_t) int_val
;
457 else if (dst_kind
== 8)
458 *(int64_t*) dst
= (int64_t) int_val
;
459 #ifdef HAVE_GFC_INTEGER_16
460 else if (dst_kind
== 16)
461 *(int128t
*) dst
= (int128t
) int_val
;
466 else if (src_type
== BT_REAL
)
469 *(int8_t*) dst
= (int8_t) real_val
;
470 else if (dst_kind
== 2)
471 *(int16_t*) dst
= (int16_t) real_val
;
472 else if (dst_kind
== 4)
473 *(int32_t*) dst
= (int32_t) real_val
;
474 else if (dst_kind
== 8)
475 *(int64_t*) dst
= (int64_t) real_val
;
476 #ifdef HAVE_GFC_INTEGER_16
477 else if (dst_kind
== 16)
478 *(int128t
*) dst
= (int128t
) real_val
;
483 else if (src_type
== BT_COMPLEX
)
486 *(int8_t*) dst
= (int8_t) cmpx_val
;
487 else if (dst_kind
== 2)
488 *(int16_t*) dst
= (int16_t) cmpx_val
;
489 else if (dst_kind
== 4)
490 *(int32_t*) dst
= (int32_t) cmpx_val
;
491 else if (dst_kind
== 8)
492 *(int64_t*) dst
= (int64_t) cmpx_val
;
493 #ifdef HAVE_GFC_INTEGER_16
494 else if (dst_kind
== 16)
495 *(int128t
*) dst
= (int128t
) cmpx_val
;
504 if (src_type
== BT_INTEGER
)
507 *(float*) dst
= (float) int_val
;
508 else if (dst_kind
== 8)
509 *(double*) dst
= (double) int_val
;
510 #ifdef HAVE_GFC_REAL_10
511 else if (dst_kind
== 10)
512 *(long double*) dst
= (long double) int_val
;
514 #ifdef HAVE_GFC_REAL_16
515 else if (dst_kind
== 16)
516 *(real128t
*) dst
= (real128t
) int_val
;
521 else if (src_type
== BT_REAL
)
524 *(float*) dst
= (float) real_val
;
525 else if (dst_kind
== 8)
526 *(double*) dst
= (double) real_val
;
527 #ifdef HAVE_GFC_REAL_10
528 else if (dst_kind
== 10)
529 *(long double*) dst
= (long double) real_val
;
531 #ifdef HAVE_GFC_REAL_16
532 else if (dst_kind
== 16)
533 *(real128t
*) dst
= (real128t
) real_val
;
538 else if (src_type
== BT_COMPLEX
)
541 *(float*) dst
= (float) cmpx_val
;
542 else if (dst_kind
== 8)
543 *(double*) dst
= (double) cmpx_val
;
544 #ifdef HAVE_GFC_REAL_10
545 else if (dst_kind
== 10)
546 *(long double*) dst
= (long double) cmpx_val
;
548 #ifdef HAVE_GFC_REAL_16
549 else if (dst_kind
== 16)
550 *(real128t
*) dst
= (real128t
) cmpx_val
;
557 if (src_type
== BT_INTEGER
)
560 *(_Complex
float*) dst
= (_Complex
float) int_val
;
561 else if (dst_kind
== 8)
562 *(_Complex
double*) dst
= (_Complex
double) int_val
;
563 #ifdef HAVE_GFC_REAL_10
564 else if (dst_kind
== 10)
565 *(_Complex
long double*) dst
= (_Complex
long double) int_val
;
567 #ifdef HAVE_GFC_REAL_16
568 else if (dst_kind
== 16)
569 *(complex128t
*) dst
= (complex128t
) int_val
;
574 else if (src_type
== BT_REAL
)
577 *(_Complex
float*) dst
= (_Complex
float) real_val
;
578 else if (dst_kind
== 8)
579 *(_Complex
double*) dst
= (_Complex
double) real_val
;
580 #ifdef HAVE_GFC_REAL_10
581 else if (dst_kind
== 10)
582 *(_Complex
long double*) dst
= (_Complex
long double) real_val
;
584 #ifdef HAVE_GFC_REAL_16
585 else if (dst_kind
== 16)
586 *(complex128t
*) dst
= (complex128t
) real_val
;
591 else if (src_type
== BT_COMPLEX
)
594 *(_Complex
float*) dst
= (_Complex
float) cmpx_val
;
595 else if (dst_kind
== 8)
596 *(_Complex
double*) dst
= (_Complex
double) cmpx_val
;
597 #ifdef HAVE_GFC_REAL_10
598 else if (dst_kind
== 10)
599 *(_Complex
long double*) dst
= (_Complex
long double) cmpx_val
;
601 #ifdef HAVE_GFC_REAL_16
602 else if (dst_kind
== 16)
603 *(complex128t
*) dst
= (complex128t
) cmpx_val
;
616 fprintf (stderr
, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind "
617 "%d to type %d kind %d\n", src_type
, src_kind
, dst_type
, dst_kind
);
626 _gfortran_caf_get (caf_token_t token
, size_t offset
,
627 int image_index
__attribute__ ((unused
)),
628 gfc_descriptor_t
*src
,
629 caf_vector_t
*src_vector
__attribute__ ((unused
)),
630 gfc_descriptor_t
*dest
, int src_kind
, int dst_kind
,
631 bool may_require_tmp
, int *stat
)
633 /* FIXME: Handle vector subscripts. */
636 int rank
= GFC_DESCRIPTOR_RANK (dest
);
637 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
638 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
645 void *sr
= (void *) ((char *) MEMTOK (token
) + offset
);
646 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
647 && dst_kind
== src_kind
)
649 memmove (GFC_DESCRIPTOR_DATA (dest
), sr
,
650 dst_size
> src_size
? src_size
: dst_size
);
651 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
654 memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest
) + src_size
,
655 ' ', dst_size
- src_size
);
656 else /* dst_kind == 4. */
657 for (i
= src_size
/4; i
< dst_size
/4; i
++)
658 ((int32_t*) GFC_DESCRIPTOR_DATA (dest
))[i
] = (int32_t) ' ';
661 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
662 assign_char1_from_char4 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
664 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
665 assign_char4_from_char1 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
668 convert_type (GFC_DESCRIPTOR_DATA (dest
), GFC_DESCRIPTOR_TYPE (dest
),
669 dst_kind
, sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
674 for (j
= 0; j
< rank
; j
++)
676 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
687 ptrdiff_t array_offset_sr
, array_offset_dst
;
688 void *tmp
= malloc (size
*src_size
);
690 array_offset_dst
= 0;
691 for (i
= 0; i
< size
; i
++)
693 ptrdiff_t array_offset_sr
= 0;
694 ptrdiff_t stride
= 1;
695 ptrdiff_t extent
= 1;
696 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
698 array_offset_sr
+= ((i
/ (extent
*stride
))
699 % (src
->dim
[j
]._ubound
700 - src
->dim
[j
].lower_bound
+ 1))
701 * src
->dim
[j
]._stride
;
702 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
703 stride
= src
->dim
[j
]._stride
;
705 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
706 void *sr
= (void *)((char *) MEMTOK (token
) + offset
707 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
708 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
709 array_offset_dst
+= src_size
;
713 for (i
= 0; i
< size
; i
++)
715 ptrdiff_t array_offset_dst
= 0;
716 ptrdiff_t stride
= 1;
717 ptrdiff_t extent
= 1;
718 for (j
= 0; j
< rank
-1; j
++)
720 array_offset_dst
+= ((i
/ (extent
*stride
))
721 % (dest
->dim
[j
]._ubound
722 - dest
->dim
[j
].lower_bound
+ 1))
723 * dest
->dim
[j
]._stride
;
724 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
725 stride
= dest
->dim
[j
]._stride
;
727 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
728 void *dst
= dest
->base_addr
729 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
730 void *sr
= tmp
+ array_offset_sr
;
732 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
733 && dst_kind
== src_kind
)
735 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
736 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
737 && dst_size
> src_size
)
740 memset ((void*)(char*) dst
+ src_size
, ' ',
742 else /* dst_kind == 4. */
743 for (k
= src_size
/4; k
< dst_size
/4; k
++)
744 ((int32_t*) dst
)[k
] = (int32_t) ' ';
747 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
748 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
749 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
750 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
752 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
753 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
754 array_offset_sr
+= src_size
;
761 for (i
= 0; i
< size
; i
++)
763 ptrdiff_t array_offset_dst
= 0;
764 ptrdiff_t stride
= 1;
765 ptrdiff_t extent
= 1;
766 for (j
= 0; j
< rank
-1; j
++)
768 array_offset_dst
+= ((i
/ (extent
*stride
))
769 % (dest
->dim
[j
]._ubound
770 - dest
->dim
[j
].lower_bound
+ 1))
771 * dest
->dim
[j
]._stride
;
772 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
773 stride
= dest
->dim
[j
]._stride
;
775 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
776 void *dst
= dest
->base_addr
+ array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
778 ptrdiff_t array_offset_sr
= 0;
781 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
783 array_offset_sr
+= ((i
/ (extent
*stride
))
784 % (src
->dim
[j
]._ubound
785 - src
->dim
[j
].lower_bound
+ 1))
786 * src
->dim
[j
]._stride
;
787 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
788 stride
= src
->dim
[j
]._stride
;
790 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
791 void *sr
= (void *)((char *) MEMTOK (token
) + offset
792 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
794 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
795 && dst_kind
== src_kind
)
797 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
798 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
801 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
802 else /* dst_kind == 4. */
803 for (k
= src_size
/4; k
< dst_size
/4; k
++)
804 ((int32_t*) dst
)[k
] = (int32_t) ' ';
807 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
808 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
809 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
810 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
812 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
813 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
819 _gfortran_caf_send (caf_token_t token
, size_t offset
,
820 int image_index
__attribute__ ((unused
)),
821 gfc_descriptor_t
*dest
,
822 caf_vector_t
*dst_vector
__attribute__ ((unused
)),
823 gfc_descriptor_t
*src
, int dst_kind
, int src_kind
,
824 bool may_require_tmp
, int *stat
)
826 /* FIXME: Handle vector subscripts. */
829 int rank
= GFC_DESCRIPTOR_RANK (dest
);
830 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
831 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
838 void *dst
= (void *) ((char *) MEMTOK (token
) + offset
);
839 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
840 && dst_kind
== src_kind
)
842 memmove (dst
, GFC_DESCRIPTOR_DATA (src
),
843 dst_size
> src_size
? src_size
: dst_size
);
844 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
847 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
848 else /* dst_kind == 4. */
849 for (i
= src_size
/4; i
< dst_size
/4; i
++)
850 ((int32_t*) dst
)[i
] = (int32_t) ' ';
853 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
854 assign_char1_from_char4 (dst_size
, src_size
, dst
,
855 GFC_DESCRIPTOR_DATA (src
));
856 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
857 assign_char4_from_char1 (dst_size
, src_size
, dst
,
858 GFC_DESCRIPTOR_DATA (src
));
860 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
861 GFC_DESCRIPTOR_DATA (src
), GFC_DESCRIPTOR_TYPE (src
),
867 for (j
= 0; j
< rank
; j
++)
869 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
880 ptrdiff_t array_offset_sr
, array_offset_dst
;
883 if (GFC_DESCRIPTOR_RANK (src
) == 0)
885 tmp
= malloc (src_size
);
886 memcpy (tmp
, GFC_DESCRIPTOR_DATA (src
), src_size
);
890 tmp
= malloc (size
*src_size
);
891 array_offset_dst
= 0;
892 for (i
= 0; i
< size
; i
++)
894 ptrdiff_t array_offset_sr
= 0;
895 ptrdiff_t stride
= 1;
896 ptrdiff_t extent
= 1;
897 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
899 array_offset_sr
+= ((i
/ (extent
*stride
))
900 % (src
->dim
[j
]._ubound
901 - src
->dim
[j
].lower_bound
+ 1))
902 * src
->dim
[j
]._stride
;
903 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
904 stride
= src
->dim
[j
]._stride
;
906 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
907 void *sr
= (void *) ((char *) src
->base_addr
908 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
909 memcpy ((void *) ((char *) tmp
+ array_offset_dst
), sr
, src_size
);
910 array_offset_dst
+= src_size
;
915 for (i
= 0; i
< size
; i
++)
917 ptrdiff_t array_offset_dst
= 0;
918 ptrdiff_t stride
= 1;
919 ptrdiff_t extent
= 1;
920 for (j
= 0; j
< rank
-1; j
++)
922 array_offset_dst
+= ((i
/ (extent
*stride
))
923 % (dest
->dim
[j
]._ubound
924 - dest
->dim
[j
].lower_bound
+ 1))
925 * dest
->dim
[j
]._stride
;
926 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
927 stride
= dest
->dim
[j
]._stride
;
929 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
930 void *dst
= (void *)((char *) MEMTOK (token
) + offset
931 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
932 void *sr
= tmp
+ array_offset_sr
;
933 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
934 && dst_kind
== src_kind
)
937 dst_size
> src_size
? src_size
: dst_size
);
938 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
939 && dst_size
> src_size
)
942 memset ((void*)(char*) dst
+ src_size
, ' ',
944 else /* dst_kind == 4. */
945 for (k
= src_size
/4; k
< dst_size
/4; k
++)
946 ((int32_t*) dst
)[k
] = (int32_t) ' ';
949 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
950 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
951 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
952 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
954 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
955 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
956 if (GFC_DESCRIPTOR_RANK (src
))
957 array_offset_sr
+= src_size
;
963 for (i
= 0; i
< size
; i
++)
965 ptrdiff_t array_offset_dst
= 0;
966 ptrdiff_t stride
= 1;
967 ptrdiff_t extent
= 1;
968 for (j
= 0; j
< rank
-1; j
++)
970 array_offset_dst
+= ((i
/ (extent
*stride
))
971 % (dest
->dim
[j
]._ubound
972 - dest
->dim
[j
].lower_bound
+ 1))
973 * dest
->dim
[j
]._stride
;
974 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
975 stride
= dest
->dim
[j
]._stride
;
977 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
978 void *dst
= (void *)((char *) MEMTOK (token
) + offset
979 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
981 if (GFC_DESCRIPTOR_RANK (src
) != 0)
983 ptrdiff_t array_offset_sr
= 0;
986 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
988 array_offset_sr
+= ((i
/ (extent
*stride
))
989 % (src
->dim
[j
]._ubound
990 - src
->dim
[j
].lower_bound
+ 1))
991 * src
->dim
[j
]._stride
;
992 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
993 stride
= src
->dim
[j
]._stride
;
995 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
996 sr
= (void *)((char *) src
->base_addr
997 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
1000 sr
= src
->base_addr
;
1002 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
1003 && dst_kind
== src_kind
)
1006 dst_size
> src_size
? src_size
: dst_size
);
1007 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
1010 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
1011 else /* dst_kind == 4. */
1012 for (k
= src_size
/4; k
< dst_size
/4; k
++)
1013 ((int32_t*) dst
)[k
] = (int32_t) ' ';
1016 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
1017 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
1018 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
1019 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
1021 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
1022 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
, stat
);
1028 _gfortran_caf_sendget (caf_token_t dst_token
, size_t dst_offset
,
1029 int dst_image_index
, gfc_descriptor_t
*dest
,
1030 caf_vector_t
*dst_vector
, caf_token_t src_token
,
1032 int src_image_index
__attribute__ ((unused
)),
1033 gfc_descriptor_t
*src
,
1034 caf_vector_t
*src_vector
__attribute__ ((unused
)),
1035 int dst_kind
, int src_kind
, bool may_require_tmp
)
1037 /* FIXME: Handle vector subscript of 'src_vector'. */
1038 /* For a single image, src->base_addr should be the same as src_token + offset
1039 but to play save, we do it properly. */
1040 void *src_base
= GFC_DESCRIPTOR_DATA (src
);
1041 GFC_DESCRIPTOR_DATA (src
) = (void *) ((char *) MEMTOK (src_token
)
1043 _gfortran_caf_send (dst_token
, dst_offset
, dst_image_index
, dest
, dst_vector
,
1044 src
, dst_kind
, src_kind
, may_require_tmp
, NULL
);
1045 GFC_DESCRIPTOR_DATA (src
) = src_base
;
1049 /* Emitted when a theorectically unreachable part is reached. */
1050 const char unreachable
[] = "Fatal error: unreachable alternative found.\n";
1054 copy_data (void *ds
, void *sr
, int dst_type
, int src_type
,
1055 int dst_kind
, int src_kind
, size_t dst_size
, size_t src_size
,
1056 size_t num
, int *stat
)
1059 if (dst_type
== src_type
&& dst_kind
== src_kind
)
1061 memmove (ds
, sr
, (dst_size
> src_size
? src_size
: dst_size
) * num
);
1062 if ((dst_type
== BT_CHARACTER
|| src_type
== BT_CHARACTER
)
1063 && dst_size
> src_size
)
1066 memset ((void*)(char*) ds
+ src_size
, ' ', dst_size
-src_size
);
1067 else /* dst_kind == 4. */
1068 for (k
= src_size
/4; k
< dst_size
/4; k
++)
1069 ((int32_t*) ds
)[k
] = (int32_t) ' ';
1072 else if (dst_type
== BT_CHARACTER
&& dst_kind
== 1)
1073 assign_char1_from_char4 (dst_size
, src_size
, ds
, sr
);
1074 else if (dst_type
== BT_CHARACTER
)
1075 assign_char4_from_char1 (dst_size
, src_size
, ds
, sr
);
1077 for (k
= 0; k
< num
; ++k
)
1079 convert_type (ds
, dst_type
, dst_kind
, sr
, src_type
, src_kind
, stat
);
1086 #define COMPUTE_NUM_ITEMS(num, stride, lb, ub) \
1088 index_type abs_stride = (stride) > 0 ? (stride) : -(stride); \
1089 num = (stride) > 0 ? (ub) + 1 - (lb) : (lb) + 1 - (ub); \
1090 if (num <= 0 || abs_stride < 1) return; \
1091 num = (abs_stride > 1) ? (1 + (num - 1) / abs_stride) : num; \
1096 get_for_ref (caf_reference_t
*ref
, size_t *i
, size_t *dst_index
,
1097 caf_single_token_t single_token
, gfc_descriptor_t
*dst
,
1098 gfc_descriptor_t
*src
, void *ds
, void *sr
,
1099 int dst_kind
, int src_kind
, size_t dst_dim
, size_t src_dim
,
1100 size_t num
, int *stat
)
1102 ptrdiff_t extent_src
= 1, array_offset_src
= 0, stride_src
;
1103 size_t next_dst_dim
;
1105 if (unlikely (ref
== NULL
))
1106 /* May be we should issue an error here, because this case should not
1110 if (ref
->next
== NULL
)
1112 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dst
);
1113 ptrdiff_t array_offset_dst
= 0;;
1114 size_t dst_rank
= GFC_DESCRIPTOR_RANK (dst
);
1119 case CAF_REF_COMPONENT
:
1120 /* Because the token is always registered after the component, its
1121 offset is always greater zeor. */
1122 if (ref
->u
.c
.caf_token_offset
> 0)
1123 copy_data (ds
, *(void **)(sr
+ ref
->u
.c
.offset
),
1124 GFC_DESCRIPTOR_TYPE (dst
), GFC_DESCRIPTOR_TYPE (dst
),
1125 dst_kind
, src_kind
, dst_size
, ref
->item_size
, 1, stat
);
1127 copy_data (ds
, sr
+ ref
->u
.c
.offset
,
1128 GFC_DESCRIPTOR_TYPE (dst
), GFC_DESCRIPTOR_TYPE (src
),
1129 dst_kind
, src_kind
, dst_size
, ref
->item_size
, 1, stat
);
1132 case CAF_REF_STATIC_ARRAY
:
1133 src_type
= ref
->u
.a
.static_array_type
;
1134 /* Intentionally fall through. */
1136 if (ref
->u
.a
.mode
[src_dim
] == CAF_ARR_REF_NONE
)
1138 for (size_t d
= 0; d
< dst_rank
; ++d
)
1139 array_offset_dst
+= dst_index
[d
];
1140 copy_data (ds
+ array_offset_dst
* dst_size
, sr
,
1141 GFC_DESCRIPTOR_TYPE (dst
),
1142 src_type
== -1 ? GFC_DESCRIPTOR_TYPE (src
) : src_type
,
1143 dst_kind
, src_kind
, dst_size
, ref
->item_size
, num
,
1150 caf_runtime_error (unreachable
);
1156 case CAF_REF_COMPONENT
:
1157 if (ref
->u
.c
.caf_token_offset
> 0)
1158 get_for_ref (ref
->next
, i
, dst_index
,
1159 *(caf_single_token_t
*)(sr
+ ref
->u
.c
.caf_token_offset
), dst
,
1160 (*(caf_single_token_t
*)(sr
+ ref
->u
.c
.caf_token_offset
))->desc
,
1161 ds
, sr
+ ref
->u
.c
.offset
, dst_kind
, src_kind
, dst_dim
, 0,
1164 get_for_ref (ref
->next
, i
, dst_index
, single_token
, dst
,
1165 (gfc_descriptor_t
*)(sr
+ ref
->u
.c
.offset
), ds
,
1166 sr
+ ref
->u
.c
.offset
, dst_kind
, src_kind
, dst_dim
, 0, 1,
1170 if (ref
->u
.a
.mode
[src_dim
] == CAF_ARR_REF_NONE
)
1172 get_for_ref (ref
->next
, i
, dst_index
, single_token
, dst
,
1173 src
, ds
, sr
, dst_kind
, src_kind
,
1174 dst_dim
, 0, 1, stat
);
1177 /* Only when on the left most index switch the data pointer to
1178 the array's data pointer. */
1180 sr
= GFC_DESCRIPTOR_DATA (src
);
1181 switch (ref
->u
.a
.mode
[src_dim
])
1183 case CAF_ARR_REF_VECTOR
:
1184 extent_src
= GFC_DIMENSION_EXTENT (src
->dim
[src_dim
]);
1185 array_offset_src
= 0;
1186 dst_index
[dst_dim
] = 0;
1187 for (size_t idx
= 0; idx
< ref
->u
.a
.dim
[src_dim
].v
.nvec
;
1190 #define KINDCASE(kind, type) case kind: \
1191 array_offset_src = (((index_type) \
1192 ((type *)ref->u.a.dim[src_dim].v.vector)[idx]) \
1193 - GFC_DIMENSION_LBOUND (src->dim[src_dim])) \
1194 * GFC_DIMENSION_STRIDE (src->dim[src_dim]); \
1197 switch (ref
->u
.a
.dim
[src_dim
].v
.kind
)
1199 KINDCASE (1, GFC_INTEGER_1
);
1200 KINDCASE (2, GFC_INTEGER_2
);
1201 KINDCASE (4, GFC_INTEGER_4
);
1202 #ifdef HAVE_GFC_INTEGER_8
1203 KINDCASE (8, GFC_INTEGER_8
);
1205 #ifdef HAVE_GFC_INTEGER_16
1206 KINDCASE (16, GFC_INTEGER_16
);
1209 caf_runtime_error (unreachable
);
1214 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
,
1215 ds
, sr
+ array_offset_src
* ref
->item_size
,
1216 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1219 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1222 case CAF_ARR_REF_FULL
:
1223 COMPUTE_NUM_ITEMS (extent_src
,
1224 ref
->u
.a
.dim
[src_dim
].s
.stride
,
1225 GFC_DIMENSION_LBOUND (src
->dim
[src_dim
]),
1226 GFC_DIMENSION_UBOUND (src
->dim
[src_dim
]));
1227 stride_src
= src
->dim
[src_dim
]._stride
1228 * ref
->u
.a
.dim
[src_dim
].s
.stride
;
1229 array_offset_src
= 0;
1230 dst_index
[dst_dim
] = 0;
1231 for (index_type idx
= 0; idx
< extent_src
;
1232 ++idx
, array_offset_src
+= stride_src
)
1234 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
,
1235 ds
, sr
+ array_offset_src
* ref
->item_size
,
1236 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1239 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1242 case CAF_ARR_REF_RANGE
:
1243 COMPUTE_NUM_ITEMS (extent_src
,
1244 ref
->u
.a
.dim
[src_dim
].s
.stride
,
1245 ref
->u
.a
.dim
[src_dim
].s
.start
,
1246 ref
->u
.a
.dim
[src_dim
].s
.end
);
1247 array_offset_src
= (ref
->u
.a
.dim
[src_dim
].s
.start
1248 - GFC_DIMENSION_LBOUND (src
->dim
[src_dim
]))
1249 * GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
1250 stride_src
= GFC_DIMENSION_STRIDE (src
->dim
[src_dim
])
1251 * ref
->u
.a
.dim
[src_dim
].s
.stride
;
1252 dst_index
[dst_dim
] = 0;
1253 /* Increase the dst_dim only, when the src_extent is greater one
1254 or src and dst extent are both one. Don't increase when the scalar
1255 source is not present in the dst. */
1256 next_dst_dim
= extent_src
> 1
1257 || (GFC_DIMENSION_EXTENT (dst
->dim
[dst_dim
]) == 1
1258 && extent_src
== 1) ? (dst_dim
+ 1) : dst_dim
;
1259 for (index_type idx
= 0; idx
< extent_src
; ++idx
)
1261 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
,
1262 ds
, sr
+ array_offset_src
* ref
->item_size
,
1263 dst_kind
, src_kind
, next_dst_dim
, src_dim
+ 1,
1266 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1267 array_offset_src
+= stride_src
;
1270 case CAF_ARR_REF_SINGLE
:
1271 array_offset_src
= (ref
->u
.a
.dim
[src_dim
].s
.start
1272 - src
->dim
[src_dim
].lower_bound
)
1273 * GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
1274 dst_index
[dst_dim
] = 0;
1275 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
, ds
,
1276 sr
+ array_offset_src
* ref
->item_size
,
1277 dst_kind
, src_kind
, dst_dim
, src_dim
+ 1, 1,
1280 case CAF_ARR_REF_OPEN_END
:
1281 COMPUTE_NUM_ITEMS (extent_src
,
1282 ref
->u
.a
.dim
[src_dim
].s
.stride
,
1283 ref
->u
.a
.dim
[src_dim
].s
.start
,
1284 GFC_DIMENSION_UBOUND (src
->dim
[src_dim
]));
1285 stride_src
= GFC_DIMENSION_STRIDE (src
->dim
[src_dim
])
1286 * ref
->u
.a
.dim
[src_dim
].s
.stride
;
1287 array_offset_src
= (ref
->u
.a
.dim
[src_dim
].s
.start
1288 - GFC_DIMENSION_LBOUND (src
->dim
[src_dim
]))
1289 * GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
1290 dst_index
[dst_dim
] = 0;
1291 for (index_type idx
= 0; idx
< extent_src
; ++idx
)
1293 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
,
1294 ds
, sr
+ array_offset_src
* ref
->item_size
,
1295 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1298 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1299 array_offset_src
+= stride_src
;
1302 case CAF_ARR_REF_OPEN_START
:
1303 COMPUTE_NUM_ITEMS (extent_src
,
1304 ref
->u
.a
.dim
[src_dim
].s
.stride
,
1305 GFC_DIMENSION_LBOUND (src
->dim
[src_dim
]),
1306 ref
->u
.a
.dim
[src_dim
].s
.end
);
1307 stride_src
= GFC_DIMENSION_STRIDE (src
->dim
[src_dim
])
1308 * ref
->u
.a
.dim
[src_dim
].s
.stride
;
1309 array_offset_src
= 0;
1310 dst_index
[dst_dim
] = 0;
1311 for (index_type idx
= 0; idx
< extent_src
; ++idx
)
1313 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, src
,
1314 ds
, sr
+ array_offset_src
* ref
->item_size
,
1315 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1318 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1319 array_offset_src
+= stride_src
;
1323 caf_runtime_error (unreachable
);
1326 case CAF_REF_STATIC_ARRAY
:
1327 if (ref
->u
.a
.mode
[src_dim
] == CAF_ARR_REF_NONE
)
1329 get_for_ref (ref
->next
, i
, dst_index
, single_token
, dst
,
1330 NULL
, ds
, sr
, dst_kind
, src_kind
,
1331 dst_dim
, 0, 1, stat
);
1334 switch (ref
->u
.a
.mode
[src_dim
])
1336 case CAF_ARR_REF_VECTOR
:
1337 array_offset_src
= 0;
1338 dst_index
[dst_dim
] = 0;
1339 for (size_t idx
= 0; idx
< ref
->u
.a
.dim
[src_dim
].v
.nvec
;
1342 #define KINDCASE(kind, type) case kind: \
1343 array_offset_src = ((type *)ref->u.a.dim[src_dim].v.vector)[idx]; \
1346 switch (ref
->u
.a
.dim
[src_dim
].v
.kind
)
1348 KINDCASE (1, GFC_INTEGER_1
);
1349 KINDCASE (2, GFC_INTEGER_2
);
1350 KINDCASE (4, GFC_INTEGER_4
);
1351 #ifdef HAVE_GFC_INTEGER_8
1352 KINDCASE (8, GFC_INTEGER_8
);
1354 #ifdef HAVE_GFC_INTEGER_16
1355 KINDCASE (16, GFC_INTEGER_16
);
1358 caf_runtime_error (unreachable
);
1363 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, NULL
,
1364 ds
, sr
+ array_offset_src
* ref
->item_size
,
1365 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1368 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1371 case CAF_ARR_REF_FULL
:
1372 dst_index
[dst_dim
] = 0;
1373 for (array_offset_src
= 0 ;
1374 array_offset_src
<= ref
->u
.a
.dim
[src_dim
].s
.end
;
1375 array_offset_src
+= ref
->u
.a
.dim
[src_dim
].s
.stride
)
1377 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, NULL
,
1378 ds
, sr
+ array_offset_src
* ref
->item_size
,
1379 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1382 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1385 case CAF_ARR_REF_RANGE
:
1386 COMPUTE_NUM_ITEMS (extent_src
,
1387 ref
->u
.a
.dim
[src_dim
].s
.stride
,
1388 ref
->u
.a
.dim
[src_dim
].s
.start
,
1389 ref
->u
.a
.dim
[src_dim
].s
.end
);
1390 array_offset_src
= ref
->u
.a
.dim
[src_dim
].s
.start
;
1391 dst_index
[dst_dim
] = 0;
1392 for (index_type idx
= 0; idx
< extent_src
; ++idx
)
1394 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, NULL
,
1395 ds
, sr
+ array_offset_src
* ref
->item_size
,
1396 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
1399 += GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
1400 array_offset_src
+= ref
->u
.a
.dim
[src_dim
].s
.stride
;
1403 case CAF_ARR_REF_SINGLE
:
1404 array_offset_src
= ref
->u
.a
.dim
[src_dim
].s
.start
;
1405 get_for_ref (ref
, i
, dst_index
, single_token
, dst
, NULL
, ds
,
1406 sr
+ array_offset_src
* ref
->item_size
,
1407 dst_kind
, src_kind
, dst_dim
, src_dim
+ 1, 1,
1410 /* The OPEN_* are mapped to a RANGE and therefore can not occur. */
1411 case CAF_ARR_REF_OPEN_END
:
1412 case CAF_ARR_REF_OPEN_START
:
1414 caf_runtime_error (unreachable
);
1418 caf_runtime_error (unreachable
);
1424 _gfortran_caf_get_by_ref (caf_token_t token
,
1425 int image_index
__attribute__ ((unused
)),
1426 gfc_descriptor_t
*dst
, caf_reference_t
*refs
,
1427 int dst_kind
, int src_kind
,
1428 bool may_require_tmp
__attribute__ ((unused
)),
1429 bool dst_reallocatable
, int *stat
)
1431 const char vecrefunknownkind
[] = "libcaf_single::caf_get_by_ref(): "
1432 "unknown kind in vector-ref.\n";
1433 const char unknownreftype
[] = "libcaf_single::caf_get_by_ref(): "
1434 "unknown reference type.\n";
1435 const char unknownarrreftype
[] = "libcaf_single::caf_get_by_ref(): "
1436 "unknown array reference type.\n";
1437 const char rankoutofrange
[] = "libcaf_single::caf_get_by_ref(): "
1438 "rank out of range.\n";
1439 const char extentoutofrange
[] = "libcaf_single::caf_get_by_ref(): "
1440 "extent out of range.\n";
1441 const char cannotallocdst
[] = "libcaf_single::caf_get_by_ref(): "
1442 "can not allocate memory.\n";
1443 const char nonallocextentmismatch
[] = "libcaf_single::caf_get_by_ref(): "
1444 "extent of non-allocatable arrays mismatch (%lu != %lu).\n";
1445 const char doublearrayref
[] = "libcaf_single::caf_get_by_ref(): "
1446 "two or more array part references are not supported.\n";
1448 size_t dst_index
[GFC_MAX_DIMENSIONS
];
1449 int dst_rank
= GFC_DESCRIPTOR_RANK (dst
);
1450 int dst_cur_dim
= 0;
1452 caf_single_token_t single_token
= TOKEN (token
);
1453 void *memptr
= single_token
->memptr
;
1454 gfc_descriptor_t
*src
= single_token
->desc
;
1455 caf_reference_t
*riter
= refs
;
1457 /* Reallocation of dst.data is needed (e.g., array to small). */
1458 bool realloc_needed
;
1459 /* Reallocation of dst.data is required, because data is not alloced at
1461 bool realloc_required
;
1462 bool extent_mismatch
= false;
1463 /* Set when the first non-scalar array reference is encountered. */
1464 bool in_array_ref
= false;
1465 bool array_extent_fixed
= false;
1466 realloc_needed
= realloc_required
= GFC_DESCRIPTOR_DATA (dst
) == NULL
;
1468 assert (!realloc_needed
|| (realloc_needed
&& dst_reallocatable
));
1473 /* Compute the size of the result. In the beginning size just counts the
1474 number of elements. */
1478 switch (riter
->type
)
1480 case CAF_REF_COMPONENT
:
1481 if (riter
->u
.c
.caf_token_offset
)
1483 single_token
= *(caf_single_token_t
*)
1484 (memptr
+ riter
->u
.c
.caf_token_offset
);
1485 memptr
= single_token
->memptr
;
1486 src
= single_token
->desc
;
1490 memptr
+= riter
->u
.c
.offset
;
1491 src
= (gfc_descriptor_t
*)memptr
;
1495 for (i
= 0; riter
->u
.a
.mode
[i
] != CAF_ARR_REF_NONE
; ++i
)
1497 switch (riter
->u
.a
.mode
[i
])
1499 case CAF_ARR_REF_VECTOR
:
1500 delta
= riter
->u
.a
.dim
[i
].v
.nvec
;
1501 #define KINDCASE(kind, type) case kind: \
1502 memptr += (((index_type) \
1503 ((type *)riter->u.a.dim[i].v.vector)[0]) \
1504 - GFC_DIMENSION_LBOUND (src->dim[i])) \
1505 * GFC_DIMENSION_STRIDE (src->dim[i]) \
1506 * riter->item_size; \
1509 switch (riter
->u
.a
.dim
[i
].v
.kind
)
1511 KINDCASE (1, GFC_INTEGER_1
);
1512 KINDCASE (2, GFC_INTEGER_2
);
1513 KINDCASE (4, GFC_INTEGER_4
);
1514 #ifdef HAVE_GFC_INTEGER_8
1515 KINDCASE (8, GFC_INTEGER_8
);
1517 #ifdef HAVE_GFC_INTEGER_16
1518 KINDCASE (16, GFC_INTEGER_16
);
1521 caf_internal_error (vecrefunknownkind
, stat
, NULL
, 0);
1526 case CAF_ARR_REF_FULL
:
1527 COMPUTE_NUM_ITEMS (delta
,
1528 riter
->u
.a
.dim
[i
].s
.stride
,
1529 GFC_DIMENSION_LBOUND (src
->dim
[i
]),
1530 GFC_DIMENSION_UBOUND (src
->dim
[i
]));
1531 /* The memptr stays unchanged when ref'ing the first element
1534 case CAF_ARR_REF_RANGE
:
1535 COMPUTE_NUM_ITEMS (delta
,
1536 riter
->u
.a
.dim
[i
].s
.stride
,
1537 riter
->u
.a
.dim
[i
].s
.start
,
1538 riter
->u
.a
.dim
[i
].s
.end
);
1539 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
1540 - GFC_DIMENSION_LBOUND (src
->dim
[i
]))
1541 * GFC_DIMENSION_STRIDE (src
->dim
[i
])
1544 case CAF_ARR_REF_SINGLE
:
1546 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
1547 - GFC_DIMENSION_LBOUND (src
->dim
[i
]))
1548 * GFC_DIMENSION_STRIDE (src
->dim
[i
])
1551 case CAF_ARR_REF_OPEN_END
:
1552 COMPUTE_NUM_ITEMS (delta
,
1553 riter
->u
.a
.dim
[i
].s
.stride
,
1554 riter
->u
.a
.dim
[i
].s
.start
,
1555 GFC_DIMENSION_UBOUND (src
->dim
[i
]));
1556 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
1557 - GFC_DIMENSION_LBOUND (src
->dim
[i
]))
1558 * GFC_DIMENSION_STRIDE (src
->dim
[i
])
1561 case CAF_ARR_REF_OPEN_START
:
1562 COMPUTE_NUM_ITEMS (delta
,
1563 riter
->u
.a
.dim
[i
].s
.stride
,
1564 GFC_DIMENSION_LBOUND (src
->dim
[i
]),
1565 riter
->u
.a
.dim
[i
].s
.end
);
1566 /* The memptr stays unchanged when ref'ing the first element
1570 caf_internal_error (unknownarrreftype
, stat
, NULL
, 0);
1575 /* Check the various properties of the destination array.
1576 Is an array expected and present? */
1577 if (delta
> 1 && dst_rank
== 0)
1579 /* No, an array is required, but not provided. */
1580 caf_internal_error (extentoutofrange
, stat
, NULL
, 0);
1583 /* When dst is an array. */
1586 /* Check that dst_cur_dim is valid for dst. Can be
1587 superceeded only by scalar data. */
1588 if (dst_cur_dim
>= dst_rank
&& delta
!= 1)
1590 caf_internal_error (rankoutofrange
, stat
, NULL
, 0);
1593 /* Do further checks, when the source is not scalar. */
1594 else if (delta
!= 1)
1596 /* Check that the extent is not scalar and we are not in
1597 an array ref for the dst side. */
1600 /* Check that this is the non-scalar extent. */
1601 if (!array_extent_fixed
)
1603 /* In an array extent now. */
1604 in_array_ref
= true;
1605 /* Check that we haven't skipped any scalar
1606 dimensions yet and that the dst is
1609 && dst_rank
== GFC_DESCRIPTOR_RANK (src
))
1611 if (dst_reallocatable
)
1613 /* Dst is reallocatable, which means that
1614 the bounds are not set. Set them. */
1615 for (dst_cur_dim
= 0; dst_cur_dim
< (int)i
;
1617 GFC_DIMENSION_SET (dst
->dim
[dst_cur_dim
],
1623 /* Else press thumbs, that there are enough
1624 dimensional refs to come. Checked below. */
1628 caf_internal_error (doublearrayref
, stat
, NULL
,
1633 /* When the realloc is required, then no extent may have
1635 extent_mismatch
= realloc_required
1636 || GFC_DESCRIPTOR_EXTENT (dst
, dst_cur_dim
) != delta
;
1637 /* When it already known, that a realloc is needed or
1638 the extent does not match the needed one. */
1639 if (realloc_required
|| realloc_needed
1642 /* Check whether dst is reallocatable. */
1643 if (unlikely (!dst_reallocatable
))
1645 caf_internal_error (nonallocextentmismatch
, stat
,
1647 GFC_DESCRIPTOR_EXTENT (dst
,
1651 /* Only report an error, when the extent needs to be
1652 modified, which is not allowed. */
1653 else if (!dst_reallocatable
&& extent_mismatch
)
1655 caf_internal_error (extentoutofrange
, stat
, NULL
,
1659 realloc_needed
= true;
1661 /* Only change the extent when it does not match. This is
1662 to prevent resetting given array bounds. */
1663 if (extent_mismatch
)
1664 GFC_DIMENSION_SET (dst
->dim
[dst_cur_dim
], 1, delta
,
1668 /* Only increase the dim counter, when in an array ref. */
1669 if (in_array_ref
&& dst_cur_dim
< dst_rank
)
1672 size
*= (index_type
)delta
;
1676 array_extent_fixed
= true;
1677 in_array_ref
= false;
1678 /* Check, if we got less dimensional refs than the rank of dst
1680 assert (dst_cur_dim
== GFC_DESCRIPTOR_RANK (dst
));
1683 case CAF_REF_STATIC_ARRAY
:
1684 for (i
= 0; riter
->u
.a
.mode
[i
] != CAF_ARR_REF_NONE
; ++i
)
1686 switch (riter
->u
.a
.mode
[i
])
1688 case CAF_ARR_REF_VECTOR
:
1689 delta
= riter
->u
.a
.dim
[i
].v
.nvec
;
1690 #define KINDCASE(kind, type) case kind: \
1691 memptr += ((type *)riter->u.a.dim[i].v.vector)[0] \
1692 * riter->item_size; \
1695 switch (riter
->u
.a
.dim
[i
].v
.kind
)
1697 KINDCASE (1, GFC_INTEGER_1
);
1698 KINDCASE (2, GFC_INTEGER_2
);
1699 KINDCASE (4, GFC_INTEGER_4
);
1700 #ifdef HAVE_GFC_INTEGER_8
1701 KINDCASE (8, GFC_INTEGER_8
);
1703 #ifdef HAVE_GFC_INTEGER_16
1704 KINDCASE (16, GFC_INTEGER_16
);
1707 caf_internal_error (vecrefunknownkind
, stat
, NULL
, 0);
1712 case CAF_ARR_REF_FULL
:
1713 delta
= riter
->u
.a
.dim
[i
].s
.end
/ riter
->u
.a
.dim
[i
].s
.stride
1715 /* The memptr stays unchanged when ref'ing the first element
1718 case CAF_ARR_REF_RANGE
:
1719 COMPUTE_NUM_ITEMS (delta
,
1720 riter
->u
.a
.dim
[i
].s
.stride
,
1721 riter
->u
.a
.dim
[i
].s
.start
,
1722 riter
->u
.a
.dim
[i
].s
.end
);
1723 memptr
+= riter
->u
.a
.dim
[i
].s
.start
1724 * riter
->u
.a
.dim
[i
].s
.stride
1727 case CAF_ARR_REF_SINGLE
:
1729 memptr
+= riter
->u
.a
.dim
[i
].s
.start
1730 * riter
->u
.a
.dim
[i
].s
.stride
1733 case CAF_ARR_REF_OPEN_END
:
1734 /* This and OPEN_START are mapped to a RANGE and therefore
1735 can not occur here. */
1736 case CAF_ARR_REF_OPEN_START
:
1738 caf_internal_error (unknownarrreftype
, stat
, NULL
, 0);
1743 /* Check the various properties of the destination array.
1744 Is an array expected and present? */
1745 if (delta
> 1 && dst_rank
== 0)
1747 /* No, an array is required, but not provided. */
1748 caf_internal_error (extentoutofrange
, stat
, NULL
, 0);
1751 /* When dst is an array. */
1754 /* Check that dst_cur_dim is valid for dst. Can be
1755 superceeded only by scalar data. */
1756 if (dst_cur_dim
>= dst_rank
&& delta
!= 1)
1758 caf_internal_error (rankoutofrange
, stat
, NULL
, 0);
1761 /* Do further checks, when the source is not scalar. */
1762 else if (delta
!= 1)
1764 /* Check that the extent is not scalar and we are not in
1765 an array ref for the dst side. */
1768 /* Check that this is the non-scalar extent. */
1769 if (!array_extent_fixed
)
1771 /* In an array extent now. */
1772 in_array_ref
= true;
1773 /* The dst is not reallocatable, so nothing more
1774 to do, then correct the dim counter. */
1779 caf_internal_error (doublearrayref
, stat
, NULL
,
1784 /* When the realloc is required, then no extent may have
1786 extent_mismatch
= realloc_required
1787 || GFC_DESCRIPTOR_EXTENT (dst
, dst_cur_dim
) != delta
;
1788 /* When it is already known, that a realloc is needed or
1789 the extent does not match the needed one. */
1790 if (realloc_required
|| realloc_needed
1793 /* Check whether dst is reallocatable. */
1794 if (unlikely (!dst_reallocatable
))
1796 caf_internal_error (nonallocextentmismatch
, stat
,
1798 GFC_DESCRIPTOR_EXTENT (dst
,
1802 /* Only report an error, when the extent needs to be
1803 modified, which is not allowed. */
1804 else if (!dst_reallocatable
&& extent_mismatch
)
1806 caf_internal_error (extentoutofrange
, stat
, NULL
,
1810 realloc_needed
= true;
1812 /* Only change the extent when it does not match. This is
1813 to prevent resetting given array bounds. */
1814 if (extent_mismatch
)
1815 GFC_DIMENSION_SET (dst
->dim
[dst_cur_dim
], 1, delta
,
1818 /* Only increase the dim counter, when in an array ref. */
1819 if (in_array_ref
&& dst_cur_dim
< dst_rank
)
1822 size
*= (index_type
)delta
;
1826 array_extent_fixed
= true;
1827 in_array_ref
= false;
1828 /* Check, if we got less dimensional refs than the rank of dst
1830 assert (dst_cur_dim
== GFC_DESCRIPTOR_RANK (dst
));
1834 caf_internal_error (unknownreftype
, stat
, NULL
, 0);
1837 src_size
= riter
->item_size
;
1838 riter
= riter
->next
;
1840 if (size
== 0 || src_size
== 0)
1843 - size contains the number of elements to store in the destination array,
1844 - src_size gives the size in bytes of each item in the destination array.
1849 if (!array_extent_fixed
)
1852 /* This can happen only, when the result is scalar. */
1853 for (dst_cur_dim
= 0; dst_cur_dim
< dst_rank
; ++dst_cur_dim
)
1854 GFC_DIMENSION_SET (dst
->dim
[dst_cur_dim
], 1, 1, 1);
1857 GFC_DESCRIPTOR_DATA (dst
) = malloc (size
* GFC_DESCRIPTOR_SIZE (dst
));
1858 if (unlikely (GFC_DESCRIPTOR_DATA (dst
) == NULL
))
1860 caf_internal_error (cannotallocdst
, stat
, NULL
, 0);
1865 /* Reset the token. */
1866 single_token
= TOKEN (token
);
1867 memptr
= single_token
->memptr
;
1868 src
= single_token
->desc
;
1869 memset(dst_index
, 0, sizeof (dst_index
));
1871 get_for_ref (refs
, &i
, dst_index
, single_token
, dst
, src
,
1872 GFC_DESCRIPTOR_DATA (dst
), memptr
, dst_kind
, src_kind
, 0, 0,
1878 send_by_ref (caf_reference_t
*ref
, size_t *i
, size_t *src_index
,
1879 caf_single_token_t single_token
, gfc_descriptor_t
*dst
,
1880 gfc_descriptor_t
*src
, void *ds
, void *sr
,
1881 int dst_kind
, int src_kind
, size_t dst_dim
, size_t src_dim
,
1882 size_t num
, size_t size
, int *stat
)
1884 const char vecrefunknownkind
[] = "libcaf_single::caf_send_by_ref(): "
1885 "unknown kind in vector-ref.\n";
1886 ptrdiff_t extent_dst
= 1, array_offset_dst
= 0, stride_dst
;
1887 const size_t src_rank
= GFC_DESCRIPTOR_RANK (src
);
1889 if (unlikely (ref
== NULL
))
1890 /* May be we should issue an error here, because this case should not
1894 if (ref
->next
== NULL
)
1896 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
1897 ptrdiff_t array_offset_src
= 0;;
1902 case CAF_REF_COMPONENT
:
1903 if (ref
->u
.c
.caf_token_offset
> 0)
1905 if (*(void**)(ds
+ ref
->u
.c
.offset
) == NULL
)
1907 /* Create a scalar temporary array descriptor. */
1908 gfc_descriptor_t static_dst
;
1909 GFC_DESCRIPTOR_DATA (&static_dst
) = NULL
;
1910 GFC_DESCRIPTOR_DTYPE (&static_dst
)
1911 = GFC_DESCRIPTOR_DTYPE (src
);
1912 /* The component may be allocated now, because it is a
1914 single_token
= *(caf_single_token_t
*)
1915 (ds
+ ref
->u
.c
.caf_token_offset
);
1916 _gfortran_caf_register (ref
->item_size
,
1917 CAF_REGTYPE_COARRAY_ALLOC
,
1918 (caf_token_t
*)&single_token
,
1919 &static_dst
, stat
, NULL
, 0);
1920 /* In case of an error in allocation return. When stat is
1921 NULL, then register_component() terminates on error. */
1922 if (stat
!= NULL
&& *stat
)
1924 /* Publish the allocated memory. */
1925 *((void **)(ds
+ ref
->u
.c
.offset
))
1926 = GFC_DESCRIPTOR_DATA (&static_dst
);
1927 ds
= GFC_DESCRIPTOR_DATA (&static_dst
);
1928 /* Set the type from the src. */
1929 dst_type
= GFC_DESCRIPTOR_TYPE (src
);
1933 ds
= GFC_DESCRIPTOR_DATA (dst
);
1934 dst_type
= GFC_DESCRIPTOR_TYPE (dst
);
1936 copy_data (ds
, sr
, dst_type
, GFC_DESCRIPTOR_TYPE (src
),
1937 dst_kind
, src_kind
, ref
->item_size
, src_size
, 1, stat
);
1940 copy_data (ds
+ ref
->u
.c
.offset
, sr
,
1941 dst
!= NULL
? GFC_DESCRIPTOR_TYPE (dst
)
1942 : GFC_DESCRIPTOR_TYPE (src
),
1943 GFC_DESCRIPTOR_TYPE (src
),
1944 dst_kind
, src_kind
, ref
->item_size
, src_size
, 1, stat
);
1947 case CAF_REF_STATIC_ARRAY
:
1948 dst_type
= ref
->u
.a
.static_array_type
;
1949 /* Intentionally fall through. */
1951 if (ref
->u
.a
.mode
[dst_dim
] == CAF_ARR_REF_NONE
)
1955 for (size_t d
= 0; d
< src_rank
; ++d
)
1956 array_offset_src
+= src_index
[d
];
1957 copy_data (ds
, sr
+ array_offset_src
* ref
->item_size
,
1958 dst_type
== -1 ? GFC_DESCRIPTOR_TYPE (dst
)
1960 GFC_DESCRIPTOR_TYPE (src
), dst_kind
, src_kind
,
1961 ref
->item_size
, src_size
, num
, stat
);
1965 dst_type
== -1 ? GFC_DESCRIPTOR_TYPE (dst
)
1967 GFC_DESCRIPTOR_TYPE (src
), dst_kind
, src_kind
,
1968 ref
->item_size
, src_size
, num
, stat
);
1974 caf_runtime_error (unreachable
);
1980 case CAF_REF_COMPONENT
:
1981 if (ref
->u
.c
.caf_token_offset
> 0)
1983 if (*(void**)(ds
+ ref
->u
.c
.offset
) == NULL
)
1985 /* This component refs an unallocated array. Non-arrays are
1986 caught in the if (!ref->next) above. */
1987 dst
= (gfc_descriptor_t
*)(ds
+ ref
->u
.c
.offset
);
1988 /* Assume that the rank and the dimensions fit for copying src
1990 GFC_DESCRIPTOR_DTYPE (dst
) = GFC_DESCRIPTOR_DTYPE (src
);
1993 for (size_t d
= 0; d
< src_rank
; ++d
)
1995 extent_dst
= GFC_DIMENSION_EXTENT (src
->dim
[d
]);
1996 GFC_DIMENSION_LBOUND (dst
->dim
[d
]) = 0;
1997 GFC_DIMENSION_UBOUND (dst
->dim
[d
]) = extent_dst
- 1;
1998 GFC_DIMENSION_STRIDE (dst
->dim
[d
]) = stride_dst
;
1999 stride_dst
*= extent_dst
;
2001 /* Null the data-pointer to make register_component allocate
2003 GFC_DESCRIPTOR_DATA (dst
) = NULL
;
2005 /* The size of the array is given by size. */
2006 _gfortran_caf_register (size
* ref
->item_size
,
2007 CAF_REGTYPE_COARRAY_ALLOC
,
2008 (void **)&single_token
,
2009 dst
, stat
, NULL
, 0);
2010 /* In case of an error in allocation return. When stat is
2011 NULL, then register_component() terminates on error. */
2012 if (stat
!= NULL
&& *stat
)
2014 /* The memptr, descriptor and the token are set below. */
2015 *(caf_single_token_t
*)(ds
+ ref
->u
.c
.caf_token_offset
)
2018 single_token
= *(caf_single_token_t
*)(ds
+ ref
->u
.c
.caf_token_offset
);
2019 send_by_ref (ref
->next
, i
, src_index
, single_token
,
2020 single_token
->desc
, src
, ds
+ ref
->u
.c
.offset
, sr
,
2021 dst_kind
, src_kind
, 0, src_dim
, 1, size
, stat
);
2024 send_by_ref (ref
->next
, i
, src_index
, single_token
,
2025 (gfc_descriptor_t
*)(ds
+ ref
->u
.c
.offset
), src
,
2026 ds
+ ref
->u
.c
.offset
, sr
, dst_kind
, src_kind
, 0, src_dim
,
2030 if (ref
->u
.a
.mode
[dst_dim
] == CAF_ARR_REF_NONE
)
2032 send_by_ref (ref
->next
, i
, src_index
, single_token
,
2033 (gfc_descriptor_t
*)ds
, src
, ds
, sr
, dst_kind
, src_kind
,
2034 0, src_dim
, 1, size
, stat
);
2037 /* Only when on the left most index switch the data pointer to
2038 the array's data pointer. And only for non-static arrays. */
2039 if (dst_dim
== 0 && ref
->type
!= CAF_REF_STATIC_ARRAY
)
2040 ds
= GFC_DESCRIPTOR_DATA (dst
);
2041 switch (ref
->u
.a
.mode
[dst_dim
])
2043 case CAF_ARR_REF_VECTOR
:
2044 array_offset_dst
= 0;
2045 src_index
[src_dim
] = 0;
2046 for (size_t idx
= 0; idx
< ref
->u
.a
.dim
[dst_dim
].v
.nvec
;
2049 #define KINDCASE(kind, type) case kind: \
2050 array_offset_dst = (((index_type) \
2051 ((type *)ref->u.a.dim[dst_dim].v.vector)[idx]) \
2052 - GFC_DIMENSION_LBOUND (dst->dim[dst_dim])) \
2053 * GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); \
2056 switch (ref
->u
.a
.dim
[dst_dim
].v
.kind
)
2058 KINDCASE (1, GFC_INTEGER_1
);
2059 KINDCASE (2, GFC_INTEGER_2
);
2060 KINDCASE (4, GFC_INTEGER_4
);
2061 #ifdef HAVE_GFC_INTEGER_8
2062 KINDCASE (8, GFC_INTEGER_8
);
2064 #ifdef HAVE_GFC_INTEGER_16
2065 KINDCASE (16, GFC_INTEGER_16
);
2068 caf_internal_error (vecrefunknownkind
, stat
, NULL
, 0);
2073 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
,
2074 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2075 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2079 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2082 case CAF_ARR_REF_FULL
:
2083 COMPUTE_NUM_ITEMS (extent_dst
,
2084 ref
->u
.a
.dim
[dst_dim
].s
.stride
,
2085 GFC_DIMENSION_LBOUND (dst
->dim
[dst_dim
]),
2086 GFC_DIMENSION_UBOUND (dst
->dim
[dst_dim
]));
2087 array_offset_dst
= 0;
2088 stride_dst
= GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
])
2089 * ref
->u
.a
.dim
[dst_dim
].s
.stride
;
2090 src_index
[src_dim
] = 0;
2091 for (index_type idx
= 0; idx
< extent_dst
;
2092 ++idx
, array_offset_dst
+= stride_dst
)
2094 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
,
2095 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2096 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2100 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2103 case CAF_ARR_REF_RANGE
:
2104 COMPUTE_NUM_ITEMS (extent_dst
,
2105 ref
->u
.a
.dim
[dst_dim
].s
.stride
,
2106 ref
->u
.a
.dim
[dst_dim
].s
.start
,
2107 ref
->u
.a
.dim
[dst_dim
].s
.end
);
2108 array_offset_dst
= ref
->u
.a
.dim
[dst_dim
].s
.start
2109 - GFC_DIMENSION_LBOUND (dst
->dim
[dst_dim
]);
2110 stride_dst
= GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
])
2111 * ref
->u
.a
.dim
[dst_dim
].s
.stride
;
2112 src_index
[src_dim
] = 0;
2113 for (index_type idx
= 0; idx
< extent_dst
; ++idx
)
2115 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
,
2116 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2117 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2121 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2122 array_offset_dst
+= stride_dst
;
2125 case CAF_ARR_REF_SINGLE
:
2126 array_offset_dst
= (ref
->u
.a
.dim
[dst_dim
].s
.start
2127 - GFC_DIMENSION_LBOUND (dst
->dim
[dst_dim
]))
2128 * GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
]);
2129 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
, ds
2130 + array_offset_dst
* ref
->item_size
, sr
,
2131 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
, 1,
2134 case CAF_ARR_REF_OPEN_END
:
2135 COMPUTE_NUM_ITEMS (extent_dst
,
2136 ref
->u
.a
.dim
[dst_dim
].s
.stride
,
2137 ref
->u
.a
.dim
[dst_dim
].s
.start
,
2138 GFC_DIMENSION_UBOUND (dst
->dim
[dst_dim
]));
2139 array_offset_dst
= ref
->u
.a
.dim
[dst_dim
].s
.start
2140 - GFC_DIMENSION_LBOUND (dst
->dim
[dst_dim
]);
2141 stride_dst
= GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
])
2142 * ref
->u
.a
.dim
[dst_dim
].s
.stride
;
2143 src_index
[src_dim
] = 0;
2144 for (index_type idx
= 0; idx
< extent_dst
; ++idx
)
2146 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
,
2147 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2148 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2152 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2153 array_offset_dst
+= stride_dst
;
2156 case CAF_ARR_REF_OPEN_START
:
2157 COMPUTE_NUM_ITEMS (extent_dst
,
2158 ref
->u
.a
.dim
[dst_dim
].s
.stride
,
2159 GFC_DIMENSION_LBOUND (dst
->dim
[dst_dim
]),
2160 ref
->u
.a
.dim
[dst_dim
].s
.end
);
2161 array_offset_dst
= 0;
2162 stride_dst
= GFC_DIMENSION_STRIDE (dst
->dim
[dst_dim
])
2163 * ref
->u
.a
.dim
[dst_dim
].s
.stride
;
2164 src_index
[src_dim
] = 0;
2165 for (index_type idx
= 0; idx
< extent_dst
; ++idx
)
2167 send_by_ref (ref
, i
, src_index
, single_token
, dst
, src
,
2168 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2169 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2173 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2174 array_offset_dst
+= stride_dst
;
2178 caf_runtime_error (unreachable
);
2181 case CAF_REF_STATIC_ARRAY
:
2182 if (ref
->u
.a
.mode
[dst_dim
] == CAF_ARR_REF_NONE
)
2184 send_by_ref (ref
->next
, i
, src_index
, single_token
, NULL
,
2185 src
, ds
, sr
, dst_kind
, src_kind
,
2186 0, src_dim
, 1, size
, stat
);
2189 switch (ref
->u
.a
.mode
[dst_dim
])
2191 case CAF_ARR_REF_VECTOR
:
2192 array_offset_dst
= 0;
2193 src_index
[src_dim
] = 0;
2194 for (size_t idx
= 0; idx
< ref
->u
.a
.dim
[dst_dim
].v
.nvec
;
2197 #define KINDCASE(kind, type) case kind: \
2198 array_offset_dst = ((type *)ref->u.a.dim[dst_dim].v.vector)[idx]; \
2201 switch (ref
->u
.a
.dim
[dst_dim
].v
.kind
)
2203 KINDCASE (1, GFC_INTEGER_1
);
2204 KINDCASE (2, GFC_INTEGER_2
);
2205 KINDCASE (4, GFC_INTEGER_4
);
2206 #ifdef HAVE_GFC_INTEGER_8
2207 KINDCASE (8, GFC_INTEGER_8
);
2209 #ifdef HAVE_GFC_INTEGER_16
2210 KINDCASE (16, GFC_INTEGER_16
);
2213 caf_runtime_error (unreachable
);
2218 send_by_ref (ref
, i
, src_index
, single_token
, NULL
, src
,
2219 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2220 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2223 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2226 case CAF_ARR_REF_FULL
:
2227 src_index
[src_dim
] = 0;
2228 for (array_offset_dst
= 0 ;
2229 array_offset_dst
<= ref
->u
.a
.dim
[dst_dim
].s
.end
;
2230 array_offset_dst
+= ref
->u
.a
.dim
[dst_dim
].s
.stride
)
2232 send_by_ref (ref
, i
, src_index
, single_token
, NULL
, src
,
2233 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2234 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2238 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2241 case CAF_ARR_REF_RANGE
:
2242 COMPUTE_NUM_ITEMS (extent_dst
,
2243 ref
->u
.a
.dim
[dst_dim
].s
.stride
,
2244 ref
->u
.a
.dim
[dst_dim
].s
.start
,
2245 ref
->u
.a
.dim
[dst_dim
].s
.end
);
2246 array_offset_dst
= ref
->u
.a
.dim
[dst_dim
].s
.start
;
2247 src_index
[src_dim
] = 0;
2248 for (index_type idx
= 0; idx
< extent_dst
; ++idx
)
2250 send_by_ref (ref
, i
, src_index
, single_token
, NULL
, src
,
2251 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2252 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
+ 1,
2256 += GFC_DIMENSION_STRIDE (src
->dim
[src_dim
]);
2257 array_offset_dst
+= ref
->u
.a
.dim
[dst_dim
].s
.stride
;
2260 case CAF_ARR_REF_SINGLE
:
2261 array_offset_dst
= ref
->u
.a
.dim
[dst_dim
].s
.start
;
2262 send_by_ref (ref
, i
, src_index
, single_token
, NULL
, src
,
2263 ds
+ array_offset_dst
* ref
->item_size
, sr
,
2264 dst_kind
, src_kind
, dst_dim
+ 1, src_dim
, 1,
2267 /* The OPEN_* are mapped to a RANGE and therefore can not occur. */
2268 case CAF_ARR_REF_OPEN_END
:
2269 case CAF_ARR_REF_OPEN_START
:
2271 caf_runtime_error (unreachable
);
2275 caf_runtime_error (unreachable
);
2281 _gfortran_caf_send_by_ref (caf_token_t token
,
2282 int image_index
__attribute__ ((unused
)),
2283 gfc_descriptor_t
*src
, caf_reference_t
*refs
,
2284 int dst_kind
, int src_kind
,
2285 bool may_require_tmp
__attribute__ ((unused
)),
2286 bool dst_reallocatable
, int *stat
)
2288 const char vecrefunknownkind
[] = "libcaf_single::caf_get_by_ref(): "
2289 "unknown kind in vector-ref.\n";
2290 const char unknownreftype
[] = "libcaf_single::caf_send_by_ref(): "
2291 "unknown reference type.\n";
2292 const char unknownarrreftype
[] = "libcaf_single::caf_send_by_ref(): "
2293 "unknown array reference type.\n";
2294 const char rankoutofrange
[] = "libcaf_single::caf_send_by_ref(): "
2295 "rank out of range.\n";
2296 const char realloconinnerref
[] = "libcaf_single::caf_send_by_ref(): "
2297 "reallocation of array followed by component ref not allowed.\n";
2298 const char cannotallocdst
[] = "libcaf_single::caf_send_by_ref(): "
2299 "can not allocate memory.\n";
2300 const char nonallocextentmismatch
[] = "libcaf_single::caf_send_by_ref(): "
2301 "extent of non-allocatable array mismatch.\n";
2302 const char innercompref
[] = "libcaf_single::caf_send_by_ref(): "
2303 "inner unallocated component detected.\n";
2305 size_t dst_index
[GFC_MAX_DIMENSIONS
];
2306 int src_rank
= GFC_DESCRIPTOR_RANK (src
);
2307 int src_cur_dim
= 0;
2309 caf_single_token_t single_token
= TOKEN (token
);
2310 void *memptr
= single_token
->memptr
;
2311 gfc_descriptor_t
*dst
= single_token
->desc
;
2312 caf_reference_t
*riter
= refs
;
2314 bool extent_mismatch
;
2315 /* Note that the component is not allocated yet. */
2316 index_type new_component_idx
= -1;
2321 /* Compute the size of the result. In the beginning size just counts the
2322 number of elements. */
2326 switch (riter
->type
)
2328 case CAF_REF_COMPONENT
:
2329 if (unlikely (new_component_idx
!= -1))
2331 /* Allocating a component in the middle of a component ref is not
2332 support. We don't know the type to allocate. */
2333 caf_internal_error (innercompref
, stat
, NULL
, 0);
2336 if (riter
->u
.c
.caf_token_offset
> 0)
2338 /* Check whether the allocatable component is zero, then no
2339 token is present, too. The token's pointer is not cleared
2340 when the structure is initialized. */
2341 if (*(void**)(memptr
+ riter
->u
.c
.offset
) == NULL
)
2343 /* This component is not yet allocated. Check that it is
2344 allocatable here. */
2345 if (!dst_reallocatable
)
2347 caf_internal_error (cannotallocdst
, stat
, NULL
, 0);
2350 single_token
= NULL
;
2355 single_token
= *(caf_single_token_t
*)
2356 (memptr
+ riter
->u
.c
.caf_token_offset
);
2357 memptr
+= riter
->u
.c
.offset
;
2358 dst
= single_token
->desc
;
2362 /* Regular component. */
2363 memptr
+= riter
->u
.c
.offset
;
2364 dst
= (gfc_descriptor_t
*)memptr
;
2369 memptr
= GFC_DESCRIPTOR_DATA (dst
);
2372 /* When the dst array needs to be allocated, then look at the
2373 extent of the source array in the dimension dst_cur_dim. */
2374 for (i
= 0; riter
->u
.a
.mode
[i
] != CAF_ARR_REF_NONE
; ++i
)
2376 switch (riter
->u
.a
.mode
[i
])
2378 case CAF_ARR_REF_VECTOR
:
2379 delta
= riter
->u
.a
.dim
[i
].v
.nvec
;
2380 #define KINDCASE(kind, type) case kind: \
2381 memptr += (((index_type) \
2382 ((type *)riter->u.a.dim[i].v.vector)[0]) \
2383 - GFC_DIMENSION_LBOUND (dst->dim[i])) \
2384 * GFC_DIMENSION_STRIDE (dst->dim[i]) \
2385 * riter->item_size; \
2388 switch (riter
->u
.a
.dim
[i
].v
.kind
)
2390 KINDCASE (1, GFC_INTEGER_1
);
2391 KINDCASE (2, GFC_INTEGER_2
);
2392 KINDCASE (4, GFC_INTEGER_4
);
2393 #ifdef HAVE_GFC_INTEGER_8
2394 KINDCASE (8, GFC_INTEGER_8
);
2396 #ifdef HAVE_GFC_INTEGER_16
2397 KINDCASE (16, GFC_INTEGER_16
);
2400 caf_internal_error (vecrefunknownkind
, stat
, NULL
, 0);
2405 case CAF_ARR_REF_FULL
:
2407 COMPUTE_NUM_ITEMS (delta
,
2408 riter
->u
.a
.dim
[i
].s
.stride
,
2409 GFC_DIMENSION_LBOUND (dst
->dim
[i
]),
2410 GFC_DIMENSION_UBOUND (dst
->dim
[i
]));
2412 COMPUTE_NUM_ITEMS (delta
,
2413 riter
->u
.a
.dim
[i
].s
.stride
,
2414 GFC_DIMENSION_LBOUND (src
->dim
[src_cur_dim
]),
2415 GFC_DIMENSION_UBOUND (src
->dim
[src_cur_dim
]));
2417 case CAF_ARR_REF_RANGE
:
2418 COMPUTE_NUM_ITEMS (delta
,
2419 riter
->u
.a
.dim
[i
].s
.stride
,
2420 riter
->u
.a
.dim
[i
].s
.start
,
2421 riter
->u
.a
.dim
[i
].s
.end
);
2422 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
2423 - dst
->dim
[i
].lower_bound
)
2424 * GFC_DIMENSION_STRIDE (dst
->dim
[i
])
2427 case CAF_ARR_REF_SINGLE
:
2429 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
2430 - dst
->dim
[i
].lower_bound
)
2431 * GFC_DIMENSION_STRIDE (dst
->dim
[i
])
2434 case CAF_ARR_REF_OPEN_END
:
2436 COMPUTE_NUM_ITEMS (delta
,
2437 riter
->u
.a
.dim
[i
].s
.stride
,
2438 riter
->u
.a
.dim
[i
].s
.start
,
2439 GFC_DIMENSION_UBOUND (dst
->dim
[i
]));
2441 COMPUTE_NUM_ITEMS (delta
,
2442 riter
->u
.a
.dim
[i
].s
.stride
,
2443 riter
->u
.a
.dim
[i
].s
.start
,
2444 GFC_DIMENSION_UBOUND (src
->dim
[src_cur_dim
]));
2445 memptr
+= (riter
->u
.a
.dim
[i
].s
.start
2446 - dst
->dim
[i
].lower_bound
)
2447 * GFC_DIMENSION_STRIDE (dst
->dim
[i
])
2450 case CAF_ARR_REF_OPEN_START
:
2452 COMPUTE_NUM_ITEMS (delta
,
2453 riter
->u
.a
.dim
[i
].s
.stride
,
2454 GFC_DIMENSION_LBOUND (dst
->dim
[i
]),
2455 riter
->u
.a
.dim
[i
].s
.end
);
2457 COMPUTE_NUM_ITEMS (delta
,
2458 riter
->u
.a
.dim
[i
].s
.stride
,
2459 GFC_DIMENSION_LBOUND (src
->dim
[src_cur_dim
]),
2460 riter
->u
.a
.dim
[i
].s
.end
);
2461 /* The memptr stays unchanged when ref'ing the first element
2465 caf_internal_error (unknownarrreftype
, stat
, NULL
, 0);
2471 /* Check the various properties of the source array.
2472 When src is an array. */
2473 if (delta
> 1 && src_rank
> 0)
2475 /* Check that src_cur_dim is valid for src. Can be
2476 superceeded only by scalar data. */
2477 if (src_cur_dim
>= src_rank
)
2479 caf_internal_error (rankoutofrange
, stat
, NULL
, 0);
2482 /* Do further checks, when the source is not scalar. */
2485 /* When the realloc is required, then no extent may have
2487 extent_mismatch
= memptr
== NULL
2489 && GFC_DESCRIPTOR_EXTENT (dst
, src_cur_dim
)
2491 /* When it already known, that a realloc is needed or
2492 the extent does not match the needed one. */
2493 if (extent_mismatch
)
2495 /* Check whether dst is reallocatable. */
2496 if (unlikely (!dst_reallocatable
))
2498 caf_internal_error (nonallocextentmismatch
, stat
,
2500 GFC_DESCRIPTOR_EXTENT (dst
,
2504 /* Report error on allocatable but missing inner
2506 else if (riter
->next
!= NULL
)
2508 caf_internal_error (realloconinnerref
, stat
, NULL
,
2513 /* Only change the extent when it does not match. This is
2514 to prevent resetting given array bounds. */
2515 if (extent_mismatch
)
2516 GFC_DIMENSION_SET (dst
->dim
[src_cur_dim
], 1, delta
,
2519 /* Increase the dim-counter of the src only when the extent
2521 if (src_cur_dim
< src_rank
2522 && GFC_DESCRIPTOR_EXTENT (src
, src_cur_dim
) == delta
)
2525 size
*= (index_type
)delta
;
2528 case CAF_REF_STATIC_ARRAY
:
2529 for (i
= 0; riter
->u
.a
.mode
[i
] != CAF_ARR_REF_NONE
; ++i
)
2531 switch (riter
->u
.a
.mode
[i
])
2533 case CAF_ARR_REF_VECTOR
:
2534 delta
= riter
->u
.a
.dim
[i
].v
.nvec
;
2535 #define KINDCASE(kind, type) case kind: \
2536 memptr += ((type *)riter->u.a.dim[i].v.vector)[0] \
2537 * riter->item_size; \
2540 switch (riter
->u
.a
.dim
[i
].v
.kind
)
2542 KINDCASE (1, GFC_INTEGER_1
);
2543 KINDCASE (2, GFC_INTEGER_2
);
2544 KINDCASE (4, GFC_INTEGER_4
);
2545 #ifdef HAVE_GFC_INTEGER_8
2546 KINDCASE (8, GFC_INTEGER_8
);
2548 #ifdef HAVE_GFC_INTEGER_16
2549 KINDCASE (16, GFC_INTEGER_16
);
2552 caf_internal_error (vecrefunknownkind
, stat
, NULL
, 0);
2557 case CAF_ARR_REF_FULL
:
2558 delta
= riter
->u
.a
.dim
[i
].s
.end
/ riter
->u
.a
.dim
[i
].s
.stride
2560 /* The memptr stays unchanged when ref'ing the first element
2563 case CAF_ARR_REF_RANGE
:
2564 COMPUTE_NUM_ITEMS (delta
,
2565 riter
->u
.a
.dim
[i
].s
.stride
,
2566 riter
->u
.a
.dim
[i
].s
.start
,
2567 riter
->u
.a
.dim
[i
].s
.end
);
2568 memptr
+= riter
->u
.a
.dim
[i
].s
.start
2569 * riter
->u
.a
.dim
[i
].s
.stride
2572 case CAF_ARR_REF_SINGLE
:
2574 memptr
+= riter
->u
.a
.dim
[i
].s
.start
2575 * riter
->u
.a
.dim
[i
].s
.stride
2578 case CAF_ARR_REF_OPEN_END
:
2579 /* This and OPEN_START are mapped to a RANGE and therefore
2580 can not occur here. */
2581 case CAF_ARR_REF_OPEN_START
:
2583 caf_internal_error (unknownarrreftype
, stat
, NULL
, 0);
2588 /* Check the various properties of the source array.
2589 Only when the source array is not scalar examine its
2591 if (delta
> 1 && src_rank
> 0)
2593 /* Check that src_cur_dim is valid for src. Can be
2594 superceeded only by scalar data. */
2595 if (src_cur_dim
>= src_rank
)
2597 caf_internal_error (rankoutofrange
, stat
, NULL
, 0);
2602 /* We will not be able to realloc the dst, because that's
2603 a fixed size array. */
2604 extent_mismatch
= GFC_DESCRIPTOR_EXTENT (src
, src_cur_dim
)
2606 /* When the extent does not match the needed one we can
2608 if (extent_mismatch
)
2610 caf_internal_error (nonallocextentmismatch
, stat
,
2612 GFC_DESCRIPTOR_EXTENT (src
,
2619 size
*= (index_type
)delta
;
2623 caf_internal_error (unknownreftype
, stat
, NULL
, 0);
2626 src_size
= riter
->item_size
;
2627 riter
= riter
->next
;
2629 if (size
== 0 || src_size
== 0)
2632 - size contains the number of elements to store in the destination array,
2633 - src_size gives the size in bytes of each item in the destination array.
2636 /* Reset the token. */
2637 single_token
= TOKEN (token
);
2638 memptr
= single_token
->memptr
;
2639 dst
= single_token
->desc
;
2640 memset (dst_index
, 0, sizeof (dst_index
));
2642 send_by_ref (refs
, &i
, dst_index
, single_token
, dst
, src
,
2643 memptr
, GFC_DESCRIPTOR_DATA (src
), dst_kind
, src_kind
, 0, 0,
2650 _gfortran_caf_sendget_by_ref (caf_token_t dst_token
, int dst_image_index
,
2651 caf_reference_t
*dst_refs
, caf_token_t src_token
,
2652 int src_image_index
,
2653 caf_reference_t
*src_refs
, int dst_kind
,
2654 int src_kind
, bool may_require_tmp
, int *dst_stat
,
2657 gfc_array_void temp
;
2659 _gfortran_caf_get_by_ref (src_token
, src_image_index
, &temp
, src_refs
,
2660 dst_kind
, src_kind
, may_require_tmp
, true,
2663 if (src_stat
&& *src_stat
!= 0)
2666 _gfortran_caf_send_by_ref (dst_token
, dst_image_index
, &temp
, dst_refs
,
2667 dst_kind
, src_kind
, may_require_tmp
, true,
2669 if (GFC_DESCRIPTOR_DATA (&temp
))
2670 free (GFC_DESCRIPTOR_DATA (&temp
));
2675 _gfortran_caf_atomic_define (caf_token_t token
, size_t offset
,
2676 int image_index
__attribute__ ((unused
)),
2677 void *value
, int *stat
,
2678 int type
__attribute__ ((unused
)), int kind
)
2682 uint32_t *atom
= (uint32_t *) ((char *) MEMTOK (token
) + offset
);
2684 __atomic_store (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
2691 _gfortran_caf_atomic_ref (caf_token_t token
, size_t offset
,
2692 int image_index
__attribute__ ((unused
)),
2693 void *value
, int *stat
,
2694 int type
__attribute__ ((unused
)), int kind
)
2698 uint32_t *atom
= (uint32_t *) ((char *) MEMTOK (token
) + offset
);
2700 __atomic_load (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
2708 _gfortran_caf_atomic_cas (caf_token_t token
, size_t offset
,
2709 int image_index
__attribute__ ((unused
)),
2710 void *old
, void *compare
, void *new_val
, int *stat
,
2711 int type
__attribute__ ((unused
)), int kind
)
2715 uint32_t *atom
= (uint32_t *) ((char *) MEMTOK (token
) + offset
);
2717 *(uint32_t *) old
= *(uint32_t *) compare
;
2718 (void) __atomic_compare_exchange_n (atom
, (uint32_t *) old
,
2719 *(uint32_t *) new_val
, false,
2720 __ATOMIC_RELAXED
, __ATOMIC_RELAXED
);
2727 _gfortran_caf_atomic_op (int op
, caf_token_t token
, size_t offset
,
2728 int image_index
__attribute__ ((unused
)),
2729 void *value
, void *old
, int *stat
,
2730 int type
__attribute__ ((unused
)), int kind
)
2735 uint32_t *atom
= (uint32_t *) ((char *) MEMTOK (token
) + offset
);
2739 case GFC_CAF_ATOMIC_ADD
:
2740 res
= __atomic_fetch_add (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
2742 case GFC_CAF_ATOMIC_AND
:
2743 res
= __atomic_fetch_and (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
2745 case GFC_CAF_ATOMIC_OR
:
2746 res
= __atomic_fetch_or (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
2748 case GFC_CAF_ATOMIC_XOR
:
2749 res
= __atomic_fetch_xor (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
2752 __builtin_unreachable();
2756 *(uint32_t *) old
= res
;
2763 _gfortran_caf_event_post (caf_token_t token
, size_t index
,
2764 int image_index
__attribute__ ((unused
)),
2765 int *stat
, char *errmsg
__attribute__ ((unused
)),
2766 int errmsg_len
__attribute__ ((unused
)))
2769 uint32_t *event
= (uint32_t *) ((char *) MEMTOK (token
) + index
2770 * sizeof (uint32_t));
2771 __atomic_fetch_add (event
, (uint32_t) value
, __ATOMIC_RELAXED
);
2778 _gfortran_caf_event_wait (caf_token_t token
, size_t index
,
2779 int until_count
, int *stat
,
2780 char *errmsg
__attribute__ ((unused
)),
2781 int errmsg_len
__attribute__ ((unused
)))
2783 uint32_t *event
= (uint32_t *) ((char *) MEMTOK (token
) + index
2784 * sizeof (uint32_t));
2785 uint32_t value
= (uint32_t)-until_count
;
2786 __atomic_fetch_add (event
, (uint32_t) value
, __ATOMIC_RELAXED
);
2793 _gfortran_caf_event_query (caf_token_t token
, size_t index
,
2794 int image_index
__attribute__ ((unused
)),
2795 int *count
, int *stat
)
2797 uint32_t *event
= (uint32_t *) ((char *) MEMTOK (token
) + index
2798 * sizeof (uint32_t));
2799 __atomic_load (event
, (uint32_t *) count
, __ATOMIC_RELAXED
);
2806 _gfortran_caf_lock (caf_token_t token
, size_t index
,
2807 int image_index
__attribute__ ((unused
)),
2808 int *aquired_lock
, int *stat
, char *errmsg
, int errmsg_len
)
2810 const char *msg
= "Already locked";
2811 bool *lock
= &((bool *) MEMTOK (token
))[index
];
2817 *aquired_lock
= (int) true;
2825 *aquired_lock
= (int) false;
2837 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
2838 : (int) sizeof (msg
);
2839 memcpy (errmsg
, msg
, len
);
2840 if (errmsg_len
> len
)
2841 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
2845 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));
2850 _gfortran_caf_unlock (caf_token_t token
, size_t index
,
2851 int image_index
__attribute__ ((unused
)),
2852 int *stat
, char *errmsg
, int errmsg_len
)
2854 const char *msg
= "Variable is not locked";
2855 bool *lock
= &((bool *) MEMTOK (token
))[index
];
2870 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
2871 : (int) sizeof (msg
);
2872 memcpy (errmsg
, msg
, len
);
2873 if (errmsg_len
> len
)
2874 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
2878 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));