~ubuntu-branches/ubuntu/saucy/nwchem/saucy

« back to all changes in this revision

Viewing changes to src/tools/ga-5-1/armci/src/devices/mpi-mt/mpi2_client.c

  • Committer: Package Import Robot
  • Author(s): Michael Banck, Michael Banck, Daniel Leidert
  • Date: 2012-02-09 20:02:41 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120209200241-jgk03qfsphal4ug2
Tags: 6.1-1
* New upstream release.

[ Michael Banck ]
* debian/patches/02_makefile_flags.patch: Updated.
* debian/patches/02_makefile_flags.patch: Use internal blas and lapack code.
* debian/patches/02_makefile_flags.patch: Define GCC4 for LINUX and LINUX64
  (Closes: #632611 and LP: #791308).
* debian/control (Build-Depends): Added openssh-client.
* debian/rules (USE_SCALAPACK, SCALAPACK): Removed variables (Closes:
  #654658).
* debian/rules (LIBDIR, USE_MPIF4, ARMCI_NETWORK): New variables.
* debian/TODO: New file.
* debian/control (Build-Depends): Removed libblas-dev, liblapack-dev and
  libscalapack-mpi-dev.
* debian/patches/04_show_testsuite_diff_output.patch: New patch, shows the
  diff output for failed tests.
* debian/patches/series: Adjusted.
* debian/testsuite: Optionally run all tests if "all" is passed as option.
* debian/rules: Run debian/testsuite with "all" if DEB_BUILD_OPTIONS
  contains "checkall".

[ Daniel Leidert ]
* debian/control: Used wrap-and-sort. Added Vcs-Svn and Vcs-Browser fields.
  (Priority): Moved to extra according to policy section 2.5.
  (Standards-Version): Bumped to 3.9.2.
  (Description): Fixed a typo.
* debian/watch: Added.
* debian/patches/03_hurd-i386_define_path_max.patch: Added.
  - Define MAX_PATH if not defines to fix FTBFS on hurd.
* debian/patches/series: Adjusted.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#if HAVE_CONFIG_H
 
2
#   include "config.h"
 
3
#endif
 
4
 
 
5
/**
 
6
 * MPI_SPAWN: ARMCI on top of MPI Multithreaded
 
7
 * Abhinav Vishnu 
 
8
 */
 
9
 
 
10
#if HAVE_STDARG_H
 
11
#   include <stdarg.h>
 
12
#endif
 
13
#if HAVE_STDIO_H
 
14
#   include <stdio.h>
 
15
#endif
 
16
#if HAVE_STRING_H
 
17
#   include <string.h>
 
18
#endif
 
19
#if HAVE_STDLIB_H
 
20
#   include <stdlib.h>
 
21
#endif
 
22
#include "mpi.h"
 
23
 
 
24
#include "mpi2.h"
 
25
#include "armcip.h"
 
26
#include "request.h"
 
27
#include "shmem.h"
 
28
#include "locks.h"
 
29
 
 
30
#include <assert.h>
 
31
 
 
32
#define ARMCI_ROOT 0 /* root process */
 
33
 
 
34
/* Inter-communicators for communicating between clients and data servers */
 
35
MPI_Comm MPI_COMM_CLIENT2SERVER=MPI_COMM_NULL;
 
36
 
 
37
static int armci_nserver=-1;
 
38
static int *_armci_mpi_tag=NULL;
 
39
 
 
40
extern char ***_armci_argv;
 
41
extern int armci_get_shmem_info(char *addrp,  int* shmid, long *shmoffset,
 
42
                                size_t *shmsize);
 
43
 
 
44
#if MPI_SPAWN_DEBUG
 
45
void armci_mpi2_debug(int rank, const char *format, ...) 
 
46
{
 
47
    va_list arg;
 
48
    if(rank == armci_me) 
 
49
    {
 
50
       va_start(arg, format);
 
51
       printf("%d: ", rank);
 
52
       vprintf(format, arg);
 
53
       va_end(arg);
 
54
       fflush(stdout);
 
55
    }
 
56
}
 
57
#else
 
58
#define armci_mpi2_debug(x, ...)
 
59
#endif
 
60
 
 
61
#if MPI_SPAWN_DEBUG
 
62
static inline int MPI_Check (int status)
 
63
{
 
64
    if(status != MPI_SUCCESS) 
 
65
    {
 
66
       armci_mpi2_debug(armci_me, "MPI Check failed.\n");
 
67
       armci_die("MPI_Check failed.", 0);
 
68
    }
 
69
}
 
70
#else
 
71
# define MPI_Check(x) x
 
72
#endif
 
73
 
 
74
 
 
75
/**************************************************************************
 
76
 * Platform specific server code as required by the ARMCI s/w layer. (BEGIN)
 
77
 */
 
78
 
 
79
/* Create connections between clients and servers */
 
80
void armci_init_connections()
 
81
{
 
82
    armci_mpi2_debug(0, "armci_init_connections\n");
 
83
    _armci_buf_init();    /* CHECK: Is this correct ? */
 
84
    MPI_Check(MPI_Barrier(ARMCI_COMM_WORLD));
 
85
    /* Abhinav Vishnu */
 
86
    armci_create_server_MPIprocess();
 
87
 
 
88
    armci_mpi2_debug(0, "armci_init_connections completed\n");
 
89
}
 
90
 
 
91
void armci_wait_for_server()
 
92
{
 
93
    armci_mpi2_debug(0, "armci_wait_for_server: wait for server to quit\n");
 
94
    if (armci_me == armci_master)
 
95
    {
 
96
       armci_serv_quit();  
 
97
    }
 
98
}
 
99
 
 
100
void armci_client_connect_to_servers()
 
101
{
 
102
 
 
103
    /* Abhinav Vishnu */
 
104
}
 
105
 
 
106
/* NOTE: armci_mpi_strided and armci_mpi_strided2 are the only 2 functions
 
107
 * that are common to client and server part  */
 
108
void armci_mpi_strided_c2s(int op, void *ptr, int stride_levels, int stride_arr[], 
 
109
                       int count[], int proc, MPI_Comm comm)
 
110
{
 
111
    int i, j;
 
112
    long idx;    /* index offset of current block position to ptr */
 
113
    int n1dim;  /* number of 1 dim block */
 
114
    int bvalue[MAX_STRIDE_LEVEL], bunit[MAX_STRIDE_LEVEL];
 
115
    MPI_Status status;
 
116
    
 
117
    /* number of n-element of the first dimension */
 
118
    n1dim = 1;
 
119
    for(i=1; i<=stride_levels; i++)
 
120
        n1dim *= count[i];
 
121
 
 
122
    /* calculate the destination indices */
 
123
    bvalue[0] = 0; bvalue[1] = 0; bunit[0] = 1; bunit[1] = 1;
 
124
    for(i=2; i<=stride_levels; i++)
 
125
    {
 
126
        bvalue[i] = 0;
 
127
        bunit[i] = bunit[i-1] * count[i-1];
 
128
    }
 
129
 
 
130
    for(i=0; i<n1dim; i++)
 
131
    {
 
132
        idx = 0;
 
133
        for(j=1; j<=stride_levels; j++)
 
134
        {
 
135
            idx += bvalue[j] * stride_arr[j-1];
 
136
            if((i+1) % bunit[j] == 0) bvalue[j]++;
 
137
            if(bvalue[j] > (count[j]-1)) bvalue[j] = 0;
 
138
        }
 
139
 
 
140
        if(op == SEND) 
 
141
        {
 
142
           MPI_Check(
 
143
              MPI_Send(((char*)ptr)+idx, count[0], MPI_BYTE, proc,
 
144
                       ARMCI_MPI_CLIENT2SERVER_TAG, comm)
 
145
              );
 
146
        }
 
147
        else /* ( op == RECV) */
 
148
        {
 
149
           MPI_Check(
 
150
              MPI_Recv(((char*)ptr)+idx, count[0], MPI_BYTE, proc,
 
151
                       ARMCI_MPI_SERVER2CLIENT_TAG, comm, &status)
 
152
              );
 
153
        }
 
154
    }
 
155
}
 
156
 
 
157
/* This is the only function that is common to client and server part */
 
158
void armci_mpi_strided2(int op, void *ptr, int stride_levels, int stride_arr[],
 
159
                        int count[], int proc, MPI_Comm comm)
 
160
{
 
161
    /* Not supported */
 
162
    assert(0);
 
163
}
 
164
 
 
165
/*\ client sends request message to server
 
166
\*/
 
167
int armci_send_req_msg (int proc, void *buf, int bytes)
 
168
{
 
169
  int clus_id = armci_clus_id(proc);
 
170
  int server ;
 
171
 
 
172
  /* Abhinav Vishnu */
 
173
  server = armci_clus_info[clus_id].master;
 
174
 
 
175
  armci_mpi2_debug(armci_me, "armci_send_req_msg(): proc=%d, server=%d, "
 
176
                   "buf=%p, bytes=%d\n", proc, server, buf, bytes);
 
177
 
 
178
  MPI_Check(
 
179
     MPI_Send(buf, bytes, MPI_BYTE, server, ARMCI_MPI_CLIENT2SERVER_TAG,
 
180
              ARMCI_COMM_WORLD)
 
181
     );
 
182
  armci_mpi2_debug(armci_me, "armci_send_req_msg(): send msg to server(%d), to"
 
183
                   "fwd to client %d\n", server, proc);
 
184
 
 
185
  return 0;
 
186
}
 
187
 
 
188
/*\ client sends strided data + request to server
 
189
\*/
 
190
int armci_send_req_msg_strided(int proc, request_header_t *msginfo,char *ptr,
 
191
                               int strides, int stride_arr[], int count[])
 
192
{
 
193
    int server;
 
194
    int clus_id = armci_clus_id(proc);
 
195
    int bytes;
 
196
 
 
197
    /* Abhinav Vishnu */
 
198
    server = armci_clus_info[clus_id].master;
 
199
 
 
200
    armci_mpi2_debug(armci_me, "armci_send_req_msg_strided: proc=%d server=%d "
 
201
                     "bytes=%d (op=%d)\n", proc, server, msginfo->datalen,
 
202
                     msginfo->operation);
 
203
 
 
204
 
 
205
    /* we write header + descriptor of strided data  */
 
206
    bytes = sizeof(request_header_t) + msginfo->dscrlen;
 
207
    armci_send_req_msg(proc, msginfo, bytes);
 
208
    
 
209
    {
 
210
       /* for larger blocks write directly thus avoiding memcopy */
 
211
       armci_mpi_strided_c2s(SEND, ptr, strides, stride_arr, count, server,
 
212
                         ARMCI_COMM_WORLD);
 
213
    }
 
214
       
 
215
 
 
216
    armci_mpi2_debug(armci_me, "armci_send_req_msg_strided(): send msg to "
 
217
                     "server(%d), to fwd to client %d\n", server, proc);
 
218
 
 
219
    return 0;
 
220
}
 
221
 
 
222
/*\ client receives data from server
 
223
\*/
 
224
char *armci_ReadFromDirect (int proc, request_header_t *msginfo, int len)
 
225
{
 
226
 
 
227
    int server;
 
228
    int clus_id = armci_clus_id(proc);
 
229
    MPI_Status status;
 
230
 
 
231
    server = armci_clus_info[clus_id].master;
 
232
 
 
233
    armci_mpi2_debug(armci_me, "armci_ReadFromDirect: proc=%d, server=%d, "
 
234
                     "msginfo=%p, bytes=%d (op=%d)\n", proc, server, msginfo,
 
235
                     len, msginfo->operation);
 
236
    MPI_Check(
 
237
       MPI_Recv(msginfo + 1, len, MPI_BYTE, server, ARMCI_MPI_SERVER2CLIENT_TAG,
 
238
                ARMCI_COMM_WORLD, &status)
 
239
       );
 
240
 
 
241
    
 
242
    armci_mpi2_debug(armci_me, "recv msg from server(%d), fwd by client %d\n",
 
243
                     server, proc);
 
244
 
 
245
    {
 
246
        int count;
 
247
        MPI_Get_count(&status, MPI_BYTE, &count);
 
248
        if (count != len) 
 
249
        {
 
250
            armci_mpi2_debug(armci_me, "armci_ReadFromDirect: got %d bytes, "
 
251
                    "expected %d bytes\n", count, len);
 
252
            armci_die("armci_ReadFromDirect: MPI_Recv failed.", count);
 
253
        }
 
254
    }
 
255
    
 
256
 return (char *) (msginfo+1);
 
257
}
 
258
 
 
259
/*\ client receives strided data from server
 
260
\*/
 
261
void armci_ReadStridedFromDirect(int proc, request_header_t* msginfo,
 
262
                                 void *ptr, int strides, int stride_arr[],
 
263
                                 int count[])
 
264
{
 
265
 
 
266
    int server;
 
267
    int clus_id = armci_clus_id(proc);
 
268
 
 
269
    /* Abhinav Vishnu */
 
270
    server = armci_clus_info[clus_id].master;
 
271
    
 
272
    armci_mpi2_debug(armci_me, "armci_ReadStridedFromDirect: proc=%d "
 
273
                     "stride_levels=%d, server=%d bytes=%d (op=%d)\n",
 
274
                     proc, strides, server, msginfo->datalen,
 
275
                     msginfo->operation);
 
276
 
 
277
    {
 
278
       armci_mpi_strided_c2s(RECV, ptr, strides, stride_arr, count, server,
 
279
                         ARMCI_COMM_WORLD);
 
280
    }
 
281
}
 
282
 
 
283
 
 
284
 
 
285
/**
 
286
 * Platform specific server code ENDs here. (END)
 
287
 **************************************************************************/
 
288
 
 
289
static void armci_gather_hostnames(char **hostname_arr) 
 
290
{
 
291
    /* Code must not flow through here */
 
292
    assert(0);
 
293
}
 
294
 
 
295
 
 
296
 
 
297
/**
 
298
 * Create server processes. This is called in armci_start_server.
 
299
 * Must be called after armci_init_clusinfo().
 
300
 */
 
301
void armci_create_server_MPIprocess ()
 
302
{
 
303
    int rank, size, flag, i;
 
304
 
 
305
    MPI_Check(MPI_Initialized(&flag));
 
306
    if (flag == 0)
 
307
       armci_die("ARMCI error: MPI_Init must be called before PARMCI_Init()",0);
 
308
    
 
309
    MPI_Check(MPI_Comm_rank(ARMCI_COMM_WORLD, &rank));
 
310
    MPI_Check(MPI_Comm_size(ARMCI_COMM_WORLD, &size));
 
311
 
 
312
    armci_nserver = armci_nclus;
 
313
    
 
314
    /* makesure all processes sync here. CHECK: does it ensure global sync ? */
 
315
    MPI_Check(MPI_Barrier(ARMCI_COMM_WORLD));
 
316
 
 
317
    armci_mpi2_debug(0, "armci_create_server_MPIprocess: Servers spawned!\n");
 
318
}
 
319
 
 
320