libxmp/libxmpf in Omni Compiler  1.3.4
xmp_async.c File Reference
#include "xmp_internal.h"
#include <string.h>
Include dependency graph for xmp_async.c:

Functions

_Bool xmp_is_async ()
 
_XMP_async_comm_t_XMP_get_async (int async_id)
 
void _XMP_initialize_async_comm_tab ()
 
void _XMP_wait_async__ (int async_id)
 
int xmp_test_async_ (int *async_id)
 
_XMP_async_comm_t_XMP_get_current_async ()
 
void xmpc_init_async (int async_id)
 
void _XMP_nodes_dealloc_after_wait_async (_XMP_nodes_t *n)
 
void xmpc_start_async ()
 
void xmpc_end_async (int async_id)
 

Variables

void(* _XMP_unpack_comm_set )(void *recvbuf, int recvbuf_size, _XMP_array_t *a, _XMP_comm_set_t *comm_set[][_XMP_N_MAX_DIM])
 

Function Documentation

◆ _XMP_get_async()

_XMP_async_comm_t* _XMP_get_async ( int  async_id)
31 {
32  int hash_id = async_id % _XMP_ASYNC_COMM_SIZE;
33  _XMP_async_comm_t *async = &_XMP_async_comm_tab[hash_id];
34 
35  if(async->async_id == async_id) return async;
36 
37  while(async->next){
38  async = async->next;
39  if(async->async_id == async_id)
40  return async;
41  }
42 
43  return NULL;
44 }
Here is the caller graph for this function:

◆ _XMP_get_current_async()

_XMP_async_comm_t* _XMP_get_current_async ( )
206 {
207  return _tmp_async;
208 }
Here is the caller graph for this function:

◆ _XMP_initialize_async_comm_tab()

void _XMP_initialize_async_comm_tab ( )
51 {
52  for(int i=0;i<_XMP_ASYNC_COMM_SIZE;i++){
53  _XMP_async_comm_tab[i].nreqs = 0;
54  _XMP_async_comm_tab[i].nnodes = 0;
55  _XMP_async_comm_tab[i].is_used = false;
56  _XMP_async_comm_tab[i].type = _XMP_COMM_NONE;
57  _XMP_async_comm_tab[i].node = NULL;
58  _XMP_async_comm_tab[i].reqs = NULL;
59  _XMP_async_comm_tab[i].gmove = NULL;
60  _XMP_async_comm_tab[i].a = NULL;
61  _XMP_async_comm_tab[i].next = NULL;
62  }
63 }

◆ _XMP_nodes_dealloc_after_wait_async()

void _XMP_nodes_dealloc_after_wait_async ( _XMP_nodes_t n)
273 {
274  if(_tmp_async->nnodes >= _XMP_MAX_ASYNC_NODES) // Fix me
275  _XMP_fatal("Too many nodes");
276 
277  if(_tmp_async->nnodes == 0)
278  _tmp_async->node = _XMP_alloc(sizeof(_XMP_nodes_t*) * _XMP_MAX_ASYNC_NODES);
279 
280  _tmp_async->node[_tmp_async->nnodes] = n;
281  _tmp_async->nnodes++;
282 }
Here is the caller graph for this function:

◆ _XMP_wait_async__()

void _XMP_wait_async__ ( int  async_id)
88 {
89  _XMP_async_comm_t *async;
90 
91  if(!(async = _XMP_get_async(async_id))) return;
92 
93  int nreqs = async->nreqs;
94  MPI_Request *reqs = async->reqs;
95 
96 #if defined(_KCOMPUTER) && defined(K_RDMA_REFLECT)
97  // For RDMA reflects, async->nreqs > 0 and async->reqs == NULL.
98  if(nreqs && !reqs){
99  _XMP_wait_async_rdma(async);
100  return;
101  }
102 #endif
103 
104  _XMP_async_gmove_t *gmove = async->gmove;
105 
106  if (async->type == _XMP_COMM_REDUCE_SHADOW){
107  MPI_Waitall(nreqs, reqs, MPI_STATUSES_IGNORE);
108  _XMP_reduce_shadow_sum(async->a);
109  }
110  else if (!gmove || gmove->mode == _XMP_N_GMOVE_NORMAL){
111  _XMP_TSTART(t0);
112  MPI_Waitall(nreqs, reqs, MPI_STATUSES_IGNORE);
113  _XMP_TEND(xmptiming_.t_wait, t0);
114  }
115 
116  //
117  // for asynchronous gmove
118  //
119 
120  if (gmove){
121  if (gmove->mode == _XMP_N_GMOVE_NORMAL) _XMP_finalize_async_gmove(gmove);
122 #ifdef _XMP_MPI3_ONESIDED
123  else {
124  int status;
125  // NOTE: the send_buf field is used for an improper purpose.
126  _XMP_sync_images_COMM((MPI_Comm *)gmove->sendbuf, &status);
127  }
128 #endif
129  }
130 
131 }
Here is the call graph for this function:

