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