@@ -76,6 +76,11 @@ typedef struct mpi_caf_token_t
7676 window gives access to the descriptor on remote images. When the object is
7777 scalar, then this is NULL. */
7878 MPI_Win * desc ;
79+ /** This window allows access the local_memptr member of the associated token.
80+ With async allocation the token may be registered, but the memory not yet. To
81+ be able to check (using is_present()), that the memory on a remote image is
82+ present, this win can be used. */
83+ MPI_Win local_memptr_win ;
7984} mpi_caf_token_t ;
8085#define TOKEN (X ) &(((mpi_caf_token_t *) (X))->memptr)
8186#else
@@ -486,13 +491,15 @@ PREFIX (finalize) (void)
486491 CAF_Win_unlock_all (* p );
487492#ifdef GCC_GE_7
488493 /* Unregister the window to the descriptors when freeing the token. */
494+ mpi_caf_token_t * mpi_token = (mpi_caf_token_t * )tmp_tot -> token ;
489495 if (((mpi_caf_token_t * )tmp_tot -> token )-> desc )
490- {
491- mpi_caf_token_t * mpi_token = (mpi_caf_token_t * )tmp_tot -> token ;
492- CAF_Win_unlock_all (* (mpi_token -> desc ));
493- MPI_Win_free (mpi_token -> desc );
494- free (mpi_token -> desc );
495- }
496+ {
497+ CAF_Win_unlock_all (* (mpi_token -> desc ));
498+ MPI_Win_free (mpi_token -> desc );
499+ free (mpi_token -> desc );
500+ }
501+ CAF_Win_unlock_all (mpi_token -> local_memptr_win );
502+ MPI_Win_free (& mpi_token -> local_memptr_win );
496503#endif // GCC_GE_7
497504 MPI_Win_free (p );
498505 free (tmp_tot );
@@ -550,7 +557,7 @@ PREFIX (register) (size_t size, caf_register_t type, caf_token_t *token,
550557 int errmsg_len )
551558{
552559 /* int ierr; */
553- void * mem ;
560+ void * mem = NULL ;
554561 size_t actual_size ;
555562 int l_var = 0 , * init_array = NULL ;
556563
@@ -601,24 +608,38 @@ PREFIX (register) (size_t size, caf_register_t type, caf_token_t *token,
601608#if MPI_VERSION >= 3
602609 if (type == CAF_REGTYPE_COARRAY_ALLOC_REGISTER_ONLY )
603610 {
604- MPI_Win_create_dynamic (MPI_INFO_NULL , CAF_COMM_WORLD , p );
605- fprintf (stderr , "%d/%d: Register win = %p\n" , caf_this_image , caf_num_images ,
606- * p );
607- // CAF_Win_lock_all (*p);
611+ int ierr = MPI_Win_create_dynamic (MPI_INFO_NULL , CAF_COMM_WORLD , p );
612+ fprintf (stderr , "%d/%d: Register win = %p, ierr= %d \n" , caf_this_image , caf_num_images ,
613+ * p , ierr );
614+ CAF_Win_lock_all (* p );
608615 }
609616 else if (type == CAF_REGTYPE_COARRAY_ALLOC_ALLOCATE_ONLY )
610617 {
618+ int ierr ;
611619 mem = malloc (actual_size );
612- MPI_Win_attach (* p , mem , actual_size );
613- fprintf (stderr , "%d/%d: Attach mem to win = %p\n" , caf_this_image , caf_num_images ,
614- * p );
615- CAF_Win_lock_all (* p );
620+ ierr = MPI_Win_attach (* p , mem , actual_size );
621+ fprintf (stderr , "%d/%d: Attach mem %p to win = %p, ierr: %d\n" , caf_this_image , caf_num_images ,
622+ mem , * p , ierr );
616623 }
617624 else
618625 {
619626 MPI_Win_allocate (actual_size , 1 , MPI_INFO_NULL , CAF_COMM_WORLD , & mem , p );
620627 CAF_Win_lock_all (* p );
621628 }
629+
630+ /* When doing a allocate only, the token is initialized already, and the
631+ * window for the local_memptr exists already. Any time else create a window
632+ * to monitor whether the data-pointer of this token is associated or not. */
633+ if (type != CAF_REGTYPE_COARRAY_ALLOC_ALLOCATE_ONLY )
634+ {
635+ int ierr ;
636+ ierr = MPI_Win_create (& mpi_token -> local_memptr , sizeof (void * ), 1 ,
637+ mpi_info_same_size , CAF_COMM_WORLD ,
638+ & mpi_token -> local_memptr_win );
639+ fprintf (stderr , "%d/%d: Creating win return error code: %d\n" , caf_this_image ,
640+ caf_num_images , ierr );
641+ CAF_Win_lock_all (mpi_token -> local_memptr_win );
642+ }
622643#else // MPI_VERSION
623644 MPI_Alloc_mem (actual_size , MPI_INFO_NULL , & mem );
624645 MPI_Win_create (mem , actual_size , 1 , MPI_INFO_NULL , CAF_COMM_WORLD , p );
@@ -823,7 +844,14 @@ PREFIX (deregister) (caf_token_t *token, int *stat, char *errmsg, int errmsg_len
823844 caf_runtime_error (msg );
824845 }
825846
847+ #ifdef GCC_GE_7
848+ if (type != CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY )
849+ /* Sync all images only, when deregistering the token. Just freeing the
850+ * memory needs no sync. */
851+ PREFIX (sync_all ) (NULL , NULL , 0 );
852+ #else
826853 PREFIX (sync_all ) (NULL , NULL , 0 );
854+ #endif
827855
828856 caf_static_t * tmp = caf_tot , * prev = caf_tot , * next = caf_tot ;
829857 MPI_Win * p ;
@@ -835,13 +863,16 @@ PREFIX (deregister) (caf_token_t *token, int *stat, char *errmsg, int errmsg_len
835863 if (tmp -> token == * token )
836864 {
837865 p = TOKEN (* token );
838- CAF_Win_unlock_all (* p );
839866#ifdef GCC_GE_7
840867 mpi_caf_token_t * mpi_token = * (mpi_caf_token_t * * )token ;
841868 if (mpi_token -> local_memptr )
842869 {
843870 if (type != CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY )
844- MPI_Win_free (p );
871+ {
872+ /* Unlock only, when removing the window. */
873+ CAF_Win_unlock_all (* p );
874+ MPI_Win_free (p );
875+ }
845876 else
846877 MPI_Win_detach (* p , mpi_token -> local_memptr );
847878 mpi_token -> local_memptr = NULL ;
@@ -853,7 +884,13 @@ PREFIX (deregister) (caf_token_t *token, int *stat, char *errmsg, int errmsg_len
853884 MPI_Win_free (mpi_token -> desc );
854885 free (mpi_token -> desc );
855886 }
887+ if (type != CAF_DEREGTYPE_COARRAY_DEALLOCATE_ONLY )
888+ {
889+ CAF_Win_unlock_all (mpi_token -> local_memptr_win );
890+ MPI_Win_free (& mpi_token -> local_memptr_win );
891+ }
856892#else
893+ CAF_Win_unlock_all (* p );
857894 MPI_Win_free (p );
858895#endif
859896
@@ -2987,121 +3024,98 @@ int
29873024PREFIX (is_present ) (caf_token_t token , int image_index , caf_reference_t * refs )
29883025{
29893026 const char unsupportedRefType [] = "Unsupported ref-type in caf_is_present()." ;
2990- MPI_Errhandler oldErr ;
29913027 mpi_caf_token_t * mpi_token = (mpi_caf_token_t * )token ;
29923028 size_t i ;
2993- ptrdiff_t offset = 0 ;
29943029 void * local_memptr = mpi_token -> local_memptr ;
29953030 gfc_descriptor_t * src ;
29963031 gfc_max_dim_descriptor_t src_desc_data , primary_src_desc_data ;
29973032 caf_reference_t * riter = refs ;
2998- enum { COMP_REF , ARR_REF } last_ref ;
29993033
30003034 GET_REMOTE_DESC (mpi_token , src , primary_src_desc_data , image_index - 1 );
30013035 while (riter )
30023036 {
30033037 switch (riter -> type )
3004- {
3005- case CAF_REF_COMPONENT :
3006- if (riter -> u .c .caf_token_offset )
3007- {
3008- mpi_token = * (mpi_caf_token_t * * )
3009- (local_memptr + riter -> u .c .caf_token_offset );
3010- local_memptr = mpi_token -> local_memptr ;
3011- GET_REMOTE_DESC (mpi_token , src , src_desc_data , image_index - 1 );
3012- offset = 0 ;
3013- }
3014- else
3015- {
3016- local_memptr += riter -> u .c .offset ;
3017- src = (gfc_descriptor_t * )local_memptr ;
3018- offset += riter -> u .c .offset ;
3019- }
3020- last_ref = COMP_REF ;
3021- break ;
3022- case CAF_REF_ARRAY :
3023- for (i = 0 ; riter -> u .a .mode [i ] != CAF_ARR_REF_NONE ; ++ i )
3024- {
3025- switch (riter -> u .a .mode [i ])
3026- {
3027- case CAF_ARR_REF_FULL :
3028- /* The memptr stays unchanged when ref'ing the first element
3029- in a dimension. */
3030- break ;
3031- case CAF_ARR_REF_SINGLE :
3038+ {
3039+ case CAF_REF_COMPONENT :
3040+ if (riter -> u .c .caf_token_offset )
3041+ {
3042+ mpi_token = * (mpi_caf_token_t * * )
3043+ (local_memptr + riter -> u .c .caf_token_offset );
3044+ local_memptr = mpi_token -> local_memptr ;
3045+ GET_REMOTE_DESC (mpi_token , src , src_desc_data , image_index - 1 );
3046+ }
3047+ else
3048+ {
3049+ local_memptr += riter -> u .c .offset ;
3050+ src = (gfc_descriptor_t * )local_memptr ;
3051+ }
3052+ break ;
3053+ case CAF_REF_ARRAY :
3054+ for (i = 0 ; riter -> u .a .mode [i ] != CAF_ARR_REF_NONE ; ++ i )
3055+ {
3056+ switch (riter -> u .a .mode [i ])
3057+ {
3058+ case CAF_ARR_REF_FULL :
3059+ /* The memptr stays unchanged when ref'ing the first element
3060+ in a dimension. */
3061+ break ;
3062+ case CAF_ARR_REF_SINGLE :
30323063 local_memptr += (riter -> u .a .dim [i ].s .start
30333064 - src -> dim [i ].lower_bound )
30343065 * src -> dim [i ]._stride
30353066 * riter -> item_size ;
3036- break ;
3067+ break ;
30373068 case CAF_ARR_REF_VECTOR :
30383069 case CAF_ARR_REF_RANGE :
3039- case CAF_ARR_REF_OPEN_END :
3040- case CAF_ARR_REF_OPEN_START :
3070+ case CAF_ARR_REF_OPEN_END :
3071+ case CAF_ARR_REF_OPEN_START :
30413072 /* Intentionally fall through, because these are not suported
30423073 * here. */
3043- default :
3044- caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3045- return false;
3046- }
3047- }
3048- last_ref = ARR_REF ;
3049- break ;
3050- case CAF_REF_STATIC_ARRAY :
3051- for (i = 0 ; riter -> u .a .mode [i ] != CAF_ARR_REF_NONE ; ++ i )
3052- {
3053- switch (riter -> u .a .mode [i ])
3054- {
3055- case CAF_ARR_REF_FULL :
3056- /* The memptr stays unchanged when ref'ing the first element
3057- in a dimension. */
3058- break ;
3059- case CAF_ARR_REF_SINGLE :
3060- local_memptr += riter -> u .a .dim [i ].s .start
3061- * riter -> u .a .dim [i ].s .stride
3062- * riter -> item_size ;
3063- break ;
3074+ default :
3075+ caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3076+ return false;
3077+ }
3078+ }
3079+ break ;
3080+ case CAF_REF_STATIC_ARRAY :
3081+ for (i = 0 ; riter -> u .a .mode [i ] != CAF_ARR_REF_NONE ; ++ i )
3082+ {
3083+ switch (riter -> u .a .mode [i ])
3084+ {
3085+ case CAF_ARR_REF_FULL :
3086+ /* The memptr stays unchanged when ref'ing the first element
3087+ in a dimension. */
3088+ break ;
3089+ case CAF_ARR_REF_SINGLE :
3090+ local_memptr += riter -> u .a .dim [i ].s .start
3091+ * riter -> u .a .dim [i ].s .stride
3092+ * riter -> item_size ;
3093+ break ;
30643094 case CAF_ARR_REF_VECTOR :
30653095 case CAF_ARR_REF_RANGE :
3066- case CAF_ARR_REF_OPEN_END :
3067- case CAF_ARR_REF_OPEN_START :
3068- default :
3069- caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3070- return false;
3071- }
3096+ case CAF_ARR_REF_OPEN_END :
3097+ case CAF_ARR_REF_OPEN_START :
3098+ default :
3099+ caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3100+ return false;
3101+ }
30723102 }
3073- last_ref = COMP_REF ;
3074- break ;
3075- default :
3076- caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3077- return false;
3078- }
3103+ break ;
3104+ default :
3105+ caf_runtime_error (unsupportedRefType , NULL , NULL , 0 );
3106+ return false;
3107+ }
30793108 riter = riter -> next ;
30803109 }
30813110
3082- if (last_ref == COMP_REF )
3083- {
3084- MPI_Win win = * TOKEN (mpi_token );
3085- char dummy ;
3086- char errmsg [200 ];
3087- int ierr , len ;
3088- len = 200 ;
3089-
3090- MPI_Win_get_errhandler (win , & oldErr );
3091- MPI_Win_set_errhandler (win , MPI_ERRORS_RETURN );
3092-
3093- ierr = MPI_Get (& dummy , 1 , MPI_BYTE , image_index - 1 , offset , 1 , MPI_BYTE ,
3094- win );
3095- MPI_Error_string (ierr , errmsg , & len );
3096- fprintf (stderr , "%d/%d: caf_is_present(): offset = %d, ierr =%d, %s\n" , caf_this_image ,
3097- caf_num_images , offset , ierr , errmsg );
3098- MPI_Win_set_errhandler (win , oldErr );
3099- return ierr == MPI_SUCCESS ;
3100- }
3101- else
3102- {
3103- return src -> base_addr != NULL ;
3104- }
3111+ void * remote_local_memory = NULL ;
3112+ MPI_Datatype dtype = sizeof (void * ) == 8 ? MPI_INTEGER8 : MPI_INTEGER4 ;
3113+ int ierr = MPI_Get (& remote_local_memory , 1 , dtype , image_index - 1 , 0 , 1 , dtype ,
3114+ mpi_token -> local_memptr_win );
3115+ fprintf (stderr , "%d/%d: Got remote_local_memory[%d] for win %p to be: %p, ierr = %d\n" ,
3116+ caf_this_image , caf_num_images , image_index , mpi_token -> memptr ,
3117+ remote_local_memory , ierr );
3118+ return remote_local_memory != NULL ;
31053119}
31063120#endif
31073121
0 commit comments