◆ xmp_is_async()

_Bool xmp_is_async ( )
21 {
22  return _xmp_is_async;
23 }
Here is the caller graph for this function:

◆ xmp_test_async_()

int xmp_test_async_ ( int *  async_id)
136 {
137  _XMP_async_comm_t *async;
138 
139  if (!(async = _XMP_get_async(*async_id))) return 1;
140 
141  int nreqs = async->nreqs;
142  MPI_Request *reqs = async->reqs;
143 
144 #if defined(_KCOMPUTER) && defined(K_RDMA_REFLECT)
145  // For RDMA reflects, async->nreqs > 0 and async->reqs == NULL.
146  _XMP_fatal("xmp_test_async not supported for RDMA.");
147 #endif
148 
149  int flag;
150  MPI_Testall(nreqs, reqs, &flag, MPI_STATUSES_IGNORE);
151 
152  if(flag){
153  _XMP_async_gmove_t *gmove = async->gmove;
154  if (gmove) _XMP_finalize_async_gmove(gmove);
155  else if(async->type == _XMP_COMM_REDUCE_SHADOW)
156  _XMP_reduce_shadow_sum(async->a);
157 
158  xmpc_end_async(*async_id);
159  return 1;
160  }
161  else{
162  return 0;
163  }
164 }
Here is the call graph for this function:

◆ xmpc_end_async()

void xmpc_end_async ( int  async_id)
328 {
329  int hash_id = async_id % _XMP_ASYNC_COMM_SIZE;
330  _XMP_async_comm_t *async = &_XMP_async_comm_tab[hash_id];
331 
332  if(!async->is_used) return;
333 
334  // The case no comm. registered for async_id 0 and xmpc_end_async called for
335  // async_id == 0, may occur and is inconsistent.
336  // But, actually, the code below works without problems in such a case, even if
337  // no hash_id == 0.
338  if(async->async_id == async_id){
339  if(async->next == NULL){
340  initialize_async(async);
341  }
342  else{
343  _XMP_async_comm_t *next = async->next;
344  initialize_async(async);
345  async->async_id = next->async_id;
346  async->nreqs = next->nreqs;
347  async->nnodes = next->nnodes;
348  async->is_used = next->is_used;
349  async->type = next->type;
350  async->node = next->node;
351  async->gmove = next->gmove;
352  async->reqs = next->reqs;
353  async->a = next->a;
354  async->next = next->next;
355  _XMP_free(next);
356  }
357  return;
358  }
359  else{
360  _XMP_async_comm_t *prev = async;
361  while((async = prev->next)){
362  if(async->async_id == async_id){
363  prev->next = async->next;
364  initialize_async(async);
365  _XMP_free(async);
366  return;
367  }
368  prev = async;
369  }
370  }
371 }

◆ xmpc_init_async()

void xmpc_init_async ( int  async_id)
220 {
221  _xmp_is_async = true;
222 
223  int hash_id = async_id % _XMP_ASYNC_COMM_SIZE;
224  _XMP_async_comm_t *async = &_XMP_async_comm_tab[hash_id];
225 
226  if(!async->is_used){
227  async->async_id = async_id;
228  async->reqs = _XMP_alloc(sizeof(MPI_Request) * _XMP_MAX_ASYNC_REQS);
229  async->is_used = true;
230  _tmp_async = async;
231  }
232  else{
233  if(async->async_id == async_id){
234  _tmp_async = async;
235  }
236  else{
237  while(async->next){
238  async = async->next;
239  if(async->async_id == async_id){
240  _tmp_async = async;
241  return;
242  }
243  }
244 
245  // When above while-statement cannot find a async descriptor,
246  // the following lines create a new async descriptor
247  async->next = _XMP_alloc(sizeof(_XMP_async_comm_t));
248  async = async->next;
249  async->async_id = async_id;
250  async->nreqs = 0;
251  async->nnodes = 0;
252  async->is_used = true;
253  async->type = _XMP_COMM_NONE;
254  async->node = NULL;
255  async->reqs = _XMP_alloc(sizeof(MPI_Request) * _XMP_MAX_ASYNC_REQS);
256  async->gmove = NULL;
257  async->a = NULL;
258  async->next = NULL;
259  _tmp_async = async;
260  }
261  }
262 }

