source: CPL/oasis3-mct_5.0/lib/mct/mpi-serial/mpi.c @ 6328

Last change on this file since 6328 was 6328, checked in by aclsce, 17 months ago

First import of oasis3-mct_5.0 (from oasis git server, branch OASIS3-MCT_5.0)

File size: 8.5 KB
Line 
1
2
3#include "mpiP.h"
4#include "mpi.h"
5#include "type.h"
6
7/****************************************************************************/
8
9static int initialized=0;
10
11
12/* Store fortran pointer values here */
13
14static int *f_MPI_STATUS_IGNORE;
15static int *f_MPI_STATUSES_IGNORE;
16static int *f_MPI_IN_PLACE;
17
18static char *mpi_version_string="mpi-serial 2.3";
19
20
21/****************************************************************************/
22
23
24/*
25 * INIT/FINALIZE
26 *
27 */
28
29
30
31FC_FUNC( mpi_init_fort , MPI_INIT_FORT)
32                          (int *f_MPI_COMM_WORLD,
33                           int *f_MPI_ANY_SOURCE, int *f_MPI_ANY_TAG,
34                           int *f_MPI_PROC_NULL, int *f_MPI_ROOT,
35                           int *f_MPI_COMM_NULL, int *f_MPI_REQUEST_NULL,
36                           int *f_MPI_GROUP_NULL, int *f_MPI_GROUP_EMPTY,
37                           int *f_MPI_UNDEFINED,
38                           int *f_MPI_MAX_ERROR_STRING,
39                           int *f_MPI_MAX_PROCESSOR_NAME,
40                           int *f_MPI_STATUS_SIZE,
41                           int *f_MPI_SOURCE, int *f_MPI_TAG, int *f_MPI_ERROR,
42                           int *f_status,
43                           int *fsource, int *ftag, int *ferror,
44                           int *f_MPI_INTEGER, void *fint1, void *fint2,
45                           int *f_MPI_LOGICAL, void *flog1, void *flog2,
46                           int *f_MPI_REAL, void *freal1, void *freal2,
47                           int *f_MPI_DOUBLE_PRECISION,
48                           void *fdub1, void *fdub2,
49                           int *f_MPI_COMPLEX, void *fcomp1, void *fcomp2,
50                           int *ierror)
51{
52  int err;
53  int size;
54  int offset;
55
56  *ierror=MPI_Init(NULL,NULL);
57
58  err=0;
59
60  /*
61   * These 3 macros compare things from mpif.h (as passed in by the f_
62   * arguments) to the values in C (from #including mpi.h).
63   *
64   * Unfortunately, this kind of thing is done most easily in a nasty
65   * looking macto.
66   *
67   */
68
69
70  /*
71   * verify_eq
72   *   compare value of constants in C and fortran
73   *   i.e. compare *f_<name> to <name>
74   */
75
76#define verify_eq(name)  \
77  if (*f_##name != name) \
78    { fprintf(stderr,"mpi-serial: mpi_init_fort: %s not consistent " \
79                     "between mpif.h (%d) and mpi.h (%d)\n",\
80                     #name,*f_##name,name); \
81      err=1; }
82
83#define verify_eq_warn(name)  \
84  if (*f_##name != name) \
85    { fprintf(stderr,"mpi-serial: mpi_init_fort: warning: %s not consistent " \
86                     "between mpif.h (%d) and mpi.h (%d)\n",\
87                     #name,*f_##name,name); \
88    }
89
90
91  /*
92   * verify_size
93   *   verify that the type name in fortran has the correct
94   *   value (i.e. the size of that data type).
95   *   Determine size by subtracting the pointer values of two
96   *   consecutive array locations.
97   */
98
99#define verify_size(name,p1,p2) \
100  if ( (size=((char *)(p2) - (char *)(p1))) != Simpletype_length( \
101              (*(Datatype*)mpi_handle_to_datatype(*f_##name))->pairs[0].type) ) \
102    { fprintf(stderr,"mpi-serial: mpi_init_fort: mpif.h %s (%d) " \
103                     "does not match actual fortran size (%d)\n", \
104                     #name,*f_##name,size); \
105      err=1; }
106
107  /*
108   * verify_field
109   *   check the struct member offsets for MPI_Status vs. the
110   *   fortan integer array offsets.  E.g. the location of
111   *   status->MPI_SOURCE should be the same as STATUS(MPI_SOURCE)
112   */
113
114#define verify_field(name) \
115  { offset= (char *)&((MPI_Status *)f_status)->name - (char *)f_status; \
116    if ( offset != (*f_##name-1)*sizeof(int) ) \
117    { fprintf(stderr,"mpi-serial: mpi_init_fort: mpif.h %s (%d) (%d bytes) " \
118                     "is inconsistent w/offset in MPI_Status (%d bytes)\n", \
119                    #name,*f_##name,(*f_##name-1)*sizeof(int),offset); \
120      err=1; }}
121
122
123
124  verify_eq(MPI_COMM_WORLD);
125  verify_eq(MPI_ANY_SOURCE);
126  verify_eq(MPI_ANY_TAG);
127  verify_eq(MPI_PROC_NULL);
128  verify_eq(MPI_ROOT);
129  verify_eq(MPI_COMM_NULL);
130  verify_eq(MPI_REQUEST_NULL);
131  verify_eq(MPI_GROUP_NULL);
132  verify_eq(MPI_GROUP_EMPTY);
133  verify_eq(MPI_UNDEFINED);
134  verify_eq(MPI_MAX_ERROR_STRING);
135  verify_eq(MPI_MAX_PROCESSOR_NAME);
136
137  verify_eq(MPI_STATUS_SIZE);
138  verify_field(MPI_SOURCE);
139  verify_field(MPI_TAG);
140  verify_field(MPI_ERROR);
141
142  verify_eq(MPI_INTEGER);
143  verify_size(MPI_INTEGER,fint1,fint2);
144
145  verify_size(MPI_LOGICAL,flog1,flog2);
146
147  verify_eq_warn(MPI_REAL);
148  verify_size(MPI_REAL,freal1,freal2);
149
150  verify_eq(MPI_DOUBLE_PRECISION);
151  verify_size(MPI_DOUBLE_PRECISION,fdub1,fdub2);
152
153  verify_size(MPI_COMPLEX,fcomp1,fcomp2);
154
155  if (err)
156    abort();
157}
158
159int MPI_Init_thread(int *argc, char **argv[], int required, int *provided)
160{
161    *provided = required;
162    return MPI_Init(argc, argv);
163}
164
165int MPI_Init(int *argc, char **argv[])
166{
167  MPI_Comm my_comm_world;
168
169  if (sizeof(MPI_Aint) < sizeof(void *))
170    {
171      fprintf(stderr, "mpi-serial: MPI_Init: "
172                      "MPI_Aint is not large enough for void *\n");
173      abort();
174    }
175
176  my_comm_world=mpi_comm_new();
177
178  if (my_comm_world != MPI_COMM_WORLD)
179    {
180      fprintf(stderr,"MPI_Init: conflicting MPI_COMM_WORLD\n");
181      abort();
182    }
183
184  // call this to have the fortran routine call back and save
185  // values for f_MPI_STATUS_IGNORE and f_MPI_STATUSES_IGNORE
186  FC_FUNC(mpi_get_fort_pointers,MPI_GET_FORT_POINTERS)();  // the () are important
187
188  initialized=1;
189  return(MPI_SUCCESS);
190}
191
192
193/*********/
194
195
196FC_FUNC( mpi_finalize, MPI_FINALIZE )(int *ierror)
197{
198  *ierror=MPI_Finalize();
199}
200
201
202/*
203 * MPI_Finalize()
204 *
205 * this library doesn't support re-initializing MPI, so
206 * the finalize will just leave everythign as it is...
207 *
208 */
209
210
211int MPI_Finalize(void)
212{
213  initialized=0;
214
215  mpi_destroy_handles();
216
217  return(MPI_SUCCESS);
218}
219
220
221/*********/
222
223
224FC_FUNC( mpi_abort , MPI_ABORT )(int *comm, int *errorcode, int *ierror)
225{
226  *ierror=MPI_Abort( *comm, *errorcode);
227}
228
229
230
231int MPI_Abort(MPI_Comm comm, int errorcode)
232{
233  fprintf(stderr,"MPI_Abort: error code = %d\n",errorcode);
234  exit(errorcode);
235}
236
237
238/*********/
239
240
241
242FC_FUNC( mpi_error_string , MPI_ERROR_STRING)
243                             (int *errorcode, char *string,
244                              int *resultlen, int *ierror)
245{
246  *ierror=MPI_Error_string(*errorcode, string, resultlen);
247}
248
249
250int MPI_Error_string(int errorcode, char *string, int *resultlen)
251{
252  sprintf(string,"MPI Error: code %d\n",errorcode);
253  *resultlen=strlen(string);
254
255  return(MPI_SUCCESS);
256}
257
258
259/*********/
260
261
262FC_FUNC( mpi_get_processor_name , MPI_GET_PROCESSOR_NAME )
263                          (char *name, int *resultlen, int *ierror)
264{
265  *ierror=MPI_Get_processor_name(name,resultlen);
266}
267
268
269int MPI_Get_processor_name(char *name, int *resultlen)
270{
271  int ret;
272
273  ret=gethostname(name,MPI_MAX_PROCESSOR_NAME);
274
275  if (ret!=0)
276    strncpy(name,"unknown host name",MPI_MAX_PROCESSOR_NAME);
277
278
279  name[MPI_MAX_PROCESSOR_NAME-1]='\0';  /* make sure NULL terminated */
280  *resultlen=strlen(name);
281
282  return(MPI_SUCCESS);
283}
284
285
286/*********/
287
288
289FC_FUNC( mpi_initialized , MPI_INITIALIZED )(int *flag, int *ierror)
290{
291  *ierror=MPI_Initialized(flag);
292}
293
294
295int MPI_Initialized(int *flag)
296{
297  *flag= initialized;
298
299  return(MPI_SUCCESS);
300}
301
302
303/**********/
304
305
306void FC_FUNC( mpi_get_library_version, MPI_GET_LIBRARY_VERSION) (char *version, int *resultlen, int *ierror)
307{
308  MPI_Get_library_version(version,resultlen);
309
310  // Sanity check before the memset()
311  if ( (*resultlen) > (MPI_MAX_LIBRARY_VERSION_STRING-1) )
312    abort();
313
314  memset(version+(*resultlen),' ',MPI_MAX_LIBRARY_VERSION_STRING-(*resultlen));
315
316  *ierror=MPI_SUCCESS;
317}
318
319
320
321int MPI_Get_library_version(char *version, int *resultlen)
322{
323
324  strncpy(version,mpi_version_string,MPI_MAX_LIBRARY_VERSION_STRING);
325  // Make sure it is null terminated
326  version[MPI_MAX_LIBRARY_VERSION_STRING-1]='\0';
327  *resultlen=strlen(version);
328
329  return(MPI_SUCCESS);
330}
331
332/**********/
333void FC_FUNC( mpi_get_version, MPI_GET_VERSION )(int *mpi_vers, int *mpi_subvers, int *ierror)
334{
335  MPI_Get_Version(mpi_vers, mpi_subvers);
336
337  *ierror=MPI_SUCCESS;
338}
339
340int MPI_Get_Version(int *mpi_vers, int *mpi_subvers)
341{
342  *mpi_vers = 1;
343  *mpi_subvers = 0;
344
345  return (MPI_SUCCESS);
346}
347
348/**********/
349
350
351void FC_FUNC( mpi_save_fort_pointers, MPI_SAVE_FORT_POINTERS ) (int *status, int *statuses, int *in_place)
352{
353  f_MPI_STATUS_IGNORE=status;
354  f_MPI_STATUSES_IGNORE=statuses;
355  f_MPI_IN_PLACE=in_place;
356}
357
358
359
360MPI_Status *mpi_c_status(int *status)
361{
362  if (status==f_MPI_STATUS_IGNORE)
363    return(MPI_STATUS_IGNORE);
364
365  return((MPI_Status *)status);
366}
367
368
369MPI_Status *mpi_c_statuses(int *statuses)
370{
371  if (statuses==f_MPI_STATUSES_IGNORE)
372    return(MPI_STATUSES_IGNORE);
373
374  return((MPI_Status *)statuses);
375}
376
377
378void *mpi_c_in_place(void *buffer)
379{
380  if (buffer==(void *)f_MPI_IN_PLACE)
381    return(MPI_IN_PLACE);
382
383  return(buffer);
384}
Note: See TracBrowser for help on using the repository browser.