1 1.1 mrg /* Single-image implementation of GNU Fortran Coarray Library 2 1.1.1.4 mrg Copyright (C) 2011-2024 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Tobias Burnus <burnus (at) net-b.de> 4 1.1 mrg 5 1.1 mrg This file is part of the GNU Fortran Coarray Runtime Library (libcaf). 6 1.1 mrg 7 1.1 mrg Libcaf is free software; you can redistribute it and/or modify 8 1.1 mrg it under the terms of the GNU General Public License as published by 9 1.1 mrg the Free Software Foundation; either version 3, or (at your option) 10 1.1 mrg any later version. 11 1.1 mrg 12 1.1 mrg Libcaf is distributed in the hope that it will be useful, 13 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 mrg GNU General Public License for more details. 16 1.1 mrg 17 1.1 mrg Under Section 7 of GPL version 3, you are granted additional 18 1.1 mrg permissions described in the GCC Runtime Library Exception, version 19 1.1 mrg 3.1, as published by the Free Software Foundation. 20 1.1 mrg 21 1.1 mrg You should have received a copy of the GNU General Public License and 22 1.1 mrg a copy of the GCC Runtime Library Exception along with this program; 23 1.1 mrg see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 1.1 mrg <http://www.gnu.org/licenses/>. */ 25 1.1 mrg 26 1.1 mrg #include "libcaf.h" 27 1.1 mrg #include <stdio.h> /* For fputs and fprintf. */ 28 1.1 mrg #include <stdlib.h> /* For exit and malloc. */ 29 1.1 mrg #include <string.h> /* For memcpy and memset. */ 30 1.1 mrg #include <stdarg.h> /* For variadic arguments. */ 31 1.1 mrg #include <stdint.h> 32 1.1 mrg #include <assert.h> 33 1.1 mrg 34 1.1 mrg /* Define GFC_CAF_CHECK to enable run-time checking. */ 35 1.1 mrg /* #define GFC_CAF_CHECK 1 */ 36 1.1 mrg 37 1.1 mrg struct caf_single_token 38 1.1 mrg { 39 1.1 mrg /* The pointer to the memory registered. For arrays this is the data member 40 1.1 mrg in the descriptor. For components it's the pure data pointer. */ 41 1.1 mrg void *memptr; 42 1.1 mrg /* The descriptor when this token is associated to an allocatable array. */ 43 1.1 mrg gfc_descriptor_t *desc; 44 1.1 mrg /* Set when the caf lib has allocated the memory in memptr and is responsible 45 1.1 mrg for freeing it on deregister. */ 46 1.1 mrg bool owning_memory; 47 1.1 mrg }; 48 1.1 mrg typedef struct caf_single_token *caf_single_token_t; 49 1.1 mrg 50 1.1 mrg #define TOKEN(X) ((caf_single_token_t) (X)) 51 1.1 mrg #define MEMTOK(X) ((caf_single_token_t) (X))->memptr 52 1.1 mrg 53 1.1 mrg /* Single-image implementation of the CAF library. 54 1.1 mrg Note: For performance reasons -fcoarry=single should be used 55 1.1 mrg rather than this library. */ 56 1.1 mrg 57 1.1 mrg /* Global variables. */ 58 1.1 mrg caf_static_t *caf_static_list = NULL; 59 1.1 mrg 60 1.1 mrg /* Keep in sync with mpi.c. */ 61 1.1 mrg static void 62 1.1 mrg caf_runtime_error (const char *message, ...) 63 1.1 mrg { 64 1.1 mrg va_list ap; 65 1.1 mrg fprintf (stderr, "Fortran runtime error: "); 66 1.1 mrg va_start (ap, message); 67 1.1 mrg vfprintf (stderr, message, ap); 68 1.1 mrg va_end (ap); 69 1.1 mrg fprintf (stderr, "\n"); 70 1.1 mrg 71 1.1 mrg /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */ 72 1.1 mrg exit (EXIT_FAILURE); 73 1.1 mrg } 74 1.1 mrg 75 1.1 mrg /* Error handling is similar everytime. */ 76 1.1 mrg static void 77 1.1 mrg caf_internal_error (const char *msg, int *stat, char *errmsg, 78 1.1 mrg size_t errmsg_len, ...) 79 1.1 mrg { 80 1.1 mrg va_list args; 81 1.1 mrg va_start (args, errmsg_len); 82 1.1 mrg if (stat) 83 1.1 mrg { 84 1.1 mrg *stat = 1; 85 1.1 mrg if (errmsg_len > 0) 86 1.1 mrg { 87 1.1 mrg int len = snprintf (errmsg, errmsg_len, msg, args); 88 1.1 mrg if (len >= 0 && errmsg_len > (size_t) len) 89 1.1 mrg memset (&errmsg[len], ' ', errmsg_len - len); 90 1.1 mrg } 91 1.1 mrg va_end (args); 92 1.1 mrg return; 93 1.1 mrg } 94 1.1 mrg else 95 1.1 mrg caf_runtime_error (msg, args); 96 1.1 mrg va_end (args); 97 1.1 mrg } 98 1.1 mrg 99 1.1 mrg 100 1.1 mrg void 101 1.1 mrg _gfortran_caf_init (int *argc __attribute__ ((unused)), 102 1.1 mrg char ***argv __attribute__ ((unused))) 103 1.1 mrg { 104 1.1 mrg } 105 1.1 mrg 106 1.1 mrg 107 1.1 mrg void 108 1.1 mrg _gfortran_caf_finalize (void) 109 1.1 mrg { 110 1.1 mrg while (caf_static_list != NULL) 111 1.1 mrg { 112 1.1 mrg caf_static_t *tmp = caf_static_list->prev; 113 1.1 mrg free (caf_static_list->token); 114 1.1 mrg free (caf_static_list); 115 1.1 mrg caf_static_list = tmp; 116 1.1 mrg } 117 1.1 mrg } 118 1.1 mrg 119 1.1 mrg 120 1.1 mrg int 121 1.1 mrg _gfortran_caf_this_image (int distance __attribute__ ((unused))) 122 1.1 mrg { 123 1.1 mrg return 1; 124 1.1 mrg } 125 1.1 mrg 126 1.1 mrg 127 1.1 mrg int 128 1.1 mrg _gfortran_caf_num_images (int distance __attribute__ ((unused)), 129 1.1 mrg int failed __attribute__ ((unused))) 130 1.1 mrg { 131 1.1 mrg return 1; 132 1.1 mrg } 133 1.1 mrg 134 1.1 mrg 135 1.1 mrg void 136 1.1 mrg _gfortran_caf_register (size_t size, caf_register_t type, caf_token_t *token, 137 1.1 mrg gfc_descriptor_t *data, int *stat, char *errmsg, 138 1.1 mrg size_t errmsg_len) 139 1.1 mrg { 140 1.1 mrg const char alloc_fail_msg[] = "Failed to allocate coarray"; 141 1.1 mrg void *local; 142 1.1 mrg caf_single_token_t single_token; 143 1.1 mrg 144 1.1 mrg if (type == CAF_REGTYPE_LOCK_STATIC || type == CAF_REGTYPE_LOCK_ALLOC 145 1.1 mrg || type == CAF_REGTYPE_CRITICAL) 146 1.1 mrg local = calloc (size, sizeof (bool)); 147 1.1 mrg else if (type == CAF_REGTYPE_EVENT_STATIC || type == CAF_REGTYPE_EVENT_ALLOC) 148 1.1 mrg /* In the event_(wait|post) function the counter for events is a uint32, 149 1.1 mrg so better allocate enough memory here. */ 150 1.1 mrg local = calloc (size, sizeof (uint32_t)); 151 1.1 mrg else if (type == CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY) 152 1.1 mrg local = NULL; 153 1.1 mrg else 154 1.1 mrg local = malloc (size); 155 1.1 mrg 156 1.1 mrg if (type != CAF_REGTYPE_COARRAY_ALLOC_ALLOCATE_ONLY) 157 1.1 mrg *token = malloc (sizeof (struct caf_single_token)); 158 1.1 mrg 159 1.1 mrg if (unlikely (*token == NULL 160 1.1 mrg || (local == NULL 161 1.1 mrg && type != CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY))) 162 1.1 mrg { 163 1.1 mrg /* Freeing the memory conditionally seems pointless, but 164 1.1 mrg caf_internal_error () may return, when a stat is given and then the 165 1.1 mrg memory may be lost. */ 166 1.1.1.4 mrg free (local); 167 1.1.1.4 mrg free (*token); 168 1.1 mrg caf_internal_error (alloc_fail_msg, stat, errmsg, errmsg_len); 169 1.1 mrg return; 170 1.1 mrg } 171 1.1 mrg 172 1.1 mrg single_token = TOKEN (*token); 173 1.1 mrg single_token->memptr = local; 174 1.1 mrg single_token->owning_memory = type != CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY; 175 1.1 mrg single_token->desc = GFC_DESCRIPTOR_RANK (data) > 0 ? data : NULL; 176 1.1 mrg 177 1.1 mrg 178 1.1 mrg if (stat) 179 1.1 mrg *stat = 0; 180 1.1 mrg 181 1.1 mrg if (type == CAF_REGTYPE_COARRAY_STATIC || type == CAF_REGTYPE_LOCK_STATIC 182 1.1 mrg || type == CAF_REGTYPE_CRITICAL || type == CAF_REGTYPE_EVENT_STATIC 183 1.1 mrg || type == CAF_REGTYPE_EVENT_ALLOC) 184 1.1 mrg { 185 1.1 mrg caf_static_t *tmp = malloc (sizeof (caf_static_t)); 186 1.1 mrg tmp->prev = caf_static_list; 187 1.1 mrg tmp->token = *token; 188 1.1 mrg caf_static_list = tmp; 189 1.1 mrg } 190 1.1 mrg GFC_DESCRIPTOR_DATA (data) = local; 191 1.1 mrg } 192 1.1 mrg 193 1.1 mrg 194 1.1 mrg void 195 1.1 mrg _gfortran_caf_deregister (caf_token_t *token, caf_deregister_t type, int *stat, 196 1.1 mrg char *errmsg __attribute__ ((unused)), 197 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 198 1.1 mrg { 199 1.1 mrg caf_single_token_t single_token = TOKEN (*token); 200 1.1 mrg 201 1.1 mrg if (single_token->owning_memory && single_token->memptr) 202 1.1 mrg free (single_token->memptr); 203 1.1 mrg 204 1.1 mrg if (type != CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY) 205 1.1 mrg { 206 1.1 mrg free (TOKEN (*token)); 207 1.1 mrg *token = NULL; 208 1.1 mrg } 209 1.1 mrg else 210 1.1 mrg { 211 1.1 mrg single_token->memptr = NULL; 212 1.1 mrg single_token->owning_memory = false; 213 1.1 mrg } 214 1.1 mrg 215 1.1 mrg if (stat) 216 1.1 mrg *stat = 0; 217 1.1 mrg } 218 1.1 mrg 219 1.1 mrg 220 1.1 mrg void 221 1.1 mrg _gfortran_caf_sync_all (int *stat, 222 1.1 mrg char *errmsg __attribute__ ((unused)), 223 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 224 1.1 mrg { 225 1.1 mrg __asm__ __volatile__ ("":::"memory"); 226 1.1 mrg if (stat) 227 1.1 mrg *stat = 0; 228 1.1 mrg } 229 1.1 mrg 230 1.1 mrg 231 1.1 mrg void 232 1.1 mrg _gfortran_caf_sync_memory (int *stat, 233 1.1 mrg char *errmsg __attribute__ ((unused)), 234 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 235 1.1 mrg { 236 1.1 mrg __asm__ __volatile__ ("":::"memory"); 237 1.1 mrg if (stat) 238 1.1 mrg *stat = 0; 239 1.1 mrg } 240 1.1 mrg 241 1.1 mrg 242 1.1 mrg void 243 1.1 mrg _gfortran_caf_sync_images (int count __attribute__ ((unused)), 244 1.1 mrg int images[] __attribute__ ((unused)), 245 1.1 mrg int *stat, 246 1.1 mrg char *errmsg __attribute__ ((unused)), 247 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 248 1.1 mrg { 249 1.1 mrg #ifdef GFC_CAF_CHECK 250 1.1 mrg int i; 251 1.1 mrg 252 1.1 mrg for (i = 0; i < count; i++) 253 1.1 mrg if (images[i] != 1) 254 1.1 mrg { 255 1.1 mrg fprintf (stderr, "COARRAY ERROR: Invalid image index %d to SYNC " 256 1.1 mrg "IMAGES", images[i]); 257 1.1 mrg exit (EXIT_FAILURE); 258 1.1 mrg } 259 1.1 mrg #endif 260 1.1 mrg 261 1.1 mrg __asm__ __volatile__ ("":::"memory"); 262 1.1 mrg if (stat) 263 1.1 mrg *stat = 0; 264 1.1 mrg } 265 1.1 mrg 266 1.1 mrg 267 1.1 mrg void 268 1.1 mrg _gfortran_caf_stop_numeric(int stop_code, bool quiet) 269 1.1 mrg { 270 1.1 mrg if (!quiet) 271 1.1 mrg fprintf (stderr, "STOP %d\n", stop_code); 272 1.1 mrg exit (0); 273 1.1 mrg } 274 1.1 mrg 275 1.1 mrg 276 1.1 mrg void 277 1.1 mrg _gfortran_caf_stop_str(const char *string, size_t len, bool quiet) 278 1.1 mrg { 279 1.1 mrg if (!quiet) 280 1.1 mrg { 281 1.1 mrg fputs ("STOP ", stderr); 282 1.1 mrg while (len--) 283 1.1 mrg fputc (*(string++), stderr); 284 1.1 mrg fputs ("\n", stderr); 285 1.1 mrg } 286 1.1 mrg exit (0); 287 1.1 mrg } 288 1.1 mrg 289 1.1 mrg 290 1.1 mrg void 291 1.1 mrg _gfortran_caf_error_stop_str (const char *string, size_t len, bool quiet) 292 1.1 mrg { 293 1.1 mrg if (!quiet) 294 1.1 mrg { 295 1.1 mrg fputs ("ERROR STOP ", stderr); 296 1.1 mrg while (len--) 297 1.1 mrg fputc (*(string++), stderr); 298 1.1 mrg fputs ("\n", stderr); 299 1.1 mrg } 300 1.1 mrg exit (1); 301 1.1 mrg } 302 1.1 mrg 303 1.1 mrg 304 1.1 mrg /* Reported that the program terminated because of a fail image issued. 305 1.1 mrg Because this is a single image library, nothing else than aborting the whole 306 1.1 mrg program can be done. */ 307 1.1 mrg 308 1.1 mrg void _gfortran_caf_fail_image (void) 309 1.1 mrg { 310 1.1 mrg fputs ("IMAGE FAILED!\n", stderr); 311 1.1 mrg exit (0); 312 1.1 mrg } 313 1.1 mrg 314 1.1 mrg 315 1.1 mrg /* Get the status of image IMAGE. Because being the single image library all 316 1.1 mrg other images are reported to be stopped. */ 317 1.1 mrg 318 1.1 mrg int _gfortran_caf_image_status (int image, 319 1.1 mrg caf_team_t * team __attribute__ ((unused))) 320 1.1 mrg { 321 1.1 mrg if (image == 1) 322 1.1 mrg return 0; 323 1.1 mrg else 324 1.1 mrg return CAF_STAT_STOPPED_IMAGE; 325 1.1 mrg } 326 1.1 mrg 327 1.1 mrg 328 1.1 mrg /* Single image library. There cannot be any failed images with only one 329 1.1 mrg image. */ 330 1.1 mrg 331 1.1 mrg void 332 1.1 mrg _gfortran_caf_failed_images (gfc_descriptor_t *array, 333 1.1 mrg caf_team_t * team __attribute__ ((unused)), 334 1.1 mrg int * kind) 335 1.1 mrg { 336 1.1 mrg int local_kind = kind != NULL ? *kind : 4; 337 1.1 mrg 338 1.1 mrg array->base_addr = NULL; 339 1.1 mrg array->dtype.type = BT_INTEGER; 340 1.1 mrg array->dtype.elem_len = local_kind; 341 1.1 mrg /* Setting lower_bound higher then upper_bound is what the compiler does to 342 1.1 mrg indicate an empty array. */ 343 1.1 mrg array->dim[0].lower_bound = 0; 344 1.1 mrg array->dim[0]._ubound = -1; 345 1.1 mrg array->dim[0]._stride = 1; 346 1.1 mrg array->offset = 0; 347 1.1 mrg } 348 1.1 mrg 349 1.1 mrg 350 1.1 mrg /* With only one image available no other images can be stopped. Therefore 351 1.1 mrg return an empty array. */ 352 1.1 mrg 353 1.1 mrg void 354 1.1 mrg _gfortran_caf_stopped_images (gfc_descriptor_t *array, 355 1.1 mrg caf_team_t * team __attribute__ ((unused)), 356 1.1 mrg int * kind) 357 1.1 mrg { 358 1.1 mrg int local_kind = kind != NULL ? *kind : 4; 359 1.1 mrg 360 1.1 mrg array->base_addr = NULL; 361 1.1 mrg array->dtype.type = BT_INTEGER; 362 1.1 mrg array->dtype.elem_len = local_kind; 363 1.1 mrg /* Setting lower_bound higher then upper_bound is what the compiler does to 364 1.1 mrg indicate an empty array. */ 365 1.1 mrg array->dim[0].lower_bound = 0; 366 1.1 mrg array->dim[0]._ubound = -1; 367 1.1 mrg array->dim[0]._stride = 1; 368 1.1 mrg array->offset = 0; 369 1.1 mrg } 370 1.1 mrg 371 1.1 mrg 372 1.1 mrg void 373 1.1 mrg _gfortran_caf_error_stop (int error, bool quiet) 374 1.1 mrg { 375 1.1 mrg if (!quiet) 376 1.1 mrg fprintf (stderr, "ERROR STOP %d\n", error); 377 1.1 mrg exit (error); 378 1.1 mrg } 379 1.1 mrg 380 1.1 mrg 381 1.1 mrg void 382 1.1 mrg _gfortran_caf_co_broadcast (gfc_descriptor_t *a __attribute__ ((unused)), 383 1.1 mrg int source_image __attribute__ ((unused)), 384 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 385 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 386 1.1 mrg { 387 1.1 mrg if (stat) 388 1.1 mrg *stat = 0; 389 1.1 mrg } 390 1.1 mrg 391 1.1 mrg void 392 1.1 mrg _gfortran_caf_co_sum (gfc_descriptor_t *a __attribute__ ((unused)), 393 1.1 mrg int result_image __attribute__ ((unused)), 394 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 395 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 396 1.1 mrg { 397 1.1 mrg if (stat) 398 1.1 mrg *stat = 0; 399 1.1 mrg } 400 1.1 mrg 401 1.1 mrg void 402 1.1 mrg _gfortran_caf_co_min (gfc_descriptor_t *a __attribute__ ((unused)), 403 1.1 mrg int result_image __attribute__ ((unused)), 404 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 405 1.1 mrg int a_len __attribute__ ((unused)), 406 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 407 1.1 mrg { 408 1.1 mrg if (stat) 409 1.1 mrg *stat = 0; 410 1.1 mrg } 411 1.1 mrg 412 1.1 mrg void 413 1.1 mrg _gfortran_caf_co_max (gfc_descriptor_t *a __attribute__ ((unused)), 414 1.1 mrg int result_image __attribute__ ((unused)), 415 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 416 1.1 mrg int a_len __attribute__ ((unused)), 417 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 418 1.1 mrg { 419 1.1 mrg if (stat) 420 1.1 mrg *stat = 0; 421 1.1 mrg } 422 1.1 mrg 423 1.1 mrg 424 1.1 mrg void 425 1.1 mrg _gfortran_caf_co_reduce (gfc_descriptor_t *a __attribute__ ((unused)), 426 1.1 mrg void * (*opr) (void *, void *) 427 1.1 mrg __attribute__ ((unused)), 428 1.1 mrg int opr_flags __attribute__ ((unused)), 429 1.1 mrg int result_image __attribute__ ((unused)), 430 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 431 1.1 mrg int a_len __attribute__ ((unused)), 432 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 433 1.1 mrg { 434 1.1 mrg if (stat) 435 1.1 mrg *stat = 0; 436 1.1 mrg } 437 1.1 mrg 438 1.1 mrg 439 1.1 mrg static void 440 1.1 mrg assign_char4_from_char1 (size_t dst_size, size_t src_size, uint32_t *dst, 441 1.1 mrg unsigned char *src) 442 1.1 mrg { 443 1.1 mrg size_t i, n; 444 1.1 mrg n = dst_size/4 > src_size ? src_size : dst_size/4; 445 1.1 mrg for (i = 0; i < n; ++i) 446 1.1 mrg dst[i] = (int32_t) src[i]; 447 1.1 mrg for (; i < dst_size/4; ++i) 448 1.1 mrg dst[i] = (int32_t) ' '; 449 1.1 mrg } 450 1.1 mrg 451 1.1 mrg 452 1.1 mrg static void 453 1.1 mrg assign_char1_from_char4 (size_t dst_size, size_t src_size, unsigned char *dst, 454 1.1 mrg uint32_t *src) 455 1.1 mrg { 456 1.1 mrg size_t i, n; 457 1.1 mrg n = dst_size > src_size/4 ? src_size/4 : dst_size; 458 1.1 mrg for (i = 0; i < n; ++i) 459 1.1 mrg dst[i] = src[i] > UINT8_MAX ? (unsigned char) '?' : (unsigned char) src[i]; 460 1.1 mrg if (dst_size > n) 461 1.1 mrg memset (&dst[n], ' ', dst_size - n); 462 1.1 mrg } 463 1.1 mrg 464 1.1 mrg 465 1.1 mrg static void 466 1.1 mrg convert_type (void *dst, int dst_type, int dst_kind, void *src, int src_type, 467 1.1 mrg int src_kind, int *stat) 468 1.1 mrg { 469 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 470 1.1 mrg typedef __int128 int128t; 471 1.1 mrg #else 472 1.1 mrg typedef int64_t int128t; 473 1.1 mrg #endif 474 1.1 mrg 475 1.1 mrg #if defined(GFC_REAL_16_IS_LONG_DOUBLE) 476 1.1 mrg typedef long double real128t; 477 1.1 mrg typedef _Complex long double complex128t; 478 1.1 mrg #elif defined(HAVE_GFC_REAL_16) 479 1.1.1.4 mrg typedef _Float128 real128t; 480 1.1.1.4 mrg typedef _Complex _Float128 complex128t; 481 1.1 mrg #elif defined(HAVE_GFC_REAL_10) 482 1.1 mrg typedef long double real128t; 483 1.1.1.4 mrg typedef _Complex long double complex128t; 484 1.1 mrg #else 485 1.1 mrg typedef double real128t; 486 1.1 mrg typedef _Complex double complex128t; 487 1.1 mrg #endif 488 1.1 mrg 489 1.1 mrg int128t int_val = 0; 490 1.1 mrg real128t real_val = 0; 491 1.1 mrg complex128t cmpx_val = 0; 492 1.1 mrg 493 1.1 mrg switch (src_type) 494 1.1 mrg { 495 1.1 mrg case BT_INTEGER: 496 1.1 mrg if (src_kind == 1) 497 1.1 mrg int_val = *(int8_t*) src; 498 1.1 mrg else if (src_kind == 2) 499 1.1 mrg int_val = *(int16_t*) src; 500 1.1 mrg else if (src_kind == 4) 501 1.1 mrg int_val = *(int32_t*) src; 502 1.1 mrg else if (src_kind == 8) 503 1.1 mrg int_val = *(int64_t*) src; 504 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 505 1.1 mrg else if (src_kind == 16) 506 1.1 mrg int_val = *(int128t*) src; 507 1.1 mrg #endif 508 1.1 mrg else 509 1.1 mrg goto error; 510 1.1 mrg break; 511 1.1 mrg case BT_REAL: 512 1.1 mrg if (src_kind == 4) 513 1.1 mrg real_val = *(float*) src; 514 1.1 mrg else if (src_kind == 8) 515 1.1 mrg real_val = *(double*) src; 516 1.1 mrg #ifdef HAVE_GFC_REAL_10 517 1.1 mrg else if (src_kind == 10) 518 1.1 mrg real_val = *(long double*) src; 519 1.1 mrg #endif 520 1.1 mrg #ifdef HAVE_GFC_REAL_16 521 1.1 mrg else if (src_kind == 16) 522 1.1 mrg real_val = *(real128t*) src; 523 1.1 mrg #endif 524 1.1 mrg else 525 1.1 mrg goto error; 526 1.1 mrg break; 527 1.1 mrg case BT_COMPLEX: 528 1.1 mrg if (src_kind == 4) 529 1.1 mrg cmpx_val = *(_Complex float*) src; 530 1.1 mrg else if (src_kind == 8) 531 1.1 mrg cmpx_val = *(_Complex double*) src; 532 1.1 mrg #ifdef HAVE_GFC_REAL_10 533 1.1 mrg else if (src_kind == 10) 534 1.1 mrg cmpx_val = *(_Complex long double*) src; 535 1.1 mrg #endif 536 1.1 mrg #ifdef HAVE_GFC_REAL_16 537 1.1 mrg else if (src_kind == 16) 538 1.1 mrg cmpx_val = *(complex128t*) src; 539 1.1 mrg #endif 540 1.1 mrg else 541 1.1 mrg goto error; 542 1.1 mrg break; 543 1.1 mrg default: 544 1.1 mrg goto error; 545 1.1 mrg } 546 1.1 mrg 547 1.1 mrg switch (dst_type) 548 1.1 mrg { 549 1.1 mrg case BT_INTEGER: 550 1.1 mrg if (src_type == BT_INTEGER) 551 1.1 mrg { 552 1.1 mrg if (dst_kind == 1) 553 1.1 mrg *(int8_t*) dst = (int8_t) int_val; 554 1.1 mrg else if (dst_kind == 2) 555 1.1 mrg *(int16_t*) dst = (int16_t) int_val; 556 1.1 mrg else if (dst_kind == 4) 557 1.1 mrg *(int32_t*) dst = (int32_t) int_val; 558 1.1 mrg else if (dst_kind == 8) 559 1.1 mrg *(int64_t*) dst = (int64_t) int_val; 560 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 561 1.1 mrg else if (dst_kind == 16) 562 1.1 mrg *(int128t*) dst = (int128t) int_val; 563 1.1 mrg #endif 564 1.1 mrg else 565 1.1 mrg goto error; 566 1.1 mrg } 567 1.1 mrg else if (src_type == BT_REAL) 568 1.1 mrg { 569 1.1 mrg if (dst_kind == 1) 570 1.1 mrg *(int8_t*) dst = (int8_t) real_val; 571 1.1 mrg else if (dst_kind == 2) 572 1.1 mrg *(int16_t*) dst = (int16_t) real_val; 573 1.1 mrg else if (dst_kind == 4) 574 1.1 mrg *(int32_t*) dst = (int32_t) real_val; 575 1.1 mrg else if (dst_kind == 8) 576 1.1 mrg *(int64_t*) dst = (int64_t) real_val; 577 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 578 1.1 mrg else if (dst_kind == 16) 579 1.1 mrg *(int128t*) dst = (int128t) real_val; 580 1.1 mrg #endif 581 1.1 mrg else 582 1.1 mrg goto error; 583 1.1 mrg } 584 1.1 mrg else if (src_type == BT_COMPLEX) 585 1.1 mrg { 586 1.1 mrg if (dst_kind == 1) 587 1.1 mrg *(int8_t*) dst = (int8_t) cmpx_val; 588 1.1 mrg else if (dst_kind == 2) 589 1.1 mrg *(int16_t*) dst = (int16_t) cmpx_val; 590 1.1 mrg else if (dst_kind == 4) 591 1.1 mrg *(int32_t*) dst = (int32_t) cmpx_val; 592 1.1 mrg else if (dst_kind == 8) 593 1.1 mrg *(int64_t*) dst = (int64_t) cmpx_val; 594 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 595 1.1 mrg else if (dst_kind == 16) 596 1.1 mrg *(int128t*) dst = (int128t) cmpx_val; 597 1.1 mrg #endif 598 1.1 mrg else 599 1.1 mrg goto error; 600 1.1 mrg } 601 1.1 mrg else 602 1.1 mrg goto error; 603 1.1 mrg return; 604 1.1 mrg case BT_REAL: 605 1.1 mrg if (src_type == BT_INTEGER) 606 1.1 mrg { 607 1.1 mrg if (dst_kind == 4) 608 1.1 mrg *(float*) dst = (float) int_val; 609 1.1 mrg else if (dst_kind == 8) 610 1.1 mrg *(double*) dst = (double) int_val; 611 1.1 mrg #ifdef HAVE_GFC_REAL_10 612 1.1 mrg else if (dst_kind == 10) 613 1.1 mrg *(long double*) dst = (long double) int_val; 614 1.1 mrg #endif 615 1.1 mrg #ifdef HAVE_GFC_REAL_16 616 1.1 mrg else if (dst_kind == 16) 617 1.1 mrg *(real128t*) dst = (real128t) int_val; 618 1.1 mrg #endif 619 1.1 mrg else 620 1.1 mrg goto error; 621 1.1 mrg } 622 1.1 mrg else if (src_type == BT_REAL) 623 1.1 mrg { 624 1.1 mrg if (dst_kind == 4) 625 1.1 mrg *(float*) dst = (float) real_val; 626 1.1 mrg else if (dst_kind == 8) 627 1.1 mrg *(double*) dst = (double) real_val; 628 1.1 mrg #ifdef HAVE_GFC_REAL_10 629 1.1 mrg else if (dst_kind == 10) 630 1.1 mrg *(long double*) dst = (long double) real_val; 631 1.1 mrg #endif 632 1.1 mrg #ifdef HAVE_GFC_REAL_16 633 1.1 mrg else if (dst_kind == 16) 634 1.1 mrg *(real128t*) dst = (real128t) real_val; 635 1.1 mrg #endif 636 1.1 mrg else 637 1.1 mrg goto error; 638 1.1 mrg } 639 1.1 mrg else if (src_type == BT_COMPLEX) 640 1.1 mrg { 641 1.1 mrg if (dst_kind == 4) 642 1.1 mrg *(float*) dst = (float) cmpx_val; 643 1.1 mrg else if (dst_kind == 8) 644 1.1 mrg *(double*) dst = (double) cmpx_val; 645 1.1 mrg #ifdef HAVE_GFC_REAL_10 646 1.1 mrg else if (dst_kind == 10) 647 1.1 mrg *(long double*) dst = (long double) cmpx_val; 648 1.1 mrg #endif 649 1.1 mrg #ifdef HAVE_GFC_REAL_16 650 1.1 mrg else if (dst_kind == 16) 651 1.1 mrg *(real128t*) dst = (real128t) cmpx_val; 652 1.1 mrg #endif 653 1.1 mrg else 654 1.1 mrg goto error; 655 1.1 mrg } 656 1.1 mrg return; 657 1.1 mrg case BT_COMPLEX: 658 1.1 mrg if (src_type == BT_INTEGER) 659 1.1 mrg { 660 1.1 mrg if (dst_kind == 4) 661 1.1 mrg *(_Complex float*) dst = (_Complex float) int_val; 662 1.1 mrg else if (dst_kind == 8) 663 1.1 mrg *(_Complex double*) dst = (_Complex double) int_val; 664 1.1 mrg #ifdef HAVE_GFC_REAL_10 665 1.1 mrg else if (dst_kind == 10) 666 1.1 mrg *(_Complex long double*) dst = (_Complex long double) int_val; 667 1.1 mrg #endif 668 1.1 mrg #ifdef HAVE_GFC_REAL_16 669 1.1 mrg else if (dst_kind == 16) 670 1.1 mrg *(complex128t*) dst = (complex128t) int_val; 671 1.1 mrg #endif 672 1.1 mrg else 673 1.1 mrg goto error; 674 1.1 mrg } 675 1.1 mrg else if (src_type == BT_REAL) 676 1.1 mrg { 677 1.1 mrg if (dst_kind == 4) 678 1.1 mrg *(_Complex float*) dst = (_Complex float) real_val; 679 1.1 mrg else if (dst_kind == 8) 680 1.1 mrg *(_Complex double*) dst = (_Complex double) real_val; 681 1.1 mrg #ifdef HAVE_GFC_REAL_10 682 1.1 mrg else if (dst_kind == 10) 683 1.1 mrg *(_Complex long double*) dst = (_Complex long double) real_val; 684 1.1 mrg #endif 685 1.1 mrg #ifdef HAVE_GFC_REAL_16 686 1.1 mrg else if (dst_kind == 16) 687 1.1 mrg *(complex128t*) dst = (complex128t) real_val; 688 1.1 mrg #endif 689 1.1 mrg else 690 1.1 mrg goto error; 691 1.1 mrg } 692 1.1 mrg else if (src_type == BT_COMPLEX) 693 1.1 mrg { 694 1.1 mrg if (dst_kind == 4) 695 1.1 mrg *(_Complex float*) dst = (_Complex float) cmpx_val; 696 1.1 mrg else if (dst_kind == 8) 697 1.1 mrg *(_Complex double*) dst = (_Complex double) cmpx_val; 698 1.1 mrg #ifdef HAVE_GFC_REAL_10 699 1.1 mrg else if (dst_kind == 10) 700 1.1 mrg *(_Complex long double*) dst = (_Complex long double) cmpx_val; 701 1.1 mrg #endif 702 1.1 mrg #ifdef HAVE_GFC_REAL_16 703 1.1 mrg else if (dst_kind == 16) 704 1.1 mrg *(complex128t*) dst = (complex128t) cmpx_val; 705 1.1 mrg #endif 706 1.1 mrg else 707 1.1 mrg goto error; 708 1.1 mrg } 709 1.1 mrg else 710 1.1 mrg goto error; 711 1.1 mrg return; 712 1.1 mrg default: 713 1.1 mrg goto error; 714 1.1 mrg } 715 1.1 mrg 716 1.1 mrg error: 717 1.1 mrg fprintf (stderr, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind " 718 1.1 mrg "%d to type %d kind %d\n", src_type, src_kind, dst_type, dst_kind); 719 1.1 mrg if (stat) 720 1.1 mrg *stat = 1; 721 1.1 mrg else 722 1.1 mrg abort (); 723 1.1 mrg } 724 1.1 mrg 725 1.1 mrg 726 1.1 mrg void 727 1.1 mrg _gfortran_caf_get (caf_token_t token, size_t offset, 728 1.1 mrg int image_index __attribute__ ((unused)), 729 1.1 mrg gfc_descriptor_t *src, 730 1.1 mrg caf_vector_t *src_vector __attribute__ ((unused)), 731 1.1 mrg gfc_descriptor_t *dest, int src_kind, int dst_kind, 732 1.1 mrg bool may_require_tmp, int *stat) 733 1.1 mrg { 734 1.1 mrg /* FIXME: Handle vector subscripts. */ 735 1.1 mrg size_t i, k, size; 736 1.1 mrg int j; 737 1.1 mrg int rank = GFC_DESCRIPTOR_RANK (dest); 738 1.1 mrg size_t src_size = GFC_DESCRIPTOR_SIZE (src); 739 1.1 mrg size_t dst_size = GFC_DESCRIPTOR_SIZE (dest); 740 1.1 mrg 741 1.1 mrg if (stat) 742 1.1 mrg *stat = 0; 743 1.1 mrg 744 1.1 mrg if (rank == 0) 745 1.1 mrg { 746 1.1 mrg void *sr = (void *) ((char *) MEMTOK (token) + offset); 747 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 748 1.1 mrg && dst_kind == src_kind) 749 1.1 mrg { 750 1.1 mrg memmove (GFC_DESCRIPTOR_DATA (dest), sr, 751 1.1 mrg dst_size > src_size ? src_size : dst_size); 752 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size) 753 1.1 mrg { 754 1.1 mrg if (dst_kind == 1) 755 1.1 mrg memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest) + src_size, 756 1.1 mrg ' ', dst_size - src_size); 757 1.1 mrg else /* dst_kind == 4. */ 758 1.1 mrg for (i = src_size/4; i < dst_size/4; i++) 759 1.1 mrg ((int32_t*) GFC_DESCRIPTOR_DATA (dest))[i] = (int32_t) ' '; 760 1.1 mrg } 761 1.1 mrg } 762 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 763 1.1 mrg assign_char1_from_char4 (dst_size, src_size, GFC_DESCRIPTOR_DATA (dest), 764 1.1 mrg sr); 765 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 766 1.1 mrg assign_char4_from_char1 (dst_size, src_size, GFC_DESCRIPTOR_DATA (dest), 767 1.1 mrg sr); 768 1.1 mrg else 769 1.1 mrg convert_type (GFC_DESCRIPTOR_DATA (dest), GFC_DESCRIPTOR_TYPE (dest), 770 1.1 mrg dst_kind, sr, GFC_DESCRIPTOR_TYPE (src), src_kind, stat); 771 1.1 mrg return; 772 1.1 mrg } 773 1.1 mrg 774 1.1 mrg size = 1; 775 1.1 mrg for (j = 0; j < rank; j++) 776 1.1 mrg { 777 1.1 mrg ptrdiff_t dimextent = dest->dim[j]._ubound - dest->dim[j].lower_bound + 1; 778 1.1 mrg if (dimextent < 0) 779 1.1 mrg dimextent = 0; 780 1.1 mrg size *= dimextent; 781 1.1 mrg } 782 1.1 mrg 783 1.1 mrg if (size == 0) 784 1.1 mrg return; 785 1.1 mrg 786 1.1 mrg if (may_require_tmp) 787 1.1 mrg { 788 1.1 mrg ptrdiff_t array_offset_sr, array_offset_dst; 789 1.1 mrg void *tmp = malloc (size*src_size); 790 1.1 mrg 791 1.1 mrg array_offset_dst = 0; 792 1.1 mrg for (i = 0; i < size; i++) 793 1.1 mrg { 794 1.1 mrg ptrdiff_t array_offset_sr = 0; 795 1.1 mrg ptrdiff_t stride = 1; 796 1.1 mrg ptrdiff_t extent = 1; 797 1.1 mrg for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++) 798 1.1 mrg { 799 1.1 mrg array_offset_sr += ((i / (extent*stride)) 800 1.1 mrg % (src->dim[j]._ubound 801 1.1 mrg - src->dim[j].lower_bound + 1)) 802 1.1 mrg * src->dim[j]._stride; 803 1.1 mrg extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1); 804 1.1 mrg stride = src->dim[j]._stride; 805 1.1 mrg } 806 1.1 mrg array_offset_sr += (i / extent) * src->dim[rank-1]._stride; 807 1.1 mrg void *sr = (void *)((char *) MEMTOK (token) + offset 808 1.1 mrg + array_offset_sr*GFC_DESCRIPTOR_SIZE (src)); 809 1.1 mrg memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size); 810 1.1 mrg array_offset_dst += src_size; 811 1.1 mrg } 812 1.1 mrg 813 1.1 mrg array_offset_sr = 0; 814 1.1 mrg for (i = 0; i < size; i++) 815 1.1 mrg { 816 1.1 mrg ptrdiff_t array_offset_dst = 0; 817 1.1 mrg ptrdiff_t stride = 1; 818 1.1 mrg ptrdiff_t extent = 1; 819 1.1 mrg for (j = 0; j < rank-1; j++) 820 1.1 mrg { 821 1.1 mrg array_offset_dst += ((i / (extent*stride)) 822 1.1 mrg % (dest->dim[j]._ubound 823 1.1 mrg - dest->dim[j].lower_bound + 1)) 824 1.1 mrg * dest->dim[j]._stride; 825 1.1 mrg extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1); 826 1.1 mrg stride = dest->dim[j]._stride; 827 1.1 mrg } 828 1.1 mrg array_offset_dst += (i / extent) * dest->dim[rank-1]._stride; 829 1.1 mrg void *dst = dest->base_addr 830 1.1 mrg + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest); 831 1.1 mrg void *sr = tmp + array_offset_sr; 832 1.1 mrg 833 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 834 1.1 mrg && dst_kind == src_kind) 835 1.1 mrg { 836 1.1 mrg memmove (dst, sr, dst_size > src_size ? src_size : dst_size); 837 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER 838 1.1 mrg && dst_size > src_size) 839 1.1 mrg { 840 1.1 mrg if (dst_kind == 1) 841 1.1 mrg memset ((void*)(char*) dst + src_size, ' ', 842 1.1 mrg dst_size-src_size); 843 1.1 mrg else /* dst_kind == 4. */ 844 1.1 mrg for (k = src_size/4; k < dst_size/4; k++) 845 1.1 mrg ((int32_t*) dst)[k] = (int32_t) ' '; 846 1.1 mrg } 847 1.1 mrg } 848 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 849 1.1 mrg assign_char1_from_char4 (dst_size, src_size, dst, sr); 850 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 851 1.1 mrg assign_char4_from_char1 (dst_size, src_size, dst, sr); 852 1.1 mrg else 853 1.1 mrg convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind, 854 1.1 mrg sr, GFC_DESCRIPTOR_TYPE (src), src_kind, stat); 855 1.1 mrg array_offset_sr += src_size; 856 1.1 mrg } 857 1.1 mrg 858 1.1 mrg free (tmp); 859 1.1 mrg return; 860 1.1 mrg } 861 1.1 mrg 862 1.1 mrg for (i = 0; i < size; i++) 863 1.1 mrg { 864 1.1 mrg ptrdiff_t array_offset_dst = 0; 865 1.1 mrg ptrdiff_t stride = 1; 866 1.1 mrg ptrdiff_t extent = 1; 867 1.1 mrg for (j = 0; j < rank-1; j++) 868 1.1 mrg { 869 1.1 mrg array_offset_dst += ((i / (extent*stride)) 870 1.1 mrg % (dest->dim[j]._ubound 871 1.1 mrg - dest->dim[j].lower_bound + 1)) 872 1.1 mrg * dest->dim[j]._stride; 873 1.1 mrg extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1); 874 1.1 mrg stride = dest->dim[j]._stride; 875 1.1 mrg } 876 1.1 mrg array_offset_dst += (i / extent) * dest->dim[rank-1]._stride; 877 1.1 mrg void *dst = dest->base_addr + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest); 878 1.1 mrg 879 1.1 mrg ptrdiff_t array_offset_sr = 0; 880 1.1 mrg stride = 1; 881 1.1 mrg extent = 1; 882 1.1 mrg for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++) 883 1.1 mrg { 884 1.1 mrg array_offset_sr += ((i / (extent*stride)) 885 1.1 mrg % (src->dim[j]._ubound 886 1.1 mrg - src->dim[j].lower_bound + 1)) 887 1.1 mrg * src->dim[j]._stride; 888 1.1 mrg extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1); 889 1.1 mrg stride = src->dim[j]._stride; 890 1.1 mrg } 891 1.1 mrg array_offset_sr += (i / extent) * src->dim[rank-1]._stride; 892 1.1 mrg void *sr = (void *)((char *) MEMTOK (token) + offset 893 1.1 mrg + array_offset_sr*GFC_DESCRIPTOR_SIZE (src)); 894 1.1 mrg 895 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 896 1.1 mrg && dst_kind == src_kind) 897 1.1 mrg { 898 1.1 mrg memmove (dst, sr, dst_size > src_size ? src_size : dst_size); 899 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size) 900 1.1 mrg { 901 1.1 mrg if (dst_kind == 1) 902 1.1 mrg memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size); 903 1.1 mrg else /* dst_kind == 4. */ 904 1.1 mrg for (k = src_size/4; k < dst_size/4; k++) 905 1.1 mrg ((int32_t*) dst)[k] = (int32_t) ' '; 906 1.1 mrg } 907 1.1 mrg } 908 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 909 1.1 mrg assign_char1_from_char4 (dst_size, src_size, dst, sr); 910 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 911 1.1 mrg assign_char4_from_char1 (dst_size, src_size, dst, sr); 912 1.1 mrg else 913 1.1 mrg convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind, 914 1.1 mrg sr, GFC_DESCRIPTOR_TYPE (src), src_kind, stat); 915 1.1 mrg } 916 1.1 mrg } 917 1.1 mrg 918 1.1 mrg 919 1.1 mrg void 920 1.1 mrg _gfortran_caf_send (caf_token_t token, size_t offset, 921 1.1 mrg int image_index __attribute__ ((unused)), 922 1.1 mrg gfc_descriptor_t *dest, 923 1.1 mrg caf_vector_t *dst_vector __attribute__ ((unused)), 924 1.1 mrg gfc_descriptor_t *src, int dst_kind, int src_kind, 925 1.1 mrg bool may_require_tmp, int *stat) 926 1.1 mrg { 927 1.1 mrg /* FIXME: Handle vector subscripts. */ 928 1.1 mrg size_t i, k, size; 929 1.1 mrg int j; 930 1.1 mrg int rank = GFC_DESCRIPTOR_RANK (dest); 931 1.1 mrg size_t src_size = GFC_DESCRIPTOR_SIZE (src); 932 1.1 mrg size_t dst_size = GFC_DESCRIPTOR_SIZE (dest); 933 1.1 mrg 934 1.1 mrg if (stat) 935 1.1 mrg *stat = 0; 936 1.1 mrg 937 1.1 mrg if (rank == 0) 938 1.1 mrg { 939 1.1 mrg void *dst = (void *) ((char *) MEMTOK (token) + offset); 940 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 941 1.1 mrg && dst_kind == src_kind) 942 1.1 mrg { 943 1.1 mrg memmove (dst, GFC_DESCRIPTOR_DATA (src), 944 1.1 mrg dst_size > src_size ? src_size : dst_size); 945 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size) 946 1.1 mrg { 947 1.1 mrg if (dst_kind == 1) 948 1.1 mrg memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size); 949 1.1 mrg else /* dst_kind == 4. */ 950 1.1 mrg for (i = src_size/4; i < dst_size/4; i++) 951 1.1 mrg ((int32_t*) dst)[i] = (int32_t) ' '; 952 1.1 mrg } 953 1.1 mrg } 954 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 955 1.1 mrg assign_char1_from_char4 (dst_size, src_size, dst, 956 1.1 mrg GFC_DESCRIPTOR_DATA (src)); 957 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 958 1.1 mrg assign_char4_from_char1 (dst_size, src_size, dst, 959 1.1 mrg GFC_DESCRIPTOR_DATA (src)); 960 1.1 mrg else 961 1.1 mrg convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind, 962 1.1 mrg GFC_DESCRIPTOR_DATA (src), GFC_DESCRIPTOR_TYPE (src), 963 1.1 mrg src_kind, stat); 964 1.1 mrg return; 965 1.1 mrg } 966 1.1 mrg 967 1.1 mrg size = 1; 968 1.1 mrg for (j = 0; j < rank; j++) 969 1.1 mrg { 970 1.1 mrg ptrdiff_t dimextent = dest->dim[j]._ubound - dest->dim[j].lower_bound + 1; 971 1.1 mrg if (dimextent < 0) 972 1.1 mrg dimextent = 0; 973 1.1 mrg size *= dimextent; 974 1.1 mrg } 975 1.1 mrg 976 1.1 mrg if (size == 0) 977 1.1 mrg return; 978 1.1 mrg 979 1.1 mrg if (may_require_tmp) 980 1.1 mrg { 981 1.1 mrg ptrdiff_t array_offset_sr, array_offset_dst; 982 1.1 mrg void *tmp; 983 1.1 mrg 984 1.1 mrg if (GFC_DESCRIPTOR_RANK (src) == 0) 985 1.1 mrg { 986 1.1 mrg tmp = malloc (src_size); 987 1.1 mrg memcpy (tmp, GFC_DESCRIPTOR_DATA (src), src_size); 988 1.1 mrg } 989 1.1 mrg else 990 1.1 mrg { 991 1.1 mrg tmp = malloc (size*src_size); 992 1.1 mrg array_offset_dst = 0; 993 1.1 mrg for (i = 0; i < size; i++) 994 1.1 mrg { 995 1.1 mrg ptrdiff_t array_offset_sr = 0; 996 1.1 mrg ptrdiff_t stride = 1; 997 1.1 mrg ptrdiff_t extent = 1; 998 1.1 mrg for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++) 999 1.1 mrg { 1000 1.1 mrg array_offset_sr += ((i / (extent*stride)) 1001 1.1 mrg % (src->dim[j]._ubound 1002 1.1 mrg - src->dim[j].lower_bound + 1)) 1003 1.1 mrg * src->dim[j]._stride; 1004 1.1 mrg extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1); 1005 1.1 mrg stride = src->dim[j]._stride; 1006 1.1 mrg } 1007 1.1 mrg array_offset_sr += (i / extent) * src->dim[rank-1]._stride; 1008 1.1 mrg void *sr = (void *) ((char *) src->base_addr 1009 1.1 mrg + array_offset_sr*GFC_DESCRIPTOR_SIZE (src)); 1010 1.1 mrg memcpy ((void *) ((char *) tmp + array_offset_dst), sr, src_size); 1011 1.1 mrg array_offset_dst += src_size; 1012 1.1 mrg } 1013 1.1 mrg } 1014 1.1 mrg 1015 1.1 mrg array_offset_sr = 0; 1016 1.1 mrg for (i = 0; i < size; i++) 1017 1.1 mrg { 1018 1.1 mrg ptrdiff_t array_offset_dst = 0; 1019 1.1 mrg ptrdiff_t stride = 1; 1020 1.1 mrg ptrdiff_t extent = 1; 1021 1.1 mrg for (j = 0; j < rank-1; j++) 1022 1.1 mrg { 1023 1.1 mrg array_offset_dst += ((i / (extent*stride)) 1024 1.1 mrg % (dest->dim[j]._ubound 1025 1.1 mrg - dest->dim[j].lower_bound + 1)) 1026 1.1 mrg * dest->dim[j]._stride; 1027 1.1 mrg extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1); 1028 1.1 mrg stride = dest->dim[j]._stride; 1029 1.1 mrg } 1030 1.1 mrg array_offset_dst += (i / extent) * dest->dim[rank-1]._stride; 1031 1.1 mrg void *dst = (void *)((char *) MEMTOK (token) + offset 1032 1.1 mrg + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest)); 1033 1.1 mrg void *sr = tmp + array_offset_sr; 1034 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 1035 1.1 mrg && dst_kind == src_kind) 1036 1.1 mrg { 1037 1.1 mrg memmove (dst, sr, 1038 1.1 mrg dst_size > src_size ? src_size : dst_size); 1039 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER 1040 1.1 mrg && dst_size > src_size) 1041 1.1 mrg { 1042 1.1 mrg if (dst_kind == 1) 1043 1.1 mrg memset ((void*)(char*) dst + src_size, ' ', 1044 1.1 mrg dst_size-src_size); 1045 1.1 mrg else /* dst_kind == 4. */ 1046 1.1 mrg for (k = src_size/4; k < dst_size/4; k++) 1047 1.1 mrg ((int32_t*) dst)[k] = (int32_t) ' '; 1048 1.1 mrg } 1049 1.1 mrg } 1050 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 1051 1.1 mrg assign_char1_from_char4 (dst_size, src_size, dst, sr); 1052 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 1053 1.1 mrg assign_char4_from_char1 (dst_size, src_size, dst, sr); 1054 1.1 mrg else 1055 1.1 mrg convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind, 1056 1.1 mrg sr, GFC_DESCRIPTOR_TYPE (src), src_kind, stat); 1057 1.1 mrg if (GFC_DESCRIPTOR_RANK (src)) 1058 1.1 mrg array_offset_sr += src_size; 1059 1.1 mrg } 1060 1.1 mrg free (tmp); 1061 1.1 mrg return; 1062 1.1 mrg } 1063 1.1 mrg 1064 1.1 mrg for (i = 0; i < size; i++) 1065 1.1 mrg { 1066 1.1 mrg ptrdiff_t array_offset_dst = 0; 1067 1.1 mrg ptrdiff_t stride = 1; 1068 1.1 mrg ptrdiff_t extent = 1; 1069 1.1 mrg for (j = 0; j < rank-1; j++) 1070 1.1 mrg { 1071 1.1 mrg array_offset_dst += ((i / (extent*stride)) 1072 1.1 mrg % (dest->dim[j]._ubound 1073 1.1 mrg - dest->dim[j].lower_bound + 1)) 1074 1.1 mrg * dest->dim[j]._stride; 1075 1.1 mrg extent = (dest->dim[j]._ubound - dest->dim[j].lower_bound + 1); 1076 1.1 mrg stride = dest->dim[j]._stride; 1077 1.1 mrg } 1078 1.1 mrg array_offset_dst += (i / extent) * dest->dim[rank-1]._stride; 1079 1.1 mrg void *dst = (void *)((char *) MEMTOK (token) + offset 1080 1.1 mrg + array_offset_dst*GFC_DESCRIPTOR_SIZE (dest)); 1081 1.1 mrg void *sr; 1082 1.1 mrg if (GFC_DESCRIPTOR_RANK (src) != 0) 1083 1.1 mrg { 1084 1.1 mrg ptrdiff_t array_offset_sr = 0; 1085 1.1 mrg stride = 1; 1086 1.1 mrg extent = 1; 1087 1.1 mrg for (j = 0; j < GFC_DESCRIPTOR_RANK (src)-1; j++) 1088 1.1 mrg { 1089 1.1 mrg array_offset_sr += ((i / (extent*stride)) 1090 1.1 mrg % (src->dim[j]._ubound 1091 1.1 mrg - src->dim[j].lower_bound + 1)) 1092 1.1 mrg * src->dim[j]._stride; 1093 1.1 mrg extent = (src->dim[j]._ubound - src->dim[j].lower_bound + 1); 1094 1.1 mrg stride = src->dim[j]._stride; 1095 1.1 mrg } 1096 1.1 mrg array_offset_sr += (i / extent) * src->dim[rank-1]._stride; 1097 1.1 mrg sr = (void *)((char *) src->base_addr 1098 1.1 mrg + array_offset_sr*GFC_DESCRIPTOR_SIZE (src)); 1099 1.1 mrg } 1100 1.1 mrg else 1101 1.1 mrg sr = src->base_addr; 1102 1.1 mrg 1103 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == GFC_DESCRIPTOR_TYPE (src) 1104 1.1 mrg && dst_kind == src_kind) 1105 1.1 mrg { 1106 1.1 mrg memmove (dst, sr, 1107 1.1 mrg dst_size > src_size ? src_size : dst_size); 1108 1.1 mrg if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_size > src_size) 1109 1.1 mrg { 1110 1.1 mrg if (dst_kind == 1) 1111 1.1 mrg memset ((void*)(char*) dst + src_size, ' ', dst_size-src_size); 1112 1.1 mrg else /* dst_kind == 4. */ 1113 1.1 mrg for (k = src_size/4; k < dst_size/4; k++) 1114 1.1 mrg ((int32_t*) dst)[k] = (int32_t) ' '; 1115 1.1 mrg } 1116 1.1 mrg } 1117 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER && dst_kind == 1) 1118 1.1 mrg assign_char1_from_char4 (dst_size, src_size, dst, sr); 1119 1.1 mrg else if (GFC_DESCRIPTOR_TYPE (dest) == BT_CHARACTER) 1120 1.1 mrg assign_char4_from_char1 (dst_size, src_size, dst, sr); 1121 1.1 mrg else 1122 1.1 mrg convert_type (dst, GFC_DESCRIPTOR_TYPE (dest), dst_kind, 1123 1.1 mrg sr, GFC_DESCRIPTOR_TYPE (src), src_kind, stat); 1124 1.1 mrg } 1125 1.1 mrg } 1126 1.1 mrg 1127 1.1 mrg 1128 1.1 mrg void 1129 1.1 mrg _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset, 1130 1.1 mrg int dst_image_index, gfc_descriptor_t *dest, 1131 1.1 mrg caf_vector_t *dst_vector, caf_token_t src_token, 1132 1.1 mrg size_t src_offset, 1133 1.1 mrg int src_image_index __attribute__ ((unused)), 1134 1.1 mrg gfc_descriptor_t *src, 1135 1.1 mrg caf_vector_t *src_vector __attribute__ ((unused)), 1136 1.1 mrg int dst_kind, int src_kind, bool may_require_tmp) 1137 1.1 mrg { 1138 1.1 mrg /* FIXME: Handle vector subscript of 'src_vector'. */ 1139 1.1 mrg /* For a single image, src->base_addr should be the same as src_token + offset 1140 1.1 mrg but to play save, we do it properly. */ 1141 1.1 mrg void *src_base = GFC_DESCRIPTOR_DATA (src); 1142 1.1 mrg GFC_DESCRIPTOR_DATA (src) = (void *) ((char *) MEMTOK (src_token) 1143 1.1 mrg + src_offset); 1144 1.1 mrg _gfortran_caf_send (dst_token, dst_offset, dst_image_index, dest, dst_vector, 1145 1.1 mrg src, dst_kind, src_kind, may_require_tmp, NULL); 1146 1.1 mrg GFC_DESCRIPTOR_DATA (src) = src_base; 1147 1.1 mrg } 1148 1.1 mrg 1149 1.1 mrg 1150 1.1 mrg /* Emitted when a theorectically unreachable part is reached. */ 1151 1.1 mrg const char unreachable[] = "Fatal error: unreachable alternative found.\n"; 1152 1.1 mrg 1153 1.1 mrg 1154 1.1 mrg static void 1155 1.1 mrg copy_data (void *ds, void *sr, int dst_type, int src_type, 1156 1.1 mrg int dst_kind, int src_kind, size_t dst_size, size_t src_size, 1157 1.1 mrg size_t num, int *stat) 1158 1.1 mrg { 1159 1.1 mrg size_t k; 1160 1.1 mrg if (dst_type == src_type && dst_kind == src_kind) 1161 1.1 mrg { 1162 1.1 mrg memmove (ds, sr, (dst_size > src_size ? src_size : dst_size) * num); 1163 1.1 mrg if ((dst_type == BT_CHARACTER || src_type == BT_CHARACTER) 1164 1.1 mrg && dst_size > src_size) 1165 1.1 mrg { 1166 1.1 mrg if (dst_kind == 1) 1167 1.1 mrg memset ((void*)(char*) ds + src_size, ' ', dst_size-src_size); 1168 1.1 mrg else /* dst_kind == 4. */ 1169 1.1 mrg for (k = src_size/4; k < dst_size/4; k++) 1170 1.1 mrg ((int32_t*) ds)[k] = (int32_t) ' '; 1171 1.1 mrg } 1172 1.1 mrg } 1173 1.1 mrg else if (dst_type == BT_CHARACTER && dst_kind == 1) 1174 1.1 mrg assign_char1_from_char4 (dst_size, src_size, ds, sr); 1175 1.1 mrg else if (dst_type == BT_CHARACTER) 1176 1.1 mrg assign_char4_from_char1 (dst_size, src_size, ds, sr); 1177 1.1 mrg else 1178 1.1 mrg for (k = 0; k < num; ++k) 1179 1.1 mrg { 1180 1.1 mrg convert_type (ds, dst_type, dst_kind, sr, src_type, src_kind, stat); 1181 1.1 mrg ds += dst_size; 1182 1.1 mrg sr += src_size; 1183 1.1 mrg } 1184 1.1 mrg } 1185 1.1 mrg 1186 1.1 mrg 1187 1.1 mrg #define COMPUTE_NUM_ITEMS(num, stride, lb, ub) \ 1188 1.1 mrg do { \ 1189 1.1 mrg index_type abs_stride = (stride) > 0 ? (stride) : -(stride); \ 1190 1.1 mrg num = (stride) > 0 ? (ub) + 1 - (lb) : (lb) + 1 - (ub); \ 1191 1.1 mrg if (num <= 0 || abs_stride < 1) return; \ 1192 1.1 mrg num = (abs_stride > 1) ? (1 + (num - 1) / abs_stride) : num; \ 1193 1.1 mrg } while (0) 1194 1.1 mrg 1195 1.1 mrg 1196 1.1 mrg static void 1197 1.1 mrg get_for_ref (caf_reference_t *ref, size_t *i, size_t *dst_index, 1198 1.1 mrg caf_single_token_t single_token, gfc_descriptor_t *dst, 1199 1.1 mrg gfc_descriptor_t *src, void *ds, void *sr, 1200 1.1 mrg int dst_kind, int src_kind, size_t dst_dim, size_t src_dim, 1201 1.1 mrg size_t num, int *stat, int src_type) 1202 1.1 mrg { 1203 1.1 mrg ptrdiff_t extent_src = 1, array_offset_src = 0, stride_src; 1204 1.1 mrg size_t next_dst_dim; 1205 1.1 mrg 1206 1.1 mrg if (unlikely (ref == NULL)) 1207 1.1 mrg /* May be we should issue an error here, because this case should not 1208 1.1 mrg occur. */ 1209 1.1 mrg return; 1210 1.1 mrg 1211 1.1 mrg if (ref->next == NULL) 1212 1.1 mrg { 1213 1.1 mrg size_t dst_size = GFC_DESCRIPTOR_SIZE (dst); 1214 1.1 mrg ptrdiff_t array_offset_dst = 0;; 1215 1.1 mrg size_t dst_rank = GFC_DESCRIPTOR_RANK (dst); 1216 1.1 mrg 1217 1.1 mrg switch (ref->type) 1218 1.1 mrg { 1219 1.1 mrg case CAF_REF_COMPONENT: 1220 1.1 mrg /* Because the token is always registered after the component, its 1221 1.1 mrg offset is always greater zero. */ 1222 1.1 mrg if (ref->u.c.caf_token_offset > 0) 1223 1.1 mrg /* Note, that sr is dereffed here. */ 1224 1.1 mrg copy_data (ds, *(void **)(sr + ref->u.c.offset), 1225 1.1 mrg GFC_DESCRIPTOR_TYPE (dst), src_type, 1226 1.1 mrg dst_kind, src_kind, dst_size, ref->item_size, 1, stat); 1227 1.1 mrg else 1228 1.1 mrg copy_data (ds, sr + ref->u.c.offset, 1229 1.1 mrg GFC_DESCRIPTOR_TYPE (dst), src_type, 1230 1.1 mrg dst_kind, src_kind, dst_size, ref->item_size, 1, stat); 1231 1.1 mrg ++(*i); 1232 1.1 mrg return; 1233 1.1 mrg case CAF_REF_STATIC_ARRAY: 1234 1.1 mrg /* Intentionally fall through. */ 1235 1.1 mrg case CAF_REF_ARRAY: 1236 1.1 mrg if (ref->u.a.mode[src_dim] == CAF_ARR_REF_NONE) 1237 1.1 mrg { 1238 1.1 mrg for (size_t d = 0; d < dst_rank; ++d) 1239 1.1 mrg array_offset_dst += dst_index[d]; 1240 1.1 mrg copy_data (ds + array_offset_dst * dst_size, sr, 1241 1.1 mrg GFC_DESCRIPTOR_TYPE (dst), src_type, 1242 1.1 mrg dst_kind, src_kind, dst_size, ref->item_size, num, 1243 1.1 mrg stat); 1244 1.1 mrg *i += num; 1245 1.1 mrg return; 1246 1.1 mrg } 1247 1.1 mrg break; 1248 1.1 mrg default: 1249 1.1 mrg caf_runtime_error (unreachable); 1250 1.1 mrg } 1251 1.1 mrg } 1252 1.1 mrg 1253 1.1 mrg switch (ref->type) 1254 1.1 mrg { 1255 1.1 mrg case CAF_REF_COMPONENT: 1256 1.1 mrg if (ref->u.c.caf_token_offset > 0) 1257 1.1 mrg { 1258 1.1 mrg single_token = *(caf_single_token_t*)(sr + ref->u.c.caf_token_offset); 1259 1.1 mrg 1260 1.1 mrg if (ref->next && ref->next->type == CAF_REF_ARRAY) 1261 1.1 mrg src = single_token->desc; 1262 1.1 mrg else 1263 1.1 mrg src = NULL; 1264 1.1 mrg 1265 1.1 mrg if (ref->next && ref->next->type == CAF_REF_COMPONENT) 1266 1.1 mrg /* The currently ref'ed component was allocatabe (caf_token_offset 1267 1.1 mrg > 0) and the next ref is a component, too, then the new sr has to 1268 1.1 mrg be dereffed. (static arrays cannot be allocatable or they 1269 1.1 mrg become an array with descriptor. */ 1270 1.1 mrg sr = *(void **)(sr + ref->u.c.offset); 1271 1.1 mrg else 1272 1.1 mrg sr += ref->u.c.offset; 1273 1.1 mrg 1274 1.1 mrg get_for_ref (ref->next, i, dst_index, single_token, dst, src, 1275 1.1 mrg ds, sr, dst_kind, src_kind, dst_dim, 0, 1276 1.1 mrg 1, stat, src_type); 1277 1.1 mrg } 1278 1.1 mrg else 1279 1.1 mrg get_for_ref (ref->next, i, dst_index, single_token, dst, 1280 1.1 mrg (gfc_descriptor_t *)(sr + ref->u.c.offset), ds, 1281 1.1 mrg sr + ref->u.c.offset, dst_kind, src_kind, dst_dim, 0, 1, 1282 1.1 mrg stat, src_type); 1283 1.1 mrg return; 1284 1.1 mrg case CAF_REF_ARRAY: 1285 1.1 mrg if (ref->u.a.mode[src_dim] == CAF_ARR_REF_NONE) 1286 1.1 mrg { 1287 1.1 mrg get_for_ref (ref->next, i, dst_index, single_token, dst, 1288 1.1 mrg src, ds, sr, dst_kind, src_kind, 1289 1.1 mrg dst_dim, 0, 1, stat, src_type); 1290 1.1 mrg return; 1291 1.1 mrg } 1292 1.1 mrg /* Only when on the left most index switch the data pointer to 1293 1.1 mrg the array's data pointer. */ 1294 1.1 mrg if (src_dim == 0) 1295 1.1 mrg sr = GFC_DESCRIPTOR_DATA (src); 1296 1.1 mrg switch (ref->u.a.mode[src_dim]) 1297 1.1 mrg { 1298 1.1 mrg case CAF_ARR_REF_VECTOR: 1299 1.1 mrg extent_src = GFC_DIMENSION_EXTENT (src->dim[src_dim]); 1300 1.1 mrg array_offset_src = 0; 1301 1.1 mrg dst_index[dst_dim] = 0; 1302 1.1 mrg for (size_t idx = 0; idx < ref->u.a.dim[src_dim].v.nvec; 1303 1.1 mrg ++idx) 1304 1.1 mrg { 1305 1.1 mrg #define KINDCASE(kind, type) case kind: \ 1306 1.1 mrg array_offset_src = (((index_type) \ 1307 1.1 mrg ((type *)ref->u.a.dim[src_dim].v.vector)[idx]) \ 1308 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[src_dim])) \ 1309 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[src_dim]); \ 1310 1.1 mrg break 1311 1.1 mrg 1312 1.1 mrg switch (ref->u.a.dim[src_dim].v.kind) 1313 1.1 mrg { 1314 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 1315 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 1316 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 1317 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 1318 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 1319 1.1 mrg #endif 1320 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 1321 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 1322 1.1 mrg #endif 1323 1.1 mrg default: 1324 1.1 mrg caf_runtime_error (unreachable); 1325 1.1 mrg return; 1326 1.1 mrg } 1327 1.1 mrg #undef KINDCASE 1328 1.1 mrg 1329 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, 1330 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1331 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1332 1.1 mrg 1, stat, src_type); 1333 1.1 mrg dst_index[dst_dim] 1334 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1335 1.1 mrg } 1336 1.1 mrg return; 1337 1.1 mrg case CAF_ARR_REF_FULL: 1338 1.1 mrg COMPUTE_NUM_ITEMS (extent_src, 1339 1.1 mrg ref->u.a.dim[src_dim].s.stride, 1340 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[src_dim]), 1341 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[src_dim])); 1342 1.1 mrg stride_src = src->dim[src_dim]._stride 1343 1.1 mrg * ref->u.a.dim[src_dim].s.stride; 1344 1.1 mrg array_offset_src = 0; 1345 1.1 mrg dst_index[dst_dim] = 0; 1346 1.1 mrg for (index_type idx = 0; idx < extent_src; 1347 1.1 mrg ++idx, array_offset_src += stride_src) 1348 1.1 mrg { 1349 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, 1350 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1351 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1352 1.1 mrg 1, stat, src_type); 1353 1.1 mrg dst_index[dst_dim] 1354 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1355 1.1 mrg } 1356 1.1 mrg return; 1357 1.1 mrg case CAF_ARR_REF_RANGE: 1358 1.1 mrg COMPUTE_NUM_ITEMS (extent_src, 1359 1.1 mrg ref->u.a.dim[src_dim].s.stride, 1360 1.1 mrg ref->u.a.dim[src_dim].s.start, 1361 1.1 mrg ref->u.a.dim[src_dim].s.end); 1362 1.1 mrg array_offset_src = (ref->u.a.dim[src_dim].s.start 1363 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[src_dim])) 1364 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[src_dim]); 1365 1.1 mrg stride_src = GFC_DIMENSION_STRIDE (src->dim[src_dim]) 1366 1.1 mrg * ref->u.a.dim[src_dim].s.stride; 1367 1.1 mrg dst_index[dst_dim] = 0; 1368 1.1 mrg /* Increase the dst_dim only, when the src_extent is greater one 1369 1.1 mrg or src and dst extent are both one. Don't increase when the scalar 1370 1.1 mrg source is not present in the dst. */ 1371 1.1 mrg next_dst_dim = extent_src > 1 1372 1.1 mrg || (GFC_DIMENSION_EXTENT (dst->dim[dst_dim]) == 1 1373 1.1 mrg && extent_src == 1) ? (dst_dim + 1) : dst_dim; 1374 1.1 mrg for (index_type idx = 0; idx < extent_src; ++idx) 1375 1.1 mrg { 1376 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, 1377 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1378 1.1 mrg dst_kind, src_kind, next_dst_dim, src_dim + 1, 1379 1.1 mrg 1, stat, src_type); 1380 1.1 mrg dst_index[dst_dim] 1381 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1382 1.1 mrg array_offset_src += stride_src; 1383 1.1 mrg } 1384 1.1 mrg return; 1385 1.1 mrg case CAF_ARR_REF_SINGLE: 1386 1.1 mrg array_offset_src = (ref->u.a.dim[src_dim].s.start 1387 1.1 mrg - src->dim[src_dim].lower_bound) 1388 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[src_dim]); 1389 1.1 mrg dst_index[dst_dim] = 0; 1390 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, ds, 1391 1.1 mrg sr + array_offset_src * ref->item_size, 1392 1.1 mrg dst_kind, src_kind, dst_dim, src_dim + 1, 1, 1393 1.1 mrg stat, src_type); 1394 1.1 mrg return; 1395 1.1 mrg case CAF_ARR_REF_OPEN_END: 1396 1.1 mrg COMPUTE_NUM_ITEMS (extent_src, 1397 1.1 mrg ref->u.a.dim[src_dim].s.stride, 1398 1.1 mrg ref->u.a.dim[src_dim].s.start, 1399 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[src_dim])); 1400 1.1 mrg stride_src = GFC_DIMENSION_STRIDE (src->dim[src_dim]) 1401 1.1 mrg * ref->u.a.dim[src_dim].s.stride; 1402 1.1 mrg array_offset_src = (ref->u.a.dim[src_dim].s.start 1403 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[src_dim])) 1404 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[src_dim]); 1405 1.1 mrg dst_index[dst_dim] = 0; 1406 1.1 mrg for (index_type idx = 0; idx < extent_src; ++idx) 1407 1.1 mrg { 1408 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, 1409 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1410 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1411 1.1 mrg 1, stat, src_type); 1412 1.1 mrg dst_index[dst_dim] 1413 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1414 1.1 mrg array_offset_src += stride_src; 1415 1.1 mrg } 1416 1.1 mrg return; 1417 1.1 mrg case CAF_ARR_REF_OPEN_START: 1418 1.1 mrg COMPUTE_NUM_ITEMS (extent_src, 1419 1.1 mrg ref->u.a.dim[src_dim].s.stride, 1420 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[src_dim]), 1421 1.1 mrg ref->u.a.dim[src_dim].s.end); 1422 1.1 mrg stride_src = GFC_DIMENSION_STRIDE (src->dim[src_dim]) 1423 1.1 mrg * ref->u.a.dim[src_dim].s.stride; 1424 1.1 mrg array_offset_src = 0; 1425 1.1 mrg dst_index[dst_dim] = 0; 1426 1.1 mrg for (index_type idx = 0; idx < extent_src; ++idx) 1427 1.1 mrg { 1428 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, src, 1429 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1430 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1431 1.1 mrg 1, stat, src_type); 1432 1.1 mrg dst_index[dst_dim] 1433 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1434 1.1 mrg array_offset_src += stride_src; 1435 1.1 mrg } 1436 1.1 mrg return; 1437 1.1 mrg default: 1438 1.1 mrg caf_runtime_error (unreachable); 1439 1.1 mrg } 1440 1.1 mrg return; 1441 1.1 mrg case CAF_REF_STATIC_ARRAY: 1442 1.1 mrg if (ref->u.a.mode[src_dim] == CAF_ARR_REF_NONE) 1443 1.1 mrg { 1444 1.1 mrg get_for_ref (ref->next, i, dst_index, single_token, dst, 1445 1.1 mrg NULL, ds, sr, dst_kind, src_kind, 1446 1.1 mrg dst_dim, 0, 1, stat, src_type); 1447 1.1 mrg return; 1448 1.1 mrg } 1449 1.1 mrg switch (ref->u.a.mode[src_dim]) 1450 1.1 mrg { 1451 1.1 mrg case CAF_ARR_REF_VECTOR: 1452 1.1 mrg array_offset_src = 0; 1453 1.1 mrg dst_index[dst_dim] = 0; 1454 1.1 mrg for (size_t idx = 0; idx < ref->u.a.dim[src_dim].v.nvec; 1455 1.1 mrg ++idx) 1456 1.1 mrg { 1457 1.1 mrg #define KINDCASE(kind, type) case kind: \ 1458 1.1 mrg array_offset_src = ((type *)ref->u.a.dim[src_dim].v.vector)[idx]; \ 1459 1.1 mrg break 1460 1.1 mrg 1461 1.1 mrg switch (ref->u.a.dim[src_dim].v.kind) 1462 1.1 mrg { 1463 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 1464 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 1465 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 1466 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 1467 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 1468 1.1 mrg #endif 1469 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 1470 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 1471 1.1 mrg #endif 1472 1.1 mrg default: 1473 1.1 mrg caf_runtime_error (unreachable); 1474 1.1 mrg return; 1475 1.1 mrg } 1476 1.1 mrg #undef KINDCASE 1477 1.1 mrg 1478 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, NULL, 1479 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1480 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1481 1.1 mrg 1, stat, src_type); 1482 1.1 mrg dst_index[dst_dim] 1483 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1484 1.1 mrg } 1485 1.1 mrg return; 1486 1.1 mrg case CAF_ARR_REF_FULL: 1487 1.1 mrg dst_index[dst_dim] = 0; 1488 1.1 mrg for (array_offset_src = 0 ; 1489 1.1 mrg array_offset_src <= ref->u.a.dim[src_dim].s.end; 1490 1.1 mrg array_offset_src += ref->u.a.dim[src_dim].s.stride) 1491 1.1 mrg { 1492 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, NULL, 1493 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1494 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1495 1.1 mrg 1, stat, src_type); 1496 1.1 mrg dst_index[dst_dim] 1497 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1498 1.1 mrg } 1499 1.1 mrg return; 1500 1.1 mrg case CAF_ARR_REF_RANGE: 1501 1.1 mrg COMPUTE_NUM_ITEMS (extent_src, 1502 1.1 mrg ref->u.a.dim[src_dim].s.stride, 1503 1.1 mrg ref->u.a.dim[src_dim].s.start, 1504 1.1 mrg ref->u.a.dim[src_dim].s.end); 1505 1.1 mrg array_offset_src = ref->u.a.dim[src_dim].s.start; 1506 1.1 mrg dst_index[dst_dim] = 0; 1507 1.1 mrg for (index_type idx = 0; idx < extent_src; ++idx) 1508 1.1 mrg { 1509 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, NULL, 1510 1.1 mrg ds, sr + array_offset_src * ref->item_size, 1511 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 1512 1.1 mrg 1, stat, src_type); 1513 1.1 mrg dst_index[dst_dim] 1514 1.1 mrg += GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 1515 1.1 mrg array_offset_src += ref->u.a.dim[src_dim].s.stride; 1516 1.1 mrg } 1517 1.1 mrg return; 1518 1.1 mrg case CAF_ARR_REF_SINGLE: 1519 1.1 mrg array_offset_src = ref->u.a.dim[src_dim].s.start; 1520 1.1 mrg get_for_ref (ref, i, dst_index, single_token, dst, NULL, ds, 1521 1.1 mrg sr + array_offset_src * ref->item_size, 1522 1.1 mrg dst_kind, src_kind, dst_dim, src_dim + 1, 1, 1523 1.1 mrg stat, src_type); 1524 1.1 mrg return; 1525 1.1 mrg /* The OPEN_* are mapped to a RANGE and therefore cannot occur. */ 1526 1.1 mrg case CAF_ARR_REF_OPEN_END: 1527 1.1 mrg case CAF_ARR_REF_OPEN_START: 1528 1.1 mrg default: 1529 1.1 mrg caf_runtime_error (unreachable); 1530 1.1 mrg } 1531 1.1 mrg return; 1532 1.1 mrg default: 1533 1.1 mrg caf_runtime_error (unreachable); 1534 1.1 mrg } 1535 1.1 mrg } 1536 1.1 mrg 1537 1.1 mrg 1538 1.1 mrg void 1539 1.1 mrg _gfortran_caf_get_by_ref (caf_token_t token, 1540 1.1 mrg int image_index __attribute__ ((unused)), 1541 1.1 mrg gfc_descriptor_t *dst, caf_reference_t *refs, 1542 1.1 mrg int dst_kind, int src_kind, 1543 1.1 mrg bool may_require_tmp __attribute__ ((unused)), 1544 1.1 mrg bool dst_reallocatable, int *stat, 1545 1.1 mrg int src_type) 1546 1.1 mrg { 1547 1.1 mrg const char vecrefunknownkind[] = "libcaf_single::caf_get_by_ref(): " 1548 1.1 mrg "unknown kind in vector-ref.\n"; 1549 1.1 mrg const char unknownreftype[] = "libcaf_single::caf_get_by_ref(): " 1550 1.1 mrg "unknown reference type.\n"; 1551 1.1 mrg const char unknownarrreftype[] = "libcaf_single::caf_get_by_ref(): " 1552 1.1 mrg "unknown array reference type.\n"; 1553 1.1 mrg const char rankoutofrange[] = "libcaf_single::caf_get_by_ref(): " 1554 1.1 mrg "rank out of range.\n"; 1555 1.1 mrg const char extentoutofrange[] = "libcaf_single::caf_get_by_ref(): " 1556 1.1 mrg "extent out of range.\n"; 1557 1.1 mrg const char cannotallocdst[] = "libcaf_single::caf_get_by_ref(): " 1558 1.1 mrg "cannot allocate memory.\n"; 1559 1.1 mrg const char nonallocextentmismatch[] = "libcaf_single::caf_get_by_ref(): " 1560 1.1 mrg "extent of non-allocatable arrays mismatch (%lu != %lu).\n"; 1561 1.1 mrg const char doublearrayref[] = "libcaf_single::caf_get_by_ref(): " 1562 1.1 mrg "two or more array part references are not supported.\n"; 1563 1.1 mrg size_t size, i; 1564 1.1 mrg size_t dst_index[GFC_MAX_DIMENSIONS]; 1565 1.1 mrg int dst_rank = GFC_DESCRIPTOR_RANK (dst); 1566 1.1 mrg int dst_cur_dim = 0; 1567 1.1 mrg size_t src_size = 0; 1568 1.1 mrg caf_single_token_t single_token = TOKEN (token); 1569 1.1 mrg void *memptr = single_token->memptr; 1570 1.1 mrg gfc_descriptor_t *src = single_token->desc; 1571 1.1 mrg caf_reference_t *riter = refs; 1572 1.1 mrg long delta; 1573 1.1 mrg /* Reallocation of dst.data is needed (e.g., array to small). */ 1574 1.1 mrg bool realloc_needed; 1575 1.1 mrg /* Reallocation of dst.data is required, because data is not alloced at 1576 1.1 mrg all. */ 1577 1.1 mrg bool realloc_required; 1578 1.1 mrg bool extent_mismatch = false; 1579 1.1 mrg /* Set when the first non-scalar array reference is encountered. */ 1580 1.1 mrg bool in_array_ref = false; 1581 1.1 mrg bool array_extent_fixed = false; 1582 1.1 mrg realloc_needed = realloc_required = GFC_DESCRIPTOR_DATA (dst) == NULL; 1583 1.1 mrg 1584 1.1 mrg assert (!realloc_needed || dst_reallocatable); 1585 1.1 mrg 1586 1.1 mrg if (stat) 1587 1.1 mrg *stat = 0; 1588 1.1 mrg 1589 1.1 mrg /* Compute the size of the result. In the beginning size just counts the 1590 1.1 mrg number of elements. */ 1591 1.1 mrg size = 1; 1592 1.1 mrg while (riter) 1593 1.1 mrg { 1594 1.1 mrg switch (riter->type) 1595 1.1 mrg { 1596 1.1 mrg case CAF_REF_COMPONENT: 1597 1.1 mrg if (riter->u.c.caf_token_offset) 1598 1.1 mrg { 1599 1.1 mrg single_token = *(caf_single_token_t*) 1600 1.1 mrg (memptr + riter->u.c.caf_token_offset); 1601 1.1 mrg memptr = single_token->memptr; 1602 1.1 mrg src = single_token->desc; 1603 1.1 mrg } 1604 1.1 mrg else 1605 1.1 mrg { 1606 1.1 mrg memptr += riter->u.c.offset; 1607 1.1 mrg /* When the next ref is an array ref, assume there is an 1608 1.1 mrg array descriptor at memptr. Note, static arrays do not have 1609 1.1 mrg a descriptor. */ 1610 1.1 mrg if (riter->next && riter->next->type == CAF_REF_ARRAY) 1611 1.1 mrg src = (gfc_descriptor_t *)memptr; 1612 1.1 mrg else 1613 1.1 mrg src = NULL; 1614 1.1 mrg } 1615 1.1 mrg break; 1616 1.1 mrg case CAF_REF_ARRAY: 1617 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 1618 1.1 mrg { 1619 1.1 mrg switch (riter->u.a.mode[i]) 1620 1.1 mrg { 1621 1.1 mrg case CAF_ARR_REF_VECTOR: 1622 1.1 mrg delta = riter->u.a.dim[i].v.nvec; 1623 1.1 mrg #define KINDCASE(kind, type) case kind: \ 1624 1.1 mrg memptr += (((index_type) \ 1625 1.1 mrg ((type *)riter->u.a.dim[i].v.vector)[0]) \ 1626 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[i])) \ 1627 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[i]) \ 1628 1.1 mrg * riter->item_size; \ 1629 1.1 mrg break 1630 1.1 mrg 1631 1.1 mrg switch (riter->u.a.dim[i].v.kind) 1632 1.1 mrg { 1633 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 1634 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 1635 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 1636 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 1637 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 1638 1.1 mrg #endif 1639 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 1640 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 1641 1.1 mrg #endif 1642 1.1 mrg default: 1643 1.1 mrg caf_internal_error (vecrefunknownkind, stat, NULL, 0); 1644 1.1 mrg return; 1645 1.1 mrg } 1646 1.1 mrg #undef KINDCASE 1647 1.1 mrg break; 1648 1.1 mrg case CAF_ARR_REF_FULL: 1649 1.1 mrg COMPUTE_NUM_ITEMS (delta, 1650 1.1 mrg riter->u.a.dim[i].s.stride, 1651 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[i]), 1652 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[i])); 1653 1.1 mrg /* The memptr stays unchanged when ref'ing the first element 1654 1.1 mrg in a dimension. */ 1655 1.1 mrg break; 1656 1.1 mrg case CAF_ARR_REF_RANGE: 1657 1.1 mrg COMPUTE_NUM_ITEMS (delta, 1658 1.1 mrg riter->u.a.dim[i].s.stride, 1659 1.1 mrg riter->u.a.dim[i].s.start, 1660 1.1 mrg riter->u.a.dim[i].s.end); 1661 1.1 mrg memptr += (riter->u.a.dim[i].s.start 1662 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[i])) 1663 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[i]) 1664 1.1 mrg * riter->item_size; 1665 1.1 mrg break; 1666 1.1 mrg case CAF_ARR_REF_SINGLE: 1667 1.1 mrg delta = 1; 1668 1.1 mrg memptr += (riter->u.a.dim[i].s.start 1669 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[i])) 1670 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[i]) 1671 1.1 mrg * riter->item_size; 1672 1.1 mrg break; 1673 1.1 mrg case CAF_ARR_REF_OPEN_END: 1674 1.1 mrg COMPUTE_NUM_ITEMS (delta, 1675 1.1 mrg riter->u.a.dim[i].s.stride, 1676 1.1 mrg riter->u.a.dim[i].s.start, 1677 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[i])); 1678 1.1 mrg memptr += (riter->u.a.dim[i].s.start 1679 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[i])) 1680 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[i]) 1681 1.1 mrg * riter->item_size; 1682 1.1 mrg break; 1683 1.1 mrg case CAF_ARR_REF_OPEN_START: 1684 1.1 mrg COMPUTE_NUM_ITEMS (delta, 1685 1.1 mrg riter->u.a.dim[i].s.stride, 1686 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[i]), 1687 1.1 mrg riter->u.a.dim[i].s.end); 1688 1.1 mrg /* The memptr stays unchanged when ref'ing the first element 1689 1.1 mrg in a dimension. */ 1690 1.1 mrg break; 1691 1.1 mrg default: 1692 1.1 mrg caf_internal_error (unknownarrreftype, stat, NULL, 0); 1693 1.1 mrg return; 1694 1.1 mrg } 1695 1.1 mrg if (delta <= 0) 1696 1.1 mrg return; 1697 1.1 mrg /* Check the various properties of the destination array. 1698 1.1 mrg Is an array expected and present? */ 1699 1.1 mrg if (delta > 1 && dst_rank == 0) 1700 1.1 mrg { 1701 1.1 mrg /* No, an array is required, but not provided. */ 1702 1.1 mrg caf_internal_error (extentoutofrange, stat, NULL, 0); 1703 1.1 mrg return; 1704 1.1 mrg } 1705 1.1 mrg /* Special mode when called by __caf_sendget_by_ref (). */ 1706 1.1 mrg if (dst_rank == -1 && GFC_DESCRIPTOR_DATA (dst) == NULL) 1707 1.1 mrg { 1708 1.1 mrg dst_rank = dst_cur_dim + 1; 1709 1.1 mrg GFC_DESCRIPTOR_RANK (dst) = dst_rank; 1710 1.1 mrg GFC_DESCRIPTOR_SIZE (dst) = dst_kind; 1711 1.1 mrg } 1712 1.1 mrg /* When dst is an array. */ 1713 1.1 mrg if (dst_rank > 0) 1714 1.1 mrg { 1715 1.1 mrg /* Check that dst_cur_dim is valid for dst. Can be 1716 1.1 mrg superceeded only by scalar data. */ 1717 1.1 mrg if (dst_cur_dim >= dst_rank && delta != 1) 1718 1.1 mrg { 1719 1.1 mrg caf_internal_error (rankoutofrange, stat, NULL, 0); 1720 1.1 mrg return; 1721 1.1 mrg } 1722 1.1 mrg /* Do further checks, when the source is not scalar. */ 1723 1.1 mrg else if (delta != 1) 1724 1.1 mrg { 1725 1.1 mrg /* Check that the extent is not scalar and we are not in 1726 1.1 mrg an array ref for the dst side. */ 1727 1.1 mrg if (!in_array_ref) 1728 1.1 mrg { 1729 1.1 mrg /* Check that this is the non-scalar extent. */ 1730 1.1 mrg if (!array_extent_fixed) 1731 1.1 mrg { 1732 1.1 mrg /* In an array extent now. */ 1733 1.1 mrg in_array_ref = true; 1734 1.1 mrg /* Check that we haven't skipped any scalar 1735 1.1 mrg dimensions yet and that the dst is 1736 1.1 mrg compatible. */ 1737 1.1 mrg if (i > 0 1738 1.1 mrg && dst_rank == GFC_DESCRIPTOR_RANK (src)) 1739 1.1 mrg { 1740 1.1 mrg if (dst_reallocatable) 1741 1.1 mrg { 1742 1.1 mrg /* Dst is reallocatable, which means that 1743 1.1 mrg the bounds are not set. Set them. */ 1744 1.1 mrg for (dst_cur_dim= 0; dst_cur_dim < (int)i; 1745 1.1 mrg ++dst_cur_dim) 1746 1.1 mrg GFC_DIMENSION_SET (dst->dim[dst_cur_dim], 1747 1.1 mrg 1, 1, 1); 1748 1.1 mrg } 1749 1.1 mrg else 1750 1.1 mrg dst_cur_dim = i; 1751 1.1 mrg } 1752 1.1 mrg /* Else press thumbs, that there are enough 1753 1.1 mrg dimensional refs to come. Checked below. */ 1754 1.1 mrg } 1755 1.1 mrg else 1756 1.1 mrg { 1757 1.1 mrg caf_internal_error (doublearrayref, stat, NULL, 1758 1.1 mrg 0); 1759 1.1 mrg return; 1760 1.1 mrg } 1761 1.1 mrg } 1762 1.1 mrg /* When the realloc is required, then no extent may have 1763 1.1 mrg been set. */ 1764 1.1 mrg extent_mismatch = realloc_required 1765 1.1 mrg || GFC_DESCRIPTOR_EXTENT (dst, dst_cur_dim) != delta; 1766 1.1 mrg /* When it already known, that a realloc is needed or 1767 1.1 mrg the extent does not match the needed one. */ 1768 1.1 mrg if (realloc_required || realloc_needed 1769 1.1 mrg || extent_mismatch) 1770 1.1 mrg { 1771 1.1 mrg /* Check whether dst is reallocatable. */ 1772 1.1 mrg if (unlikely (!dst_reallocatable)) 1773 1.1 mrg { 1774 1.1 mrg caf_internal_error (nonallocextentmismatch, stat, 1775 1.1 mrg NULL, 0, delta, 1776 1.1 mrg GFC_DESCRIPTOR_EXTENT (dst, 1777 1.1 mrg dst_cur_dim)); 1778 1.1 mrg return; 1779 1.1 mrg } 1780 1.1 mrg /* Only report an error, when the extent needs to be 1781 1.1 mrg modified, which is not allowed. */ 1782 1.1 mrg else if (!dst_reallocatable && extent_mismatch) 1783 1.1 mrg { 1784 1.1 mrg caf_internal_error (extentoutofrange, stat, NULL, 1785 1.1 mrg 0); 1786 1.1 mrg return; 1787 1.1 mrg } 1788 1.1 mrg realloc_needed = true; 1789 1.1 mrg } 1790 1.1 mrg /* Only change the extent when it does not match. This is 1791 1.1 mrg to prevent resetting given array bounds. */ 1792 1.1 mrg if (extent_mismatch) 1793 1.1 mrg GFC_DIMENSION_SET (dst->dim[dst_cur_dim], 1, delta, 1794 1.1 mrg size); 1795 1.1 mrg } 1796 1.1 mrg 1797 1.1 mrg /* Only increase the dim counter, when in an array ref. */ 1798 1.1 mrg if (in_array_ref && dst_cur_dim < dst_rank) 1799 1.1 mrg ++dst_cur_dim; 1800 1.1 mrg } 1801 1.1 mrg size *= (index_type)delta; 1802 1.1 mrg } 1803 1.1 mrg if (in_array_ref) 1804 1.1 mrg { 1805 1.1 mrg array_extent_fixed = true; 1806 1.1 mrg in_array_ref = false; 1807 1.1 mrg /* Check, if we got less dimensional refs than the rank of dst 1808 1.1 mrg expects. */ 1809 1.1 mrg assert (dst_cur_dim == GFC_DESCRIPTOR_RANK (dst)); 1810 1.1 mrg } 1811 1.1 mrg break; 1812 1.1 mrg case CAF_REF_STATIC_ARRAY: 1813 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 1814 1.1 mrg { 1815 1.1 mrg switch (riter->u.a.mode[i]) 1816 1.1 mrg { 1817 1.1 mrg case CAF_ARR_REF_VECTOR: 1818 1.1 mrg delta = riter->u.a.dim[i].v.nvec; 1819 1.1 mrg #define KINDCASE(kind, type) case kind: \ 1820 1.1 mrg memptr += ((type *)riter->u.a.dim[i].v.vector)[0] \ 1821 1.1 mrg * riter->item_size; \ 1822 1.1 mrg break 1823 1.1 mrg 1824 1.1 mrg switch (riter->u.a.dim[i].v.kind) 1825 1.1 mrg { 1826 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 1827 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 1828 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 1829 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 1830 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 1831 1.1 mrg #endif 1832 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 1833 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 1834 1.1 mrg #endif 1835 1.1 mrg default: 1836 1.1 mrg caf_internal_error (vecrefunknownkind, stat, NULL, 0); 1837 1.1 mrg return; 1838 1.1 mrg } 1839 1.1 mrg #undef KINDCASE 1840 1.1 mrg break; 1841 1.1 mrg case CAF_ARR_REF_FULL: 1842 1.1 mrg delta = riter->u.a.dim[i].s.end / riter->u.a.dim[i].s.stride 1843 1.1 mrg + 1; 1844 1.1 mrg /* The memptr stays unchanged when ref'ing the first element 1845 1.1 mrg in a dimension. */ 1846 1.1 mrg break; 1847 1.1 mrg case CAF_ARR_REF_RANGE: 1848 1.1 mrg COMPUTE_NUM_ITEMS (delta, 1849 1.1 mrg riter->u.a.dim[i].s.stride, 1850 1.1 mrg riter->u.a.dim[i].s.start, 1851 1.1 mrg riter->u.a.dim[i].s.end); 1852 1.1 mrg memptr += riter->u.a.dim[i].s.start 1853 1.1 mrg * riter->u.a.dim[i].s.stride 1854 1.1 mrg * riter->item_size; 1855 1.1 mrg break; 1856 1.1 mrg case CAF_ARR_REF_SINGLE: 1857 1.1 mrg delta = 1; 1858 1.1 mrg memptr += riter->u.a.dim[i].s.start 1859 1.1 mrg * riter->u.a.dim[i].s.stride 1860 1.1 mrg * riter->item_size; 1861 1.1 mrg break; 1862 1.1 mrg case CAF_ARR_REF_OPEN_END: 1863 1.1 mrg /* This and OPEN_START are mapped to a RANGE and therefore 1864 1.1 mrg cannot occur here. */ 1865 1.1 mrg case CAF_ARR_REF_OPEN_START: 1866 1.1 mrg default: 1867 1.1 mrg caf_internal_error (unknownarrreftype, stat, NULL, 0); 1868 1.1 mrg return; 1869 1.1 mrg } 1870 1.1 mrg if (delta <= 0) 1871 1.1 mrg return; 1872 1.1 mrg /* Check the various properties of the destination array. 1873 1.1 mrg Is an array expected and present? */ 1874 1.1 mrg if (delta > 1 && dst_rank == 0) 1875 1.1 mrg { 1876 1.1 mrg /* No, an array is required, but not provided. */ 1877 1.1 mrg caf_internal_error (extentoutofrange, stat, NULL, 0); 1878 1.1 mrg return; 1879 1.1 mrg } 1880 1.1 mrg /* Special mode when called by __caf_sendget_by_ref (). */ 1881 1.1 mrg if (dst_rank == -1 && GFC_DESCRIPTOR_DATA (dst) == NULL) 1882 1.1 mrg { 1883 1.1 mrg dst_rank = dst_cur_dim + 1; 1884 1.1 mrg GFC_DESCRIPTOR_RANK (dst) = dst_rank; 1885 1.1 mrg GFC_DESCRIPTOR_SIZE (dst) = dst_kind; 1886 1.1 mrg } 1887 1.1 mrg /* When dst is an array. */ 1888 1.1 mrg if (dst_rank > 0) 1889 1.1 mrg { 1890 1.1 mrg /* Check that dst_cur_dim is valid for dst. Can be 1891 1.1 mrg superceeded only by scalar data. */ 1892 1.1 mrg if (dst_cur_dim >= dst_rank && delta != 1) 1893 1.1 mrg { 1894 1.1 mrg caf_internal_error (rankoutofrange, stat, NULL, 0); 1895 1.1 mrg return; 1896 1.1 mrg } 1897 1.1 mrg /* Do further checks, when the source is not scalar. */ 1898 1.1 mrg else if (delta != 1) 1899 1.1 mrg { 1900 1.1 mrg /* Check that the extent is not scalar and we are not in 1901 1.1 mrg an array ref for the dst side. */ 1902 1.1 mrg if (!in_array_ref) 1903 1.1 mrg { 1904 1.1 mrg /* Check that this is the non-scalar extent. */ 1905 1.1 mrg if (!array_extent_fixed) 1906 1.1 mrg { 1907 1.1 mrg /* In an array extent now. */ 1908 1.1 mrg in_array_ref = true; 1909 1.1 mrg /* The dst is not reallocatable, so nothing more 1910 1.1 mrg to do, then correct the dim counter. */ 1911 1.1 mrg dst_cur_dim = i; 1912 1.1 mrg } 1913 1.1 mrg else 1914 1.1 mrg { 1915 1.1 mrg caf_internal_error (doublearrayref, stat, NULL, 1916 1.1 mrg 0); 1917 1.1 mrg return; 1918 1.1 mrg } 1919 1.1 mrg } 1920 1.1 mrg /* When the realloc is required, then no extent may have 1921 1.1 mrg been set. */ 1922 1.1 mrg extent_mismatch = realloc_required 1923 1.1 mrg || GFC_DESCRIPTOR_EXTENT (dst, dst_cur_dim) != delta; 1924 1.1 mrg /* When it is already known, that a realloc is needed or 1925 1.1 mrg the extent does not match the needed one. */ 1926 1.1 mrg if (realloc_required || realloc_needed 1927 1.1 mrg || extent_mismatch) 1928 1.1 mrg { 1929 1.1 mrg /* Check whether dst is reallocatable. */ 1930 1.1 mrg if (unlikely (!dst_reallocatable)) 1931 1.1 mrg { 1932 1.1 mrg caf_internal_error (nonallocextentmismatch, stat, 1933 1.1 mrg NULL, 0, delta, 1934 1.1 mrg GFC_DESCRIPTOR_EXTENT (dst, 1935 1.1 mrg dst_cur_dim)); 1936 1.1 mrg return; 1937 1.1 mrg } 1938 1.1 mrg /* Only report an error, when the extent needs to be 1939 1.1 mrg modified, which is not allowed. */ 1940 1.1 mrg else if (!dst_reallocatable && extent_mismatch) 1941 1.1 mrg { 1942 1.1 mrg caf_internal_error (extentoutofrange, stat, NULL, 1943 1.1 mrg 0); 1944 1.1 mrg return; 1945 1.1 mrg } 1946 1.1 mrg realloc_needed = true; 1947 1.1 mrg } 1948 1.1 mrg /* Only change the extent when it does not match. This is 1949 1.1 mrg to prevent resetting given array bounds. */ 1950 1.1 mrg if (extent_mismatch) 1951 1.1 mrg GFC_DIMENSION_SET (dst->dim[dst_cur_dim], 1, delta, 1952 1.1 mrg size); 1953 1.1 mrg } 1954 1.1 mrg /* Only increase the dim counter, when in an array ref. */ 1955 1.1 mrg if (in_array_ref && dst_cur_dim < dst_rank) 1956 1.1 mrg ++dst_cur_dim; 1957 1.1 mrg } 1958 1.1 mrg size *= (index_type)delta; 1959 1.1 mrg } 1960 1.1 mrg if (in_array_ref) 1961 1.1 mrg { 1962 1.1 mrg array_extent_fixed = true; 1963 1.1 mrg in_array_ref = false; 1964 1.1 mrg /* Check, if we got less dimensional refs than the rank of dst 1965 1.1 mrg expects. */ 1966 1.1 mrg assert (dst_cur_dim == GFC_DESCRIPTOR_RANK (dst)); 1967 1.1 mrg } 1968 1.1 mrg break; 1969 1.1 mrg default: 1970 1.1 mrg caf_internal_error (unknownreftype, stat, NULL, 0); 1971 1.1 mrg return; 1972 1.1 mrg } 1973 1.1 mrg src_size = riter->item_size; 1974 1.1 mrg riter = riter->next; 1975 1.1 mrg } 1976 1.1 mrg if (size == 0 || src_size == 0) 1977 1.1 mrg return; 1978 1.1 mrg /* Postcondition: 1979 1.1 mrg - size contains the number of elements to store in the destination array, 1980 1.1 mrg - src_size gives the size in bytes of each item in the destination array. 1981 1.1 mrg */ 1982 1.1 mrg 1983 1.1 mrg if (realloc_needed) 1984 1.1 mrg { 1985 1.1 mrg if (!array_extent_fixed) 1986 1.1 mrg { 1987 1.1 mrg assert (size == 1); 1988 1.1 mrg /* Special mode when called by __caf_sendget_by_ref (). */ 1989 1.1 mrg if (dst_rank == -1 && GFC_DESCRIPTOR_DATA (dst) == NULL) 1990 1.1 mrg { 1991 1.1 mrg dst_rank = dst_cur_dim + 1; 1992 1.1 mrg GFC_DESCRIPTOR_RANK (dst) = dst_rank; 1993 1.1 mrg GFC_DESCRIPTOR_SIZE (dst) = dst_kind; 1994 1.1 mrg } 1995 1.1 mrg /* This can happen only, when the result is scalar. */ 1996 1.1 mrg for (dst_cur_dim = 0; dst_cur_dim < dst_rank; ++dst_cur_dim) 1997 1.1 mrg GFC_DIMENSION_SET (dst->dim[dst_cur_dim], 1, 1, 1); 1998 1.1 mrg } 1999 1.1 mrg 2000 1.1 mrg GFC_DESCRIPTOR_DATA (dst) = malloc (size * GFC_DESCRIPTOR_SIZE (dst)); 2001 1.1 mrg if (unlikely (GFC_DESCRIPTOR_DATA (dst) == NULL)) 2002 1.1 mrg { 2003 1.1 mrg caf_internal_error (cannotallocdst, stat, NULL, 0); 2004 1.1 mrg return; 2005 1.1 mrg } 2006 1.1 mrg } 2007 1.1 mrg 2008 1.1 mrg /* Reset the token. */ 2009 1.1 mrg single_token = TOKEN (token); 2010 1.1 mrg memptr = single_token->memptr; 2011 1.1 mrg src = single_token->desc; 2012 1.1 mrg memset(dst_index, 0, sizeof (dst_index)); 2013 1.1 mrg i = 0; 2014 1.1 mrg get_for_ref (refs, &i, dst_index, single_token, dst, src, 2015 1.1 mrg GFC_DESCRIPTOR_DATA (dst), memptr, dst_kind, src_kind, 0, 0, 2016 1.1 mrg 1, stat, src_type); 2017 1.1 mrg } 2018 1.1 mrg 2019 1.1 mrg 2020 1.1 mrg static void 2021 1.1 mrg send_by_ref (caf_reference_t *ref, size_t *i, size_t *src_index, 2022 1.1 mrg caf_single_token_t single_token, gfc_descriptor_t *dst, 2023 1.1 mrg gfc_descriptor_t *src, void *ds, void *sr, 2024 1.1 mrg int dst_kind, int src_kind, size_t dst_dim, size_t src_dim, 2025 1.1 mrg size_t num, size_t size, int *stat, int dst_type) 2026 1.1 mrg { 2027 1.1 mrg const char vecrefunknownkind[] = "libcaf_single::caf_send_by_ref(): " 2028 1.1 mrg "unknown kind in vector-ref.\n"; 2029 1.1 mrg ptrdiff_t extent_dst = 1, array_offset_dst = 0, stride_dst; 2030 1.1 mrg const size_t src_rank = GFC_DESCRIPTOR_RANK (src); 2031 1.1 mrg 2032 1.1 mrg if (unlikely (ref == NULL)) 2033 1.1 mrg /* May be we should issue an error here, because this case should not 2034 1.1 mrg occur. */ 2035 1.1 mrg return; 2036 1.1 mrg 2037 1.1 mrg if (ref->next == NULL) 2038 1.1 mrg { 2039 1.1 mrg size_t src_size = GFC_DESCRIPTOR_SIZE (src); 2040 1.1 mrg ptrdiff_t array_offset_src = 0;; 2041 1.1 mrg 2042 1.1 mrg switch (ref->type) 2043 1.1 mrg { 2044 1.1 mrg case CAF_REF_COMPONENT: 2045 1.1 mrg if (ref->u.c.caf_token_offset > 0) 2046 1.1 mrg { 2047 1.1 mrg if (*(void**)(ds + ref->u.c.offset) == NULL) 2048 1.1 mrg { 2049 1.1 mrg /* Create a scalar temporary array descriptor. */ 2050 1.1 mrg gfc_descriptor_t static_dst; 2051 1.1 mrg GFC_DESCRIPTOR_DATA (&static_dst) = NULL; 2052 1.1 mrg GFC_DESCRIPTOR_DTYPE (&static_dst) 2053 1.1 mrg = GFC_DESCRIPTOR_DTYPE (src); 2054 1.1 mrg /* The component can be allocated now, because it is a 2055 1.1 mrg scalar. */ 2056 1.1 mrg _gfortran_caf_register (ref->item_size, 2057 1.1 mrg CAF_REGTYPE_COARRAY_ALLOC, 2058 1.1 mrg ds + ref->u.c.caf_token_offset, 2059 1.1 mrg &static_dst, stat, NULL, 0); 2060 1.1 mrg single_token = *(caf_single_token_t *) 2061 1.1 mrg (ds + ref->u.c.caf_token_offset); 2062 1.1 mrg /* In case of an error in allocation return. When stat is 2063 1.1 mrg NULL, then register_component() terminates on error. */ 2064 1.1 mrg if (stat != NULL && *stat) 2065 1.1 mrg return; 2066 1.1 mrg /* Publish the allocated memory. */ 2067 1.1 mrg *((void **)(ds + ref->u.c.offset)) 2068 1.1 mrg = GFC_DESCRIPTOR_DATA (&static_dst); 2069 1.1 mrg ds = GFC_DESCRIPTOR_DATA (&static_dst); 2070 1.1 mrg /* Set the type from the src. */ 2071 1.1 mrg dst_type = GFC_DESCRIPTOR_TYPE (src); 2072 1.1 mrg } 2073 1.1 mrg else 2074 1.1 mrg { 2075 1.1 mrg single_token = *(caf_single_token_t *) 2076 1.1 mrg (ds + ref->u.c.caf_token_offset); 2077 1.1 mrg dst = single_token->desc; 2078 1.1 mrg if (dst) 2079 1.1 mrg { 2080 1.1 mrg ds = GFC_DESCRIPTOR_DATA (dst); 2081 1.1 mrg dst_type = GFC_DESCRIPTOR_TYPE (dst); 2082 1.1 mrg } 2083 1.1 mrg else 2084 1.1 mrg ds = *(void **)(ds + ref->u.c.offset); 2085 1.1 mrg } 2086 1.1 mrg copy_data (ds, sr, dst_type, GFC_DESCRIPTOR_TYPE (src), 2087 1.1 mrg dst_kind, src_kind, ref->item_size, src_size, 1, stat); 2088 1.1 mrg } 2089 1.1 mrg else 2090 1.1 mrg copy_data (ds + ref->u.c.offset, sr, dst_type, 2091 1.1 mrg GFC_DESCRIPTOR_TYPE (src), 2092 1.1 mrg dst_kind, src_kind, ref->item_size, src_size, 1, stat); 2093 1.1 mrg ++(*i); 2094 1.1 mrg return; 2095 1.1 mrg case CAF_REF_STATIC_ARRAY: 2096 1.1 mrg /* Intentionally fall through. */ 2097 1.1 mrg case CAF_REF_ARRAY: 2098 1.1 mrg if (ref->u.a.mode[dst_dim] == CAF_ARR_REF_NONE) 2099 1.1 mrg { 2100 1.1 mrg if (src_rank > 0) 2101 1.1 mrg { 2102 1.1 mrg for (size_t d = 0; d < src_rank; ++d) 2103 1.1 mrg array_offset_src += src_index[d]; 2104 1.1 mrg copy_data (ds, sr + array_offset_src * src_size, 2105 1.1 mrg dst_type, GFC_DESCRIPTOR_TYPE (src), dst_kind, 2106 1.1 mrg src_kind, ref->item_size, src_size, num, stat); 2107 1.1 mrg } 2108 1.1 mrg else 2109 1.1 mrg copy_data (ds, sr, dst_type, GFC_DESCRIPTOR_TYPE (src), 2110 1.1 mrg dst_kind, src_kind, ref->item_size, src_size, num, 2111 1.1 mrg stat); 2112 1.1 mrg *i += num; 2113 1.1 mrg return; 2114 1.1 mrg } 2115 1.1 mrg break; 2116 1.1 mrg default: 2117 1.1 mrg caf_runtime_error (unreachable); 2118 1.1 mrg } 2119 1.1 mrg } 2120 1.1 mrg 2121 1.1 mrg switch (ref->type) 2122 1.1 mrg { 2123 1.1 mrg case CAF_REF_COMPONENT: 2124 1.1 mrg if (ref->u.c.caf_token_offset > 0) 2125 1.1 mrg { 2126 1.1 mrg if (*(void**)(ds + ref->u.c.offset) == NULL) 2127 1.1 mrg { 2128 1.1 mrg /* This component refs an unallocated array. Non-arrays are 2129 1.1 mrg caught in the if (!ref->next) above. */ 2130 1.1 mrg dst = (gfc_descriptor_t *)(ds + ref->u.c.offset); 2131 1.1 mrg /* Assume that the rank and the dimensions fit for copying src 2132 1.1 mrg to dst. */ 2133 1.1 mrg GFC_DESCRIPTOR_DTYPE (dst) = GFC_DESCRIPTOR_DTYPE (src); 2134 1.1 mrg dst->offset = 0; 2135 1.1 mrg stride_dst = 1; 2136 1.1 mrg for (size_t d = 0; d < src_rank; ++d) 2137 1.1 mrg { 2138 1.1 mrg extent_dst = GFC_DIMENSION_EXTENT (src->dim[d]); 2139 1.1 mrg GFC_DIMENSION_LBOUND (dst->dim[d]) = 0; 2140 1.1 mrg GFC_DIMENSION_UBOUND (dst->dim[d]) = extent_dst - 1; 2141 1.1 mrg GFC_DIMENSION_STRIDE (dst->dim[d]) = stride_dst; 2142 1.1 mrg stride_dst *= extent_dst; 2143 1.1 mrg } 2144 1.1 mrg /* Null the data-pointer to make register_component allocate 2145 1.1 mrg its own memory. */ 2146 1.1 mrg GFC_DESCRIPTOR_DATA (dst) = NULL; 2147 1.1 mrg 2148 1.1 mrg /* The size of the array is given by size. */ 2149 1.1 mrg _gfortran_caf_register (size * ref->item_size, 2150 1.1 mrg CAF_REGTYPE_COARRAY_ALLOC, 2151 1.1 mrg ds + ref->u.c.caf_token_offset, 2152 1.1 mrg dst, stat, NULL, 0); 2153 1.1 mrg /* In case of an error in allocation return. When stat is 2154 1.1 mrg NULL, then register_component() terminates on error. */ 2155 1.1 mrg if (stat != NULL && *stat) 2156 1.1 mrg return; 2157 1.1 mrg } 2158 1.1 mrg single_token = *(caf_single_token_t*)(ds + ref->u.c.caf_token_offset); 2159 1.1 mrg /* When a component is allocatable (caf_token_offset != 0) and not an 2160 1.1 mrg array (ref->next->type == CAF_REF_COMPONENT), then ds has to be 2161 1.1 mrg dereffed. */ 2162 1.1 mrg if (ref->next && ref->next->type == CAF_REF_COMPONENT) 2163 1.1 mrg ds = *(void **)(ds + ref->u.c.offset); 2164 1.1 mrg else 2165 1.1 mrg ds += ref->u.c.offset; 2166 1.1 mrg 2167 1.1 mrg send_by_ref (ref->next, i, src_index, single_token, 2168 1.1 mrg single_token->desc, src, ds, sr, 2169 1.1 mrg dst_kind, src_kind, 0, src_dim, 1, size, stat, dst_type); 2170 1.1 mrg } 2171 1.1 mrg else 2172 1.1 mrg send_by_ref (ref->next, i, src_index, single_token, 2173 1.1 mrg (gfc_descriptor_t *)(ds + ref->u.c.offset), src, 2174 1.1 mrg ds + ref->u.c.offset, sr, dst_kind, src_kind, 0, src_dim, 2175 1.1 mrg 1, size, stat, dst_type); 2176 1.1 mrg return; 2177 1.1 mrg case CAF_REF_ARRAY: 2178 1.1 mrg if (ref->u.a.mode[dst_dim] == CAF_ARR_REF_NONE) 2179 1.1 mrg { 2180 1.1 mrg send_by_ref (ref->next, i, src_index, single_token, 2181 1.1 mrg (gfc_descriptor_t *)ds, src, ds, sr, dst_kind, src_kind, 2182 1.1 mrg 0, src_dim, 1, size, stat, dst_type); 2183 1.1 mrg return; 2184 1.1 mrg } 2185 1.1 mrg /* Only when on the left most index switch the data pointer to 2186 1.1 mrg the array's data pointer. And only for non-static arrays. */ 2187 1.1 mrg if (dst_dim == 0 && ref->type != CAF_REF_STATIC_ARRAY) 2188 1.1 mrg ds = GFC_DESCRIPTOR_DATA (dst); 2189 1.1 mrg switch (ref->u.a.mode[dst_dim]) 2190 1.1 mrg { 2191 1.1 mrg case CAF_ARR_REF_VECTOR: 2192 1.1 mrg array_offset_dst = 0; 2193 1.1 mrg src_index[src_dim] = 0; 2194 1.1 mrg for (size_t idx = 0; idx < ref->u.a.dim[dst_dim].v.nvec; 2195 1.1 mrg ++idx) 2196 1.1 mrg { 2197 1.1 mrg #define KINDCASE(kind, type) case kind: \ 2198 1.1 mrg array_offset_dst = (((index_type) \ 2199 1.1 mrg ((type *)ref->u.a.dim[dst_dim].v.vector)[idx]) \ 2200 1.1 mrg - GFC_DIMENSION_LBOUND (dst->dim[dst_dim])) \ 2201 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); \ 2202 1.1 mrg break 2203 1.1 mrg 2204 1.1 mrg switch (ref->u.a.dim[dst_dim].v.kind) 2205 1.1 mrg { 2206 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 2207 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 2208 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 2209 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 2210 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 2211 1.1 mrg #endif 2212 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 2213 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 2214 1.1 mrg #endif 2215 1.1 mrg default: 2216 1.1 mrg caf_internal_error (vecrefunknownkind, stat, NULL, 0); 2217 1.1 mrg return; 2218 1.1 mrg } 2219 1.1 mrg #undef KINDCASE 2220 1.1 mrg 2221 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, 2222 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2223 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2224 1.1 mrg 1, size, stat, dst_type); 2225 1.1 mrg if (src_rank > 0) 2226 1.1 mrg src_index[src_dim] 2227 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2228 1.1 mrg } 2229 1.1 mrg return; 2230 1.1 mrg case CAF_ARR_REF_FULL: 2231 1.1 mrg COMPUTE_NUM_ITEMS (extent_dst, 2232 1.1 mrg ref->u.a.dim[dst_dim].s.stride, 2233 1.1 mrg GFC_DIMENSION_LBOUND (dst->dim[dst_dim]), 2234 1.1 mrg GFC_DIMENSION_UBOUND (dst->dim[dst_dim])); 2235 1.1 mrg array_offset_dst = 0; 2236 1.1 mrg stride_dst = GFC_DIMENSION_STRIDE (dst->dim[dst_dim]) 2237 1.1 mrg * ref->u.a.dim[dst_dim].s.stride; 2238 1.1 mrg src_index[src_dim] = 0; 2239 1.1 mrg for (index_type idx = 0; idx < extent_dst; 2240 1.1 mrg ++idx, array_offset_dst += stride_dst) 2241 1.1 mrg { 2242 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, 2243 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2244 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2245 1.1 mrg 1, size, stat, dst_type); 2246 1.1 mrg if (src_rank > 0) 2247 1.1 mrg src_index[src_dim] 2248 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2249 1.1 mrg } 2250 1.1 mrg return; 2251 1.1 mrg case CAF_ARR_REF_RANGE: 2252 1.1 mrg COMPUTE_NUM_ITEMS (extent_dst, 2253 1.1 mrg ref->u.a.dim[dst_dim].s.stride, 2254 1.1 mrg ref->u.a.dim[dst_dim].s.start, 2255 1.1 mrg ref->u.a.dim[dst_dim].s.end); 2256 1.1 mrg array_offset_dst = ref->u.a.dim[dst_dim].s.start 2257 1.1 mrg - GFC_DIMENSION_LBOUND (dst->dim[dst_dim]); 2258 1.1 mrg stride_dst = GFC_DIMENSION_STRIDE (dst->dim[dst_dim]) 2259 1.1 mrg * ref->u.a.dim[dst_dim].s.stride; 2260 1.1 mrg src_index[src_dim] = 0; 2261 1.1 mrg for (index_type idx = 0; idx < extent_dst; ++idx) 2262 1.1 mrg { 2263 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, 2264 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2265 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2266 1.1 mrg 1, size, stat, dst_type); 2267 1.1 mrg if (src_rank > 0) 2268 1.1 mrg src_index[src_dim] 2269 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2270 1.1 mrg array_offset_dst += stride_dst; 2271 1.1 mrg } 2272 1.1 mrg return; 2273 1.1 mrg case CAF_ARR_REF_SINGLE: 2274 1.1 mrg array_offset_dst = (ref->u.a.dim[dst_dim].s.start 2275 1.1 mrg - GFC_DIMENSION_LBOUND (dst->dim[dst_dim])) 2276 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[dst_dim]); 2277 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, ds 2278 1.1 mrg + array_offset_dst * ref->item_size, sr, 2279 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim, 1, 2280 1.1 mrg size, stat, dst_type); 2281 1.1 mrg return; 2282 1.1 mrg case CAF_ARR_REF_OPEN_END: 2283 1.1 mrg COMPUTE_NUM_ITEMS (extent_dst, 2284 1.1 mrg ref->u.a.dim[dst_dim].s.stride, 2285 1.1 mrg ref->u.a.dim[dst_dim].s.start, 2286 1.1 mrg GFC_DIMENSION_UBOUND (dst->dim[dst_dim])); 2287 1.1 mrg array_offset_dst = ref->u.a.dim[dst_dim].s.start 2288 1.1 mrg - GFC_DIMENSION_LBOUND (dst->dim[dst_dim]); 2289 1.1 mrg stride_dst = GFC_DIMENSION_STRIDE (dst->dim[dst_dim]) 2290 1.1 mrg * ref->u.a.dim[dst_dim].s.stride; 2291 1.1 mrg src_index[src_dim] = 0; 2292 1.1 mrg for (index_type idx = 0; idx < extent_dst; ++idx) 2293 1.1 mrg { 2294 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, 2295 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2296 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2297 1.1 mrg 1, size, stat, dst_type); 2298 1.1 mrg if (src_rank > 0) 2299 1.1 mrg src_index[src_dim] 2300 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2301 1.1 mrg array_offset_dst += stride_dst; 2302 1.1 mrg } 2303 1.1 mrg return; 2304 1.1 mrg case CAF_ARR_REF_OPEN_START: 2305 1.1 mrg COMPUTE_NUM_ITEMS (extent_dst, 2306 1.1 mrg ref->u.a.dim[dst_dim].s.stride, 2307 1.1 mrg GFC_DIMENSION_LBOUND (dst->dim[dst_dim]), 2308 1.1 mrg ref->u.a.dim[dst_dim].s.end); 2309 1.1 mrg array_offset_dst = 0; 2310 1.1 mrg stride_dst = GFC_DIMENSION_STRIDE (dst->dim[dst_dim]) 2311 1.1 mrg * ref->u.a.dim[dst_dim].s.stride; 2312 1.1 mrg src_index[src_dim] = 0; 2313 1.1 mrg for (index_type idx = 0; idx < extent_dst; ++idx) 2314 1.1 mrg { 2315 1.1 mrg send_by_ref (ref, i, src_index, single_token, dst, src, 2316 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2317 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2318 1.1 mrg 1, size, stat, dst_type); 2319 1.1 mrg if (src_rank > 0) 2320 1.1 mrg src_index[src_dim] 2321 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2322 1.1 mrg array_offset_dst += stride_dst; 2323 1.1 mrg } 2324 1.1 mrg return; 2325 1.1 mrg default: 2326 1.1 mrg caf_runtime_error (unreachable); 2327 1.1 mrg } 2328 1.1 mrg return; 2329 1.1 mrg case CAF_REF_STATIC_ARRAY: 2330 1.1 mrg if (ref->u.a.mode[dst_dim] == CAF_ARR_REF_NONE) 2331 1.1 mrg { 2332 1.1 mrg send_by_ref (ref->next, i, src_index, single_token, NULL, 2333 1.1 mrg src, ds, sr, dst_kind, src_kind, 2334 1.1 mrg 0, src_dim, 1, size, stat, dst_type); 2335 1.1 mrg return; 2336 1.1 mrg } 2337 1.1 mrg switch (ref->u.a.mode[dst_dim]) 2338 1.1 mrg { 2339 1.1 mrg case CAF_ARR_REF_VECTOR: 2340 1.1 mrg array_offset_dst = 0; 2341 1.1 mrg src_index[src_dim] = 0; 2342 1.1 mrg for (size_t idx = 0; idx < ref->u.a.dim[dst_dim].v.nvec; 2343 1.1 mrg ++idx) 2344 1.1 mrg { 2345 1.1 mrg #define KINDCASE(kind, type) case kind: \ 2346 1.1 mrg array_offset_dst = ((type *)ref->u.a.dim[dst_dim].v.vector)[idx]; \ 2347 1.1 mrg break 2348 1.1 mrg 2349 1.1 mrg switch (ref->u.a.dim[dst_dim].v.kind) 2350 1.1 mrg { 2351 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 2352 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 2353 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 2354 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 2355 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 2356 1.1 mrg #endif 2357 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 2358 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 2359 1.1 mrg #endif 2360 1.1 mrg default: 2361 1.1 mrg caf_runtime_error (unreachable); 2362 1.1 mrg return; 2363 1.1 mrg } 2364 1.1 mrg #undef KINDCASE 2365 1.1 mrg 2366 1.1 mrg send_by_ref (ref, i, src_index, single_token, NULL, src, 2367 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2368 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2369 1.1 mrg 1, size, stat, dst_type); 2370 1.1 mrg src_index[src_dim] 2371 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2372 1.1 mrg } 2373 1.1 mrg return; 2374 1.1 mrg case CAF_ARR_REF_FULL: 2375 1.1 mrg src_index[src_dim] = 0; 2376 1.1 mrg for (array_offset_dst = 0 ; 2377 1.1 mrg array_offset_dst <= ref->u.a.dim[dst_dim].s.end; 2378 1.1 mrg array_offset_dst += ref->u.a.dim[dst_dim].s.stride) 2379 1.1 mrg { 2380 1.1 mrg send_by_ref (ref, i, src_index, single_token, NULL, src, 2381 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2382 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2383 1.1 mrg 1, size, stat, dst_type); 2384 1.1 mrg if (src_rank > 0) 2385 1.1 mrg src_index[src_dim] 2386 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2387 1.1 mrg } 2388 1.1 mrg return; 2389 1.1 mrg case CAF_ARR_REF_RANGE: 2390 1.1 mrg COMPUTE_NUM_ITEMS (extent_dst, 2391 1.1 mrg ref->u.a.dim[dst_dim].s.stride, 2392 1.1 mrg ref->u.a.dim[dst_dim].s.start, 2393 1.1 mrg ref->u.a.dim[dst_dim].s.end); 2394 1.1 mrg array_offset_dst = ref->u.a.dim[dst_dim].s.start; 2395 1.1 mrg src_index[src_dim] = 0; 2396 1.1 mrg for (index_type idx = 0; idx < extent_dst; ++idx) 2397 1.1 mrg { 2398 1.1 mrg send_by_ref (ref, i, src_index, single_token, NULL, src, 2399 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2400 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim + 1, 2401 1.1 mrg 1, size, stat, dst_type); 2402 1.1 mrg if (src_rank > 0) 2403 1.1 mrg src_index[src_dim] 2404 1.1 mrg += GFC_DIMENSION_STRIDE (src->dim[src_dim]); 2405 1.1 mrg array_offset_dst += ref->u.a.dim[dst_dim].s.stride; 2406 1.1 mrg } 2407 1.1 mrg return; 2408 1.1 mrg case CAF_ARR_REF_SINGLE: 2409 1.1 mrg array_offset_dst = ref->u.a.dim[dst_dim].s.start; 2410 1.1 mrg send_by_ref (ref, i, src_index, single_token, NULL, src, 2411 1.1 mrg ds + array_offset_dst * ref->item_size, sr, 2412 1.1 mrg dst_kind, src_kind, dst_dim + 1, src_dim, 1, 2413 1.1 mrg size, stat, dst_type); 2414 1.1 mrg return; 2415 1.1 mrg /* The OPEN_* are mapped to a RANGE and therefore cannot occur. */ 2416 1.1 mrg case CAF_ARR_REF_OPEN_END: 2417 1.1 mrg case CAF_ARR_REF_OPEN_START: 2418 1.1 mrg default: 2419 1.1 mrg caf_runtime_error (unreachable); 2420 1.1 mrg } 2421 1.1 mrg return; 2422 1.1 mrg default: 2423 1.1 mrg caf_runtime_error (unreachable); 2424 1.1 mrg } 2425 1.1 mrg } 2426 1.1 mrg 2427 1.1 mrg 2428 1.1 mrg void 2429 1.1 mrg _gfortran_caf_send_by_ref (caf_token_t token, 2430 1.1 mrg int image_index __attribute__ ((unused)), 2431 1.1 mrg gfc_descriptor_t *src, caf_reference_t *refs, 2432 1.1 mrg int dst_kind, int src_kind, 2433 1.1 mrg bool may_require_tmp __attribute__ ((unused)), 2434 1.1 mrg bool dst_reallocatable, int *stat, int dst_type) 2435 1.1 mrg { 2436 1.1 mrg const char vecrefunknownkind[] = "libcaf_single::caf_get_by_ref(): " 2437 1.1 mrg "unknown kind in vector-ref.\n"; 2438 1.1 mrg const char unknownreftype[] = "libcaf_single::caf_send_by_ref(): " 2439 1.1 mrg "unknown reference type.\n"; 2440 1.1 mrg const char unknownarrreftype[] = "libcaf_single::caf_send_by_ref(): " 2441 1.1 mrg "unknown array reference type.\n"; 2442 1.1 mrg const char rankoutofrange[] = "libcaf_single::caf_send_by_ref(): " 2443 1.1 mrg "rank out of range.\n"; 2444 1.1 mrg const char realloconinnerref[] = "libcaf_single::caf_send_by_ref(): " 2445 1.1 mrg "reallocation of array followed by component ref not allowed.\n"; 2446 1.1 mrg const char cannotallocdst[] = "libcaf_single::caf_send_by_ref(): " 2447 1.1 mrg "cannot allocate memory.\n"; 2448 1.1 mrg const char nonallocextentmismatch[] = "libcaf_single::caf_send_by_ref(): " 2449 1.1 mrg "extent of non-allocatable array mismatch.\n"; 2450 1.1 mrg const char innercompref[] = "libcaf_single::caf_send_by_ref(): " 2451 1.1 mrg "inner unallocated component detected.\n"; 2452 1.1 mrg size_t size, i; 2453 1.1 mrg size_t dst_index[GFC_MAX_DIMENSIONS]; 2454 1.1 mrg int src_rank = GFC_DESCRIPTOR_RANK (src); 2455 1.1 mrg int src_cur_dim = 0; 2456 1.1 mrg size_t src_size = 0; 2457 1.1 mrg caf_single_token_t single_token = TOKEN (token); 2458 1.1 mrg void *memptr = single_token->memptr; 2459 1.1 mrg gfc_descriptor_t *dst = single_token->desc; 2460 1.1 mrg caf_reference_t *riter = refs; 2461 1.1 mrg long delta; 2462 1.1 mrg bool extent_mismatch; 2463 1.1 mrg /* Note that the component is not allocated yet. */ 2464 1.1 mrg index_type new_component_idx = -1; 2465 1.1 mrg 2466 1.1 mrg if (stat) 2467 1.1 mrg *stat = 0; 2468 1.1 mrg 2469 1.1 mrg /* Compute the size of the result. In the beginning size just counts the 2470 1.1 mrg number of elements. */ 2471 1.1 mrg size = 1; 2472 1.1 mrg while (riter) 2473 1.1 mrg { 2474 1.1 mrg switch (riter->type) 2475 1.1 mrg { 2476 1.1 mrg case CAF_REF_COMPONENT: 2477 1.1 mrg if (unlikely (new_component_idx != -1)) 2478 1.1 mrg { 2479 1.1 mrg /* Allocating a component in the middle of a component ref is not 2480 1.1 mrg support. We don't know the type to allocate. */ 2481 1.1 mrg caf_internal_error (innercompref, stat, NULL, 0); 2482 1.1 mrg return; 2483 1.1 mrg } 2484 1.1 mrg if (riter->u.c.caf_token_offset > 0) 2485 1.1 mrg { 2486 1.1 mrg /* Check whether the allocatable component is zero, then no 2487 1.1 mrg token is present, too. The token's pointer is not cleared 2488 1.1 mrg when the structure is initialized. */ 2489 1.1 mrg if (*(void**)(memptr + riter->u.c.offset) == NULL) 2490 1.1 mrg { 2491 1.1 mrg /* This component is not yet allocated. Check that it is 2492 1.1 mrg allocatable here. */ 2493 1.1 mrg if (!dst_reallocatable) 2494 1.1 mrg { 2495 1.1 mrg caf_internal_error (cannotallocdst, stat, NULL, 0); 2496 1.1 mrg return; 2497 1.1 mrg } 2498 1.1 mrg single_token = NULL; 2499 1.1 mrg memptr = NULL; 2500 1.1 mrg dst = NULL; 2501 1.1 mrg break; 2502 1.1 mrg } 2503 1.1 mrg single_token = *(caf_single_token_t*) 2504 1.1 mrg (memptr + riter->u.c.caf_token_offset); 2505 1.1 mrg memptr += riter->u.c.offset; 2506 1.1 mrg dst = single_token->desc; 2507 1.1 mrg } 2508 1.1 mrg else 2509 1.1 mrg { 2510 1.1 mrg /* Regular component. */ 2511 1.1 mrg memptr += riter->u.c.offset; 2512 1.1 mrg dst = (gfc_descriptor_t *)memptr; 2513 1.1 mrg } 2514 1.1 mrg break; 2515 1.1 mrg case CAF_REF_ARRAY: 2516 1.1 mrg if (dst != NULL) 2517 1.1 mrg memptr = GFC_DESCRIPTOR_DATA (dst); 2518 1.1 mrg else 2519 1.1 mrg dst = src; 2520 1.1 mrg /* When the dst array needs to be allocated, then look at the 2521 1.1 mrg extent of the source array in the dimension dst_cur_dim. */ 2522 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 2523 1.1 mrg { 2524 1.1 mrg switch (riter->u.a.mode[i]) 2525 1.1 mrg { 2526 1.1 mrg case CAF_ARR_REF_VECTOR: 2527 1.1 mrg delta = riter->u.a.dim[i].v.nvec; 2528 1.1 mrg #define KINDCASE(kind, type) case kind: \ 2529 1.1 mrg memptr += (((index_type) \ 2530 1.1 mrg ((type *)riter->u.a.dim[i].v.vector)[0]) \ 2531 1.1 mrg - GFC_DIMENSION_LBOUND (dst->dim[i])) \ 2532 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[i]) \ 2533 1.1 mrg * riter->item_size; \ 2534 1.1 mrg break 2535 1.1 mrg 2536 1.1 mrg switch (riter->u.a.dim[i].v.kind) 2537 1.1 mrg { 2538 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 2539 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 2540 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 2541 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 2542 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 2543 1.1 mrg #endif 2544 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 2545 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 2546 1.1 mrg #endif 2547 1.1 mrg default: 2548 1.1 mrg caf_internal_error (vecrefunknownkind, stat, NULL, 0); 2549 1.1 mrg return; 2550 1.1 mrg } 2551 1.1 mrg #undef KINDCASE 2552 1.1 mrg break; 2553 1.1 mrg case CAF_ARR_REF_FULL: 2554 1.1 mrg if (dst) 2555 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2556 1.1 mrg riter->u.a.dim[i].s.stride, 2557 1.1 mrg GFC_DIMENSION_LBOUND (dst->dim[i]), 2558 1.1 mrg GFC_DIMENSION_UBOUND (dst->dim[i])); 2559 1.1 mrg else 2560 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2561 1.1 mrg riter->u.a.dim[i].s.stride, 2562 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[src_cur_dim]), 2563 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[src_cur_dim])); 2564 1.1 mrg break; 2565 1.1 mrg case CAF_ARR_REF_RANGE: 2566 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2567 1.1 mrg riter->u.a.dim[i].s.stride, 2568 1.1 mrg riter->u.a.dim[i].s.start, 2569 1.1 mrg riter->u.a.dim[i].s.end); 2570 1.1 mrg memptr += (riter->u.a.dim[i].s.start 2571 1.1 mrg - dst->dim[i].lower_bound) 2572 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[i]) 2573 1.1 mrg * riter->item_size; 2574 1.1 mrg break; 2575 1.1 mrg case CAF_ARR_REF_SINGLE: 2576 1.1 mrg delta = 1; 2577 1.1 mrg memptr += (riter->u.a.dim[i].s.start 2578 1.1 mrg - dst->dim[i].lower_bound) 2579 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[i]) 2580 1.1 mrg * riter->item_size; 2581 1.1 mrg break; 2582 1.1 mrg case CAF_ARR_REF_OPEN_END: 2583 1.1 mrg if (dst) 2584 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2585 1.1 mrg riter->u.a.dim[i].s.stride, 2586 1.1 mrg riter->u.a.dim[i].s.start, 2587 1.1 mrg GFC_DIMENSION_UBOUND (dst->dim[i])); 2588 1.1 mrg else 2589 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2590 1.1 mrg riter->u.a.dim[i].s.stride, 2591 1.1 mrg riter->u.a.dim[i].s.start, 2592 1.1 mrg GFC_DIMENSION_UBOUND (src->dim[src_cur_dim])); 2593 1.1 mrg memptr += (riter->u.a.dim[i].s.start 2594 1.1 mrg - dst->dim[i].lower_bound) 2595 1.1 mrg * GFC_DIMENSION_STRIDE (dst->dim[i]) 2596 1.1 mrg * riter->item_size; 2597 1.1 mrg break; 2598 1.1 mrg case CAF_ARR_REF_OPEN_START: 2599 1.1 mrg if (dst) 2600 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2601 1.1 mrg riter->u.a.dim[i].s.stride, 2602 1.1 mrg GFC_DIMENSION_LBOUND (dst->dim[i]), 2603 1.1 mrg riter->u.a.dim[i].s.end); 2604 1.1 mrg else 2605 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2606 1.1 mrg riter->u.a.dim[i].s.stride, 2607 1.1 mrg GFC_DIMENSION_LBOUND (src->dim[src_cur_dim]), 2608 1.1 mrg riter->u.a.dim[i].s.end); 2609 1.1 mrg /* The memptr stays unchanged when ref'ing the first element 2610 1.1 mrg in a dimension. */ 2611 1.1 mrg break; 2612 1.1 mrg default: 2613 1.1 mrg caf_internal_error (unknownarrreftype, stat, NULL, 0); 2614 1.1 mrg return; 2615 1.1 mrg } 2616 1.1 mrg 2617 1.1 mrg if (delta <= 0) 2618 1.1 mrg return; 2619 1.1 mrg /* Check the various properties of the source array. 2620 1.1 mrg When src is an array. */ 2621 1.1 mrg if (delta > 1 && src_rank > 0) 2622 1.1 mrg { 2623 1.1 mrg /* Check that src_cur_dim is valid for src. Can be 2624 1.1 mrg superceeded only by scalar data. */ 2625 1.1 mrg if (src_cur_dim >= src_rank) 2626 1.1 mrg { 2627 1.1 mrg caf_internal_error (rankoutofrange, stat, NULL, 0); 2628 1.1 mrg return; 2629 1.1 mrg } 2630 1.1 mrg /* Do further checks, when the source is not scalar. */ 2631 1.1 mrg else 2632 1.1 mrg { 2633 1.1 mrg /* When the realloc is required, then no extent may have 2634 1.1 mrg been set. */ 2635 1.1 mrg extent_mismatch = memptr == NULL 2636 1.1 mrg || (dst 2637 1.1 mrg && GFC_DESCRIPTOR_EXTENT (dst, src_cur_dim) 2638 1.1 mrg != delta); 2639 1.1 mrg /* When it already known, that a realloc is needed or 2640 1.1 mrg the extent does not match the needed one. */ 2641 1.1 mrg if (extent_mismatch) 2642 1.1 mrg { 2643 1.1 mrg /* Check whether dst is reallocatable. */ 2644 1.1 mrg if (unlikely (!dst_reallocatable)) 2645 1.1 mrg { 2646 1.1 mrg caf_internal_error (nonallocextentmismatch, stat, 2647 1.1 mrg NULL, 0, delta, 2648 1.1 mrg GFC_DESCRIPTOR_EXTENT (dst, 2649 1.1 mrg src_cur_dim)); 2650 1.1 mrg return; 2651 1.1 mrg } 2652 1.1 mrg /* Report error on allocatable but missing inner 2653 1.1 mrg ref. */ 2654 1.1 mrg else if (riter->next != NULL) 2655 1.1 mrg { 2656 1.1 mrg caf_internal_error (realloconinnerref, stat, NULL, 2657 1.1 mrg 0); 2658 1.1 mrg return; 2659 1.1 mrg } 2660 1.1 mrg } 2661 1.1 mrg /* Only change the extent when it does not match. This is 2662 1.1 mrg to prevent resetting given array bounds. */ 2663 1.1 mrg if (extent_mismatch) 2664 1.1 mrg GFC_DIMENSION_SET (dst->dim[src_cur_dim], 1, delta, 2665 1.1 mrg size); 2666 1.1 mrg } 2667 1.1 mrg /* Increase the dim-counter of the src only when the extent 2668 1.1 mrg matches. */ 2669 1.1 mrg if (src_cur_dim < src_rank 2670 1.1 mrg && GFC_DESCRIPTOR_EXTENT (src, src_cur_dim) == delta) 2671 1.1 mrg ++src_cur_dim; 2672 1.1 mrg } 2673 1.1 mrg size *= (index_type)delta; 2674 1.1 mrg } 2675 1.1 mrg break; 2676 1.1 mrg case CAF_REF_STATIC_ARRAY: 2677 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 2678 1.1 mrg { 2679 1.1 mrg switch (riter->u.a.mode[i]) 2680 1.1 mrg { 2681 1.1 mrg case CAF_ARR_REF_VECTOR: 2682 1.1 mrg delta = riter->u.a.dim[i].v.nvec; 2683 1.1 mrg #define KINDCASE(kind, type) case kind: \ 2684 1.1 mrg memptr += ((type *)riter->u.a.dim[i].v.vector)[0] \ 2685 1.1 mrg * riter->item_size; \ 2686 1.1 mrg break 2687 1.1 mrg 2688 1.1 mrg switch (riter->u.a.dim[i].v.kind) 2689 1.1 mrg { 2690 1.1 mrg KINDCASE (1, GFC_INTEGER_1); 2691 1.1 mrg KINDCASE (2, GFC_INTEGER_2); 2692 1.1 mrg KINDCASE (4, GFC_INTEGER_4); 2693 1.1 mrg #ifdef HAVE_GFC_INTEGER_8 2694 1.1 mrg KINDCASE (8, GFC_INTEGER_8); 2695 1.1 mrg #endif 2696 1.1 mrg #ifdef HAVE_GFC_INTEGER_16 2697 1.1 mrg KINDCASE (16, GFC_INTEGER_16); 2698 1.1 mrg #endif 2699 1.1 mrg default: 2700 1.1 mrg caf_internal_error (vecrefunknownkind, stat, NULL, 0); 2701 1.1 mrg return; 2702 1.1 mrg } 2703 1.1 mrg #undef KINDCASE 2704 1.1 mrg break; 2705 1.1 mrg case CAF_ARR_REF_FULL: 2706 1.1 mrg delta = riter->u.a.dim[i].s.end / riter->u.a.dim[i].s.stride 2707 1.1 mrg + 1; 2708 1.1 mrg /* The memptr stays unchanged when ref'ing the first element 2709 1.1 mrg in a dimension. */ 2710 1.1 mrg break; 2711 1.1 mrg case CAF_ARR_REF_RANGE: 2712 1.1 mrg COMPUTE_NUM_ITEMS (delta, 2713 1.1 mrg riter->u.a.dim[i].s.stride, 2714 1.1 mrg riter->u.a.dim[i].s.start, 2715 1.1 mrg riter->u.a.dim[i].s.end); 2716 1.1 mrg memptr += riter->u.a.dim[i].s.start 2717 1.1 mrg * riter->u.a.dim[i].s.stride 2718 1.1 mrg * riter->item_size; 2719 1.1 mrg break; 2720 1.1 mrg case CAF_ARR_REF_SINGLE: 2721 1.1 mrg delta = 1; 2722 1.1 mrg memptr += riter->u.a.dim[i].s.start 2723 1.1 mrg * riter->u.a.dim[i].s.stride 2724 1.1 mrg * riter->item_size; 2725 1.1 mrg break; 2726 1.1 mrg case CAF_ARR_REF_OPEN_END: 2727 1.1 mrg /* This and OPEN_START are mapped to a RANGE and therefore 2728 1.1 mrg cannot occur here. */ 2729 1.1 mrg case CAF_ARR_REF_OPEN_START: 2730 1.1 mrg default: 2731 1.1 mrg caf_internal_error (unknownarrreftype, stat, NULL, 0); 2732 1.1 mrg return; 2733 1.1 mrg } 2734 1.1 mrg if (delta <= 0) 2735 1.1 mrg return; 2736 1.1 mrg /* Check the various properties of the source array. 2737 1.1 mrg Only when the source array is not scalar examine its 2738 1.1 mrg properties. */ 2739 1.1 mrg if (delta > 1 && src_rank > 0) 2740 1.1 mrg { 2741 1.1 mrg /* Check that src_cur_dim is valid for src. Can be 2742 1.1 mrg superceeded only by scalar data. */ 2743 1.1 mrg if (src_cur_dim >= src_rank) 2744 1.1 mrg { 2745 1.1 mrg caf_internal_error (rankoutofrange, stat, NULL, 0); 2746 1.1 mrg return; 2747 1.1 mrg } 2748 1.1 mrg else 2749 1.1 mrg { 2750 1.1 mrg /* We will not be able to realloc the dst, because that's 2751 1.1 mrg a fixed size array. */ 2752 1.1 mrg extent_mismatch = GFC_DESCRIPTOR_EXTENT (src, src_cur_dim) 2753 1.1 mrg != delta; 2754 1.1 mrg /* When the extent does not match the needed one we can 2755 1.1 mrg only stop here. */ 2756 1.1 mrg if (extent_mismatch) 2757 1.1 mrg { 2758 1.1 mrg caf_internal_error (nonallocextentmismatch, stat, 2759 1.1 mrg NULL, 0, delta, 2760 1.1 mrg GFC_DESCRIPTOR_EXTENT (src, 2761 1.1 mrg src_cur_dim)); 2762 1.1 mrg return; 2763 1.1 mrg } 2764 1.1 mrg } 2765 1.1 mrg ++src_cur_dim; 2766 1.1 mrg } 2767 1.1 mrg size *= (index_type)delta; 2768 1.1 mrg } 2769 1.1 mrg break; 2770 1.1 mrg default: 2771 1.1 mrg caf_internal_error (unknownreftype, stat, NULL, 0); 2772 1.1 mrg return; 2773 1.1 mrg } 2774 1.1 mrg src_size = riter->item_size; 2775 1.1 mrg riter = riter->next; 2776 1.1 mrg } 2777 1.1 mrg if (size == 0 || src_size == 0) 2778 1.1 mrg return; 2779 1.1 mrg /* Postcondition: 2780 1.1 mrg - size contains the number of elements to store in the destination array, 2781 1.1 mrg - src_size gives the size in bytes of each item in the destination array. 2782 1.1 mrg */ 2783 1.1 mrg 2784 1.1 mrg /* Reset the token. */ 2785 1.1 mrg single_token = TOKEN (token); 2786 1.1 mrg memptr = single_token->memptr; 2787 1.1 mrg dst = single_token->desc; 2788 1.1 mrg memset (dst_index, 0, sizeof (dst_index)); 2789 1.1 mrg i = 0; 2790 1.1 mrg send_by_ref (refs, &i, dst_index, single_token, dst, src, 2791 1.1 mrg memptr, GFC_DESCRIPTOR_DATA (src), dst_kind, src_kind, 0, 0, 2792 1.1 mrg 1, size, stat, dst_type); 2793 1.1 mrg assert (i == size); 2794 1.1 mrg } 2795 1.1 mrg 2796 1.1 mrg 2797 1.1 mrg void 2798 1.1 mrg _gfortran_caf_sendget_by_ref (caf_token_t dst_token, int dst_image_index, 2799 1.1 mrg caf_reference_t *dst_refs, caf_token_t src_token, 2800 1.1 mrg int src_image_index, 2801 1.1 mrg caf_reference_t *src_refs, int dst_kind, 2802 1.1 mrg int src_kind, bool may_require_tmp, int *dst_stat, 2803 1.1 mrg int *src_stat, int dst_type, int src_type) 2804 1.1 mrg { 2805 1.1 mrg GFC_FULL_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, void) temp; 2806 1.1 mrg GFC_DESCRIPTOR_DATA (&temp) = NULL; 2807 1.1 mrg GFC_DESCRIPTOR_RANK (&temp) = -1; 2808 1.1 mrg GFC_DESCRIPTOR_TYPE (&temp) = dst_type; 2809 1.1 mrg 2810 1.1 mrg _gfortran_caf_get_by_ref (src_token, src_image_index, 2811 1.1 mrg (gfc_descriptor_t *) &temp, src_refs, 2812 1.1 mrg dst_kind, src_kind, may_require_tmp, true, 2813 1.1 mrg src_stat, src_type); 2814 1.1 mrg 2815 1.1 mrg if (src_stat && *src_stat != 0) 2816 1.1 mrg return; 2817 1.1 mrg 2818 1.1 mrg _gfortran_caf_send_by_ref (dst_token, dst_image_index, 2819 1.1 mrg (gfc_descriptor_t *) &temp, dst_refs, 2820 1.1 mrg dst_kind, dst_kind, may_require_tmp, true, 2821 1.1 mrg dst_stat, dst_type); 2822 1.1 mrg if (GFC_DESCRIPTOR_DATA (&temp)) 2823 1.1 mrg free (GFC_DESCRIPTOR_DATA (&temp)); 2824 1.1 mrg } 2825 1.1 mrg 2826 1.1 mrg 2827 1.1 mrg void 2828 1.1 mrg _gfortran_caf_atomic_define (caf_token_t token, size_t offset, 2829 1.1 mrg int image_index __attribute__ ((unused)), 2830 1.1 mrg void *value, int *stat, 2831 1.1 mrg int type __attribute__ ((unused)), int kind) 2832 1.1 mrg { 2833 1.1 mrg assert(kind == 4); 2834 1.1 mrg 2835 1.1 mrg uint32_t *atom = (uint32_t *) ((char *) MEMTOK (token) + offset); 2836 1.1 mrg 2837 1.1 mrg __atomic_store (atom, (uint32_t *) value, __ATOMIC_RELAXED); 2838 1.1 mrg 2839 1.1 mrg if (stat) 2840 1.1 mrg *stat = 0; 2841 1.1 mrg } 2842 1.1 mrg 2843 1.1 mrg void 2844 1.1 mrg _gfortran_caf_atomic_ref (caf_token_t token, size_t offset, 2845 1.1 mrg int image_index __attribute__ ((unused)), 2846 1.1 mrg void *value, int *stat, 2847 1.1 mrg int type __attribute__ ((unused)), int kind) 2848 1.1 mrg { 2849 1.1 mrg assert(kind == 4); 2850 1.1 mrg 2851 1.1 mrg uint32_t *atom = (uint32_t *) ((char *) MEMTOK (token) + offset); 2852 1.1 mrg 2853 1.1 mrg __atomic_load (atom, (uint32_t *) value, __ATOMIC_RELAXED); 2854 1.1 mrg 2855 1.1 mrg if (stat) 2856 1.1 mrg *stat = 0; 2857 1.1 mrg } 2858 1.1 mrg 2859 1.1 mrg 2860 1.1 mrg void 2861 1.1 mrg _gfortran_caf_atomic_cas (caf_token_t token, size_t offset, 2862 1.1 mrg int image_index __attribute__ ((unused)), 2863 1.1 mrg void *old, void *compare, void *new_val, int *stat, 2864 1.1 mrg int type __attribute__ ((unused)), int kind) 2865 1.1 mrg { 2866 1.1 mrg assert(kind == 4); 2867 1.1 mrg 2868 1.1 mrg uint32_t *atom = (uint32_t *) ((char *) MEMTOK (token) + offset); 2869 1.1 mrg 2870 1.1 mrg *(uint32_t *) old = *(uint32_t *) compare; 2871 1.1 mrg (void) __atomic_compare_exchange_n (atom, (uint32_t *) old, 2872 1.1 mrg *(uint32_t *) new_val, false, 2873 1.1 mrg __ATOMIC_RELAXED, __ATOMIC_RELAXED); 2874 1.1 mrg if (stat) 2875 1.1 mrg *stat = 0; 2876 1.1 mrg } 2877 1.1 mrg 2878 1.1 mrg 2879 1.1 mrg void 2880 1.1 mrg _gfortran_caf_atomic_op (int op, caf_token_t token, size_t offset, 2881 1.1 mrg int image_index __attribute__ ((unused)), 2882 1.1 mrg void *value, void *old, int *stat, 2883 1.1 mrg int type __attribute__ ((unused)), int kind) 2884 1.1 mrg { 2885 1.1 mrg assert(kind == 4); 2886 1.1 mrg 2887 1.1 mrg uint32_t res; 2888 1.1 mrg uint32_t *atom = (uint32_t *) ((char *) MEMTOK (token) + offset); 2889 1.1 mrg 2890 1.1 mrg switch (op) 2891 1.1 mrg { 2892 1.1 mrg case GFC_CAF_ATOMIC_ADD: 2893 1.1 mrg res = __atomic_fetch_add (atom, *(uint32_t *) value, __ATOMIC_RELAXED); 2894 1.1 mrg break; 2895 1.1 mrg case GFC_CAF_ATOMIC_AND: 2896 1.1 mrg res = __atomic_fetch_and (atom, *(uint32_t *) value, __ATOMIC_RELAXED); 2897 1.1 mrg break; 2898 1.1 mrg case GFC_CAF_ATOMIC_OR: 2899 1.1 mrg res = __atomic_fetch_or (atom, *(uint32_t *) value, __ATOMIC_RELAXED); 2900 1.1 mrg break; 2901 1.1 mrg case GFC_CAF_ATOMIC_XOR: 2902 1.1 mrg res = __atomic_fetch_xor (atom, *(uint32_t *) value, __ATOMIC_RELAXED); 2903 1.1 mrg break; 2904 1.1 mrg default: 2905 1.1 mrg __builtin_unreachable(); 2906 1.1 mrg } 2907 1.1 mrg 2908 1.1 mrg if (old) 2909 1.1 mrg *(uint32_t *) old = res; 2910 1.1 mrg 2911 1.1 mrg if (stat) 2912 1.1 mrg *stat = 0; 2913 1.1 mrg } 2914 1.1 mrg 2915 1.1 mrg void 2916 1.1 mrg _gfortran_caf_event_post (caf_token_t token, size_t index, 2917 1.1 mrg int image_index __attribute__ ((unused)), 2918 1.1 mrg int *stat, char *errmsg __attribute__ ((unused)), 2919 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 2920 1.1 mrg { 2921 1.1 mrg uint32_t value = 1; 2922 1.1 mrg uint32_t *event = (uint32_t *) ((char *) MEMTOK (token) + index 2923 1.1 mrg * sizeof (uint32_t)); 2924 1.1 mrg __atomic_fetch_add (event, (uint32_t) value, __ATOMIC_RELAXED); 2925 1.1 mrg 2926 1.1 mrg if(stat) 2927 1.1 mrg *stat = 0; 2928 1.1 mrg } 2929 1.1 mrg 2930 1.1 mrg void 2931 1.1 mrg _gfortran_caf_event_wait (caf_token_t token, size_t index, 2932 1.1 mrg int until_count, int *stat, 2933 1.1 mrg char *errmsg __attribute__ ((unused)), 2934 1.1 mrg size_t errmsg_len __attribute__ ((unused))) 2935 1.1 mrg { 2936 1.1 mrg uint32_t *event = (uint32_t *) ((char *) MEMTOK (token) + index 2937 1.1 mrg * sizeof (uint32_t)); 2938 1.1 mrg uint32_t value = (uint32_t)-until_count; 2939 1.1 mrg __atomic_fetch_add (event, (uint32_t) value, __ATOMIC_RELAXED); 2940 1.1 mrg 2941 1.1 mrg if(stat) 2942 1.1 mrg *stat = 0; 2943 1.1 mrg } 2944 1.1 mrg 2945 1.1 mrg void 2946 1.1 mrg _gfortran_caf_event_query (caf_token_t token, size_t index, 2947 1.1 mrg int image_index __attribute__ ((unused)), 2948 1.1 mrg int *count, int *stat) 2949 1.1 mrg { 2950 1.1 mrg uint32_t *event = (uint32_t *) ((char *) MEMTOK (token) + index 2951 1.1 mrg * sizeof (uint32_t)); 2952 1.1 mrg __atomic_load (event, (uint32_t *) count, __ATOMIC_RELAXED); 2953 1.1 mrg 2954 1.1 mrg if(stat) 2955 1.1 mrg *stat = 0; 2956 1.1 mrg } 2957 1.1 mrg 2958 1.1 mrg void 2959 1.1 mrg _gfortran_caf_lock (caf_token_t token, size_t index, 2960 1.1 mrg int image_index __attribute__ ((unused)), 2961 1.1.1.3 mrg int *acquired_lock, int *stat, char *errmsg, 2962 1.1.1.3 mrg size_t errmsg_len) 2963 1.1 mrg { 2964 1.1 mrg const char *msg = "Already locked"; 2965 1.1 mrg bool *lock = &((bool *) MEMTOK (token))[index]; 2966 1.1 mrg 2967 1.1 mrg if (!*lock) 2968 1.1 mrg { 2969 1.1 mrg *lock = true; 2970 1.1.1.3 mrg if (acquired_lock) 2971 1.1.1.3 mrg *acquired_lock = (int) true; 2972 1.1 mrg if (stat) 2973 1.1 mrg *stat = 0; 2974 1.1 mrg return; 2975 1.1 mrg } 2976 1.1 mrg 2977 1.1.1.3 mrg if (acquired_lock) 2978 1.1 mrg { 2979 1.1.1.3 mrg *acquired_lock = (int) false; 2980 1.1 mrg if (stat) 2981 1.1 mrg *stat = 0; 2982 1.1 mrg return; 2983 1.1 mrg } 2984 1.1 mrg 2985 1.1 mrg 2986 1.1 mrg if (stat) 2987 1.1 mrg { 2988 1.1 mrg *stat = 1; 2989 1.1 mrg if (errmsg_len > 0) 2990 1.1 mrg { 2991 1.1 mrg size_t len = (sizeof (msg) > errmsg_len) ? errmsg_len 2992 1.1 mrg : sizeof (msg); 2993 1.1 mrg memcpy (errmsg, msg, len); 2994 1.1 mrg if (errmsg_len > len) 2995 1.1 mrg memset (&errmsg[len], ' ', errmsg_len-len); 2996 1.1 mrg } 2997 1.1 mrg return; 2998 1.1 mrg } 2999 1.1 mrg _gfortran_caf_error_stop_str (msg, strlen (msg), false); 3000 1.1 mrg } 3001 1.1 mrg 3002 1.1 mrg 3003 1.1 mrg void 3004 1.1 mrg _gfortran_caf_unlock (caf_token_t token, size_t index, 3005 1.1 mrg int image_index __attribute__ ((unused)), 3006 1.1 mrg int *stat, char *errmsg, size_t errmsg_len) 3007 1.1 mrg { 3008 1.1 mrg const char *msg = "Variable is not locked"; 3009 1.1 mrg bool *lock = &((bool *) MEMTOK (token))[index]; 3010 1.1 mrg 3011 1.1 mrg if (*lock) 3012 1.1 mrg { 3013 1.1 mrg *lock = false; 3014 1.1 mrg if (stat) 3015 1.1 mrg *stat = 0; 3016 1.1 mrg return; 3017 1.1 mrg } 3018 1.1 mrg 3019 1.1 mrg if (stat) 3020 1.1 mrg { 3021 1.1 mrg *stat = 1; 3022 1.1 mrg if (errmsg_len > 0) 3023 1.1 mrg { 3024 1.1 mrg size_t len = (sizeof (msg) > errmsg_len) ? errmsg_len 3025 1.1 mrg : sizeof (msg); 3026 1.1 mrg memcpy (errmsg, msg, len); 3027 1.1 mrg if (errmsg_len > len) 3028 1.1 mrg memset (&errmsg[len], ' ', errmsg_len-len); 3029 1.1 mrg } 3030 1.1 mrg return; 3031 1.1 mrg } 3032 1.1 mrg _gfortran_caf_error_stop_str (msg, strlen (msg), false); 3033 1.1 mrg } 3034 1.1 mrg 3035 1.1 mrg int 3036 1.1 mrg _gfortran_caf_is_present (caf_token_t token, 3037 1.1 mrg int image_index __attribute__ ((unused)), 3038 1.1 mrg caf_reference_t *refs) 3039 1.1 mrg { 3040 1.1 mrg const char arraddressingnotallowed[] = "libcaf_single::caf_is_present(): " 3041 1.1 mrg "only scalar indexes allowed.\n"; 3042 1.1 mrg const char unknownreftype[] = "libcaf_single::caf_get_by_ref(): " 3043 1.1 mrg "unknown reference type.\n"; 3044 1.1 mrg const char unknownarrreftype[] = "libcaf_single::caf_get_by_ref(): " 3045 1.1 mrg "unknown array reference type.\n"; 3046 1.1 mrg size_t i; 3047 1.1 mrg caf_single_token_t single_token = TOKEN (token); 3048 1.1 mrg void *memptr = single_token->memptr; 3049 1.1 mrg gfc_descriptor_t *src = single_token->desc; 3050 1.1 mrg caf_reference_t *riter = refs; 3051 1.1 mrg 3052 1.1 mrg while (riter) 3053 1.1 mrg { 3054 1.1 mrg switch (riter->type) 3055 1.1 mrg { 3056 1.1 mrg case CAF_REF_COMPONENT: 3057 1.1 mrg if (riter->u.c.caf_token_offset) 3058 1.1 mrg { 3059 1.1 mrg single_token = *(caf_single_token_t*) 3060 1.1 mrg (memptr + riter->u.c.caf_token_offset); 3061 1.1 mrg memptr = single_token->memptr; 3062 1.1 mrg src = single_token->desc; 3063 1.1 mrg } 3064 1.1 mrg else 3065 1.1 mrg { 3066 1.1 mrg memptr += riter->u.c.offset; 3067 1.1 mrg src = (gfc_descriptor_t *)memptr; 3068 1.1 mrg } 3069 1.1 mrg break; 3070 1.1 mrg case CAF_REF_ARRAY: 3071 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 3072 1.1 mrg { 3073 1.1 mrg switch (riter->u.a.mode[i]) 3074 1.1 mrg { 3075 1.1 mrg case CAF_ARR_REF_SINGLE: 3076 1.1 mrg memptr += (riter->u.a.dim[i].s.start 3077 1.1 mrg - GFC_DIMENSION_LBOUND (src->dim[i])) 3078 1.1 mrg * GFC_DIMENSION_STRIDE (src->dim[i]) 3079 1.1 mrg * riter->item_size; 3080 1.1 mrg break; 3081 1.1 mrg case CAF_ARR_REF_FULL: 3082 1.1 mrg /* A full array ref is allowed on the last reference only. */ 3083 1.1 mrg if (riter->next == NULL) 3084 1.1 mrg break; 3085 1.1 mrg /* else fall through reporting an error. */ 3086 1.1 mrg /* FALLTHROUGH */ 3087 1.1 mrg case CAF_ARR_REF_VECTOR: 3088 1.1 mrg case CAF_ARR_REF_RANGE: 3089 1.1 mrg case CAF_ARR_REF_OPEN_END: 3090 1.1 mrg case CAF_ARR_REF_OPEN_START: 3091 1.1 mrg caf_internal_error (arraddressingnotallowed, 0, NULL, 0); 3092 1.1 mrg return 0; 3093 1.1 mrg default: 3094 1.1 mrg caf_internal_error (unknownarrreftype, 0, NULL, 0); 3095 1.1 mrg return 0; 3096 1.1 mrg } 3097 1.1 mrg } 3098 1.1 mrg break; 3099 1.1 mrg case CAF_REF_STATIC_ARRAY: 3100 1.1 mrg for (i = 0; riter->u.a.mode[i] != CAF_ARR_REF_NONE; ++i) 3101 1.1 mrg { 3102 1.1 mrg switch (riter->u.a.mode[i]) 3103 1.1 mrg { 3104 1.1 mrg case CAF_ARR_REF_SINGLE: 3105 1.1 mrg memptr += riter->u.a.dim[i].s.start 3106 1.1 mrg * riter->u.a.dim[i].s.stride 3107 1.1 mrg * riter->item_size; 3108 1.1 mrg break; 3109 1.1 mrg case CAF_ARR_REF_FULL: 3110 1.1 mrg /* A full array ref is allowed on the last reference only. */ 3111 1.1 mrg if (riter->next == NULL) 3112 1.1 mrg break; 3113 1.1 mrg /* else fall through reporting an error. */ 3114 1.1 mrg /* FALLTHROUGH */ 3115 1.1 mrg case CAF_ARR_REF_VECTOR: 3116 1.1 mrg case CAF_ARR_REF_RANGE: 3117 1.1 mrg case CAF_ARR_REF_OPEN_END: 3118 1.1 mrg case CAF_ARR_REF_OPEN_START: 3119 1.1 mrg caf_internal_error (arraddressingnotallowed, 0, NULL, 0); 3120 1.1 mrg return 0; 3121 1.1 mrg default: 3122 1.1 mrg caf_internal_error (unknownarrreftype, 0, NULL, 0); 3123 1.1 mrg return 0; 3124 1.1 mrg } 3125 1.1 mrg } 3126 1.1 mrg break; 3127 1.1 mrg default: 3128 1.1 mrg caf_internal_error (unknownreftype, 0, NULL, 0); 3129 1.1 mrg return 0; 3130 1.1 mrg } 3131 1.1 mrg riter = riter->next; 3132 1.1 mrg } 3133 1.1 mrg return memptr != NULL; 3134 1.1 mrg } 3135 1.1.1.3 mrg 3136 1.1.1.3 mrg /* Reference the libraries implementation. */ 3137 1.1.1.3 mrg extern void _gfortran_random_init (int32_t, int32_t, int32_t); 3138 1.1.1.3 mrg 3139 1.1.1.3 mrg void _gfortran_caf_random_init (bool repeatable, bool image_distinct) 3140 1.1.1.3 mrg { 3141 1.1.1.3 mrg /* In a single image implementation always forward to the gfortran 3142 1.1.1.3 mrg routine. */ 3143 1.1.1.3 mrg _gfortran_random_init (repeatable, image_distinct, 1); 3144 1.1.1.3 mrg } 3145