1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/*@@
@file PostReceiveGA.c
@date Wed Feb 2 11:28:06 1997
@author Gabrielle Allen
@desc
Routines which post all the IRecv commands for a GA. These
allow the asyncronous model proposed in, for example,
@seeroutine SyncGA to go!
@enddesc
@version $Header$
@@*/
#include <stdio.h>
#include "pugh.h"
static char *rcsid = "$Header$";
CCTK_FILEVERSION(CactusPUGH_PUGH_PostReceiveGA_c)
/*#define DEBUG_PUGH*/
/*@@
@routine PostReceiveGA
@date Thu Apr 3 12:10:46 1997
@author Paul Walker
@desc
This routine posts a recieve (MPI_Irecv) of the buffer
we want to get the send from another processor, which
will be sent by @seeroutine pGA_PostSend and then
finalized by @seeroutoine pGA_FinishRecv.
<p>
Aside from a silly calculation to get a unique tag
based on neigbors and processors, this is a very
straightforward routine.
@enddesc
@history
@hdate Nov 4 1998 @hauthor Gabrielle Allen
@hdesc Allow for forced synchronization of all GAs with storage
@endhistory
@@*/
void PostReceiveGA(pGH *GH, pGA *GA, int dir)
{
#ifdef CCTK_MPI
int rtag;
MPI_Datatype mpi_type;
MPI_Datatype *recv_dt;
if (!(GA->storage))
{
CCTK_VWarn(2, __LINE__, __FILE__, CCTK_THORNSTRING,
"Trying to synchronize variable '%s' with no storage", GA->name);
return;
}
/* Return if communication not required and no forced synchronisation */
if (!(GH->forceSync || GA->docomm[dir]))
{
return;
}
if (GA->connectivity->neighbours[GH->myproc][dir] < 0)
{
return;
}
switch (GA->vtype)
{
case CCTK_VARIABLE_CHAR:
mpi_type = PUGH_MPI_CHAR;
recv_dt = GH->recv_char_dt [GA->stagger];
break;
case CCTK_VARIABLE_INT:
mpi_type = PUGH_MPI_INT;
recv_dt = GH->recv_int_dt [GA->stagger];
break;
case CCTK_VARIABLE_REAL:
mpi_type = PUGH_MPI_REAL;
recv_dt = GH->recv_real_dt [GA->stagger];
break;
case CCTK_VARIABLE_COMPLEX:
mpi_type = GH->PUGH_mpi_complex;
recv_dt = GH->recv_complex_dt [GA->stagger];
break;
default:
CCTK_WARN (1, "Unknown variable type in PostReceiveGA");
return;
}
rtag = 1000 + dir + 2 * (GH->myproc + GH->nprocs * GA->id);
/* mod the tag to force MPI compliance */
rtag = rtag % 32768;
#ifdef DEBUG_PUGH
printf ("RECV GA %s Side %d Proc %d rtag %d size %d from proc %d\n",
GA->name,
dir,
GH->myproc,
rtag,
GA->buffer_sz[dir],
GA->connectivity->neighbours[GH->myproc][dir]);
#endif
if (GH->commmodel == PUGH_ALLOCATEDBUFFERS)
{
CACTUS_MPI_ERROR (MPI_Irecv (GA->recv_buffer [dir],
GA->buffer_sz [dir], mpi_type,
GA->connectivity->neighbours [GH->myproc][dir], rtag,
GH->PUGH_COMM_WORLD, &(GA->rreq [dir])));
}
if (GH->commmodel == PUGH_DERIVEDTYPES)
{
CACTUS_MPI_ERROR (MPI_Irecv (GA->data,
1, recv_dt [dir],
GA->connectivity->neighbours [GH->myproc][dir], rtag,
GH->PUGH_COMM_WORLD, &(GA->rreq [dir])));
}
#endif
}
|