@@ -5333,20 +5333,20 @@ PREFIX (send_by_ref) (caf_token_t token, int image_index,
5333
5333
"rank out of range.\n" ;
5334
5334
const char extentoutofrange [] = "libcaf_mpi::caf_send_by_ref(): "
5335
5335
"extent out of range.\n" ;
5336
+ const char cannotallocdst [] = "libcaf_mpi::caf_get_by_ref(): "
5337
+ "can not allocate %d bytes of memory.\n" ;
5336
5338
const char unabletoallocdst [] = "libcaf_mpi::caf_send_by_ref(): "
5337
5339
"unable to allocate memory on remote image.\n" ;
5338
5340
const char nonallocextentmismatch [] = "libcaf_mpi::caf_send_by_ref(): "
5339
5341
"extent of non-allocatable arrays mismatch (%lu != %lu).\n" ;
5340
- const char doublearrayref [] = "libcaf_mpi::caf_get_by_ref(): "
5341
- "two or more array part references are not supported.\n" ;
5342
5342
size_t size , i , ref_rank ;
5343
5343
size_t src_index ;
5344
5344
int dst_rank = -1 ;
5345
5345
int src_cur_dim = 0 ;
5346
5346
size_t dst_size ;
5347
5347
mpi_caf_token_t * mpi_token = (mpi_caf_token_t * ) token ;
5348
5348
void * remote_memptr = mpi_token -> memptr , * remote_base_memptr = NULL ;
5349
- gfc_max_dim_descriptor_t dst_desc ;
5349
+ gfc_max_dim_descriptor_t dst_desc , temp_src ;
5350
5350
gfc_descriptor_t * dst = (gfc_descriptor_t * )& dst_desc ;
5351
5351
caf_reference_t * riter = refs ;
5352
5352
long delta ;
@@ -5364,6 +5364,7 @@ PREFIX (send_by_ref) (caf_token_t token, int image_index,
5364
5364
bool access_data_through_global_win = false;
5365
5365
/* Set when the remote descriptor is to accessed through the global window. */
5366
5366
bool access_desc_through_global_win = false;
5367
+ bool free_temp_src = false;
5367
5368
5368
5369
if (stat )
5369
5370
* stat = 0 ;
@@ -5556,41 +5557,41 @@ PREFIX (send_by_ref) (caf_token_t token, int image_index,
5556
5557
return ;
5557
5558
}
5558
5559
/* Do further checks, when the source is not scalar. */
5559
- // else if (delta != 1)
5560
- // {
5561
- // /* When the realloc is required, then no extent may have
5562
- // been set. */
5563
- // extent_mismatch = GFC_DESCRIPTOR_EXTENT (dst,
5564
- // src_cur_dim)
5565
- // != delta;
5566
- // /* When it already known, that a realloc is needed or
5567
- // the extent does not match the needed one. */
5568
- // if (realloc_dst || extent_mismatch)
5569
- // {
5570
- // /* Check whether dst is reallocatable. */
5571
- // if (unlikely (!dst_reallocatable))
5572
- // {
5573
- // caf_runtime_error (nonallocextentmismatch, stat,
5574
- // NULL, 0, delta,
5575
- // GFC_DESCRIPTOR_EXTENT (dst,
5576
- // src_cur_dim));
5577
- // return;
5578
- // }
5579
- // /* Only report an error, when the extent needs to be
5580
- // modified, which is not allowed. */
5581
- // else if (!dst_reallocatable && extent_mismatch)
5582
- // {
5583
- // caf_runtime_error (extentoutofrange, stat, NULL,
5584
- // 0);
5585
- // return;
5586
- // }
5587
- // dprint ("%d/%d: %s() extent(dst): %d != delta: %d.\n",
5588
- // caf_this_image, caf_num_images, __FUNCTION__,
5589
- // GFC_DESCRIPTOR_EXTENT (dst, src_cur_dim),
5590
- // delta);
5591
- // realloc_dst = true;
5592
- // }
5593
- // }
5560
+ else if (delta != 1 )
5561
+ {
5562
+ /* When the realloc is required, then no extent may have
5563
+ been set. */
5564
+ extent_mismatch = GFC_DESCRIPTOR_EXTENT (dst ,
5565
+ src_cur_dim )
5566
+ < delta ;
5567
+ /* When it already known, that a realloc is needed or
5568
+ the extent does not match the needed one. */
5569
+ if (realloc_dst || extent_mismatch )
5570
+ {
5571
+ /* Check whether dst is reallocatable. */
5572
+ if (unlikely (!dst_reallocatable ))
5573
+ {
5574
+ caf_runtime_error (nonallocextentmismatch , stat ,
5575
+ NULL , 0 , delta ,
5576
+ GFC_DESCRIPTOR_EXTENT (dst ,
5577
+ src_cur_dim ));
5578
+ return ;
5579
+ }
5580
+ /* Only report an error, when the extent needs to be
5581
+ modified, which is not allowed. */
5582
+ else if (!dst_reallocatable && extent_mismatch )
5583
+ {
5584
+ caf_runtime_error (extentoutofrange , stat , NULL ,
5585
+ 0 );
5586
+ return ;
5587
+ }
5588
+ dprint ("%d/%d: %s() extent(dst): %d != delta: %d.\n" ,
5589
+ caf_this_image , caf_num_images , __FUNCTION__ ,
5590
+ GFC_DESCRIPTOR_EXTENT (dst , src_cur_dim ),
5591
+ delta );
5592
+ realloc_dst = true;
5593
+ }
5594
+ }
5594
5595
5595
5596
/* Only increase the dim counter, when in an array ref. */
5596
5597
if (in_array_ref && src_cur_dim < GFC_DESCRIPTOR_RANK (src ))
@@ -5683,41 +5684,21 @@ PREFIX (send_by_ref) (caf_token_t token, int image_index,
5683
5684
return ;
5684
5685
}
5685
5686
/* Do further checks, when the source is not scalar. */
5686
- // else if (delta != 1)
5687
- // {
5688
- // /* Check that the extent is not scalar and we are not in
5689
- // an array ref for the dst side. */
5690
- // if (!in_array_ref)
5691
- // {
5692
- // /* Check that this is the non-scalar extent. */
5693
- // if (!array_extent_fixed)
5694
- // {
5695
- // /* In an array extent now. */
5696
- // in_array_ref = true;
5697
- // /* The dst is not reallocatable, so nothing more
5698
- // to do, then correct the dim counter. */
5699
- // src_cur_dim = i;
5700
- // }
5701
- // else
5702
- // {
5703
- // caf_runtime_error (doublearrayref, stat, NULL,
5704
- // 0);
5705
- // return;
5706
- // }
5707
- // }
5708
- // /* When the realloc is required, then no extent may have
5709
- // been set. */
5710
- // extent_mismatch = GFC_DESCRIPTOR_EXTENT (dst,
5711
- // src_cur_dim)
5712
- // != delta;
5713
- // /* When it is already known, that a realloc is needed or
5714
- // the extent does not match the needed one. */
5715
- // if (realloc_dst || extent_mismatch)
5716
- // {
5717
- // caf_runtime_error(unabletoallocdst, stat);
5718
- // return;
5719
- // }
5720
- // }
5687
+ else if (delta != 1 )
5688
+ {
5689
+ /* When the realloc is required, then no extent may have
5690
+ been set. */
5691
+ extent_mismatch = GFC_DESCRIPTOR_EXTENT (dst ,
5692
+ src_cur_dim )
5693
+ < delta ;
5694
+ /* When it is already known, that a realloc is needed or
5695
+ the extent does not match the needed one. */
5696
+ if (realloc_dst || extent_mismatch )
5697
+ {
5698
+ caf_runtime_error (unabletoallocdst , stat );
5699
+ return ;
5700
+ }
5701
+ }
5721
5702
/* Only increase the dim counter, when in an array ref. */
5722
5703
if (in_array_ref && src_cur_dim < GFC_DESCRIPTOR_RANK (src ))
5723
5704
++ src_cur_dim ;
@@ -5761,12 +5742,42 @@ PREFIX (send_by_ref) (caf_token_t token, int image_index,
5761
5742
fprintf (stderr , "%d/%d: %s() dst_dim[%d] = (%d, %d)\n" , caf_this_image , caf_num_images ,
5762
5743
__FUNCTION__ , i , src -> dim [i ].lower_bound , src -> dim [i ]._ubound );
5763
5744
#endif
5745
+ /* When accessing myself and may_require_tmp is set, then copy the source
5746
+ * array. */
5747
+ if (caf_this_image == image_index && may_require_tmp )
5748
+ {
5749
+ dprint ("%d/%d: %s() preparing temporary source.\n" , caf_this_image ,
5750
+ caf_num_images , __FUNCTION__ );
5751
+ memcpy (& temp_src , src , sizeof_desc_for_rank (GFC_DESCRIPTOR_RANK (src )));
5752
+ size_t cap = 0 ;
5753
+ for (int r = 0 ; r < GFC_DESCRIPTOR_RANK (src ); ++ r )
5754
+ cap += GFC_DESCRIPTOR_EXTENT (src , r );
5755
+
5756
+ cap *= GFC_DESCRIPTOR_SIZE (src );
5757
+ temp_src .base .base_addr = alloca (cap );
5758
+ if ((free_temp_src = (temp_src .base .base_addr == NULL )))
5759
+ {
5760
+ temp_src .base .base_addr = malloc (cap );
5761
+ if (temp_src .base .base_addr == NULL )
5762
+ {
5763
+ caf_runtime_error (cannotallocdst , stat , NULL , cap );
5764
+ return ;
5765
+ }
5766
+ }
5767
+ memcpy (temp_src .base .base_addr , src -> base_addr , cap );
5768
+ src = (gfc_descriptor_t * )& temp_src ;
5769
+ }
5770
+
5764
5771
i = 0 ;
5765
5772
dprint ("%d/%d: %s() calling send_for_ref.\n" , caf_this_image ,
5766
5773
caf_num_images , __FUNCTION__ );
5767
5774
send_by_ref (refs , & i , src_index , mpi_token , mpi_token -> desc , src ,
5768
5775
remote_memptr , src -> base_addr , 0 , 0 , dst_kind , src_kind , 0 , 0 ,
5769
5776
1 , stat , remote_image , false, false);
5777
+ if (free_temp_src )
5778
+ {
5779
+ free (temp_src .base .base_addr );
5780
+ }
5770
5781
CAF_Win_unlock (remote_image , global_dynamic_win );
5771
5782
CAF_Win_unlock (remote_image , mpi_token -> memptr_win );
5772
5783
}
0 commit comments