◆ xmpc_start_async()

void xmpc_start_async ( )
290 {
291  _xmp_is_async = false;
292  _tmp_async = NULL;
293 }

Variable Documentation

◆ _XMP_unpack_comm_set

void(* _XMP_unpack_comm_set) (void *recvbuf, int recvbuf_size, _XMP_array_t *a, _XMP_comm_set_t *comm_set[][_XMP_N_MAX_DIM])
_XMP_COMM_NONE
#define _XMP_COMM_NONE
Definition: xmp_constant.h:135
_XMP_ASYNC_COMM_SIZE
#define _XMP_ASYNC_COMM_SIZE
Definition: xmp_data_struct.h:471
_XMP_MAX_ASYNC_REQS
#define _XMP_MAX_ASYNC_REQS
Definition: xmp_data_struct.h:472
_XMP_MAX_ASYNC_NODES
#define _XMP_MAX_ASYNC_NODES
Definition: xmp_data_struct.h:473
_XMP_alloc
void * _XMP_alloc(size_t size)
Definition: xmp_util.c:21
_XMP_async_comm::next
struct _XMP_async_comm * next
Definition: xmp_data_struct.h:468
_XMP_N_GMOVE_NORMAL
#define _XMP_N_GMOVE_NORMAL
Definition: xmp_constant.h:69
_XMP_async_gmove::sendbuf
void * sendbuf
Definition: xmp_data_struct.h:451
xmpc_end_async
void xmpc_end_async(int async_id)
Definition: xmp_async.c:327
_XMP_async_comm::gmove
_XMP_async_gmove_t * gmove
Definition: xmp_data_struct.h:466
_XMP_TEND
#define _XMP_TEND(t, t0)
Definition: xmp_internal.h:748
_XMP_async_comm::type
int type
Definition: xmp_data_struct.h:463
_XMP_async_comm::is_used
_Bool is_used
Definition: xmp_data_struct.h:462
_XMP_COMM_REDUCE_SHADOW
#define _XMP_COMM_REDUCE_SHADOW
Definition: xmp_constant.h:137
_XMP_TSTART
#define _XMP_TSTART(t0)
Definition: xmp_internal.h:747
_XMP_async_comm::nnodes
int nnodes
Definition: xmp_data_struct.h:461
_XMP_async_comm::nreqs
int nreqs
Definition: xmp_data_struct.h:460
_XMP_async_comm::reqs
MPI_Request * reqs
Definition: xmp_data_struct.h:464
_XMP_async_comm
Definition: xmp_data_struct.h:458
_XMP_free
void _XMP_free(void *p)
Definition: xmp_util.c:37
_XMP_async_comm::a
_XMP_array_t * a
Definition: xmp_data_struct.h:467
_XMP_sync_images_COMM
void _XMP_sync_images_COMM(MPI_Comm *comm, int *status)
Definition: xmp_coarray_mpi.c:1105
_XMP_async_comm::node
_XMP_nodes_t ** node
Definition: xmp_data_struct.h:465
_XMP_get_async
_XMP_async_comm_t * _XMP_get_async(int async_id)
Definition: xmp_async.c:30
_XMP_fatal
void _XMP_fatal(char *msg)
Definition: xmp_util.c:42
_XMP_reduce_shadow_sum
void _XMP_reduce_shadow_sum(_XMP_array_t *a)
Definition: xmp_reduce_shadow.c:153
_XMP_nodes_type
Definition: xmp_data_struct.h:40
_XMP_async_comm::async_id
int async_id
Definition: xmp_data_struct.h:459
_XMP_async_gmove::mode
int mode
Definition: xmp_data_struct.h:450
_XMP_async_gmove
Definition: xmp_data_struct.h:449