1 /* ----------------------------------------------------------------------
2 SPARTA - Stochastic PArallel Rarefied-gas Time-accurate Analyzer
3 http://sparta.sandia.gov
4 Steve Plimpton, sjplimp@sandia.gov, Michael Gallis, magalli@sandia.gov
5 Sandia National Laboratories
6
7 Copyright (2014) Sandia Corporation. Under the terms of Contract
8 DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
9 certain rights in this software. This software is distributed under
10 the GNU General Public License.
11
12 See the README file in the top-level SPARTA directory.
13 ------------------------------------------------------------------------- */
14
15 /* Single-processor "stub" versions of MPI routines */
16 /* -I. in Makefile insures dummy mpi.h in this dir is included */
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include <stdio.h>
21 #include <stdint.h>
22 #include <sys/time.h>
23 #include "mpi.h"
24
25 /* data structure for double/int */
26
27 struct _mpi_double_int {
28 double value;
29 int proc;
30 };
31 typedef struct _mpi_double_int double_int;
32
33 /* extra MPI_Datatypes registered by MPI_Type_contiguous */
34
35 #define MAXEXTRA_DATATYPE 16
36
37 int nextra_datatype;
38 MPI_Datatype *ptr_datatype[MAXEXTRA_DATATYPE];
39 int index_datatype[MAXEXTRA_DATATYPE];
40 int size_datatype[MAXEXTRA_DATATYPE];
41
42 static int _mpi_is_initialized=0;
43
44 /* ---------------------------------------------------------------------- */
45 /* MPI Functions */
46 /* ---------------------------------------------------------------------- */
47
MPI_Init(int * argc,char *** argv)48 int MPI_Init(int *argc, char ***argv)
49 {
50 if (_mpi_is_initialized > 0) {
51 printf("MPI Stub WARNING: MPI already initialized\n");
52 return 1;
53 }
54 if (_mpi_is_initialized < 0) {
55 printf("MPI Stub WARNING: MPI already finalized\n");
56 return 1;
57 }
58 _mpi_is_initialized = 1;
59 return 0;
60 }
61
62 /* ---------------------------------------------------------------------- */
63
MPI_Initialized(int * flag)64 int MPI_Initialized(int *flag)
65 {
66 *flag = (_mpi_is_initialized > 0) ? 1 : 0;
67 return 0;
68 }
69
70 /* ---------------------------------------------------------------------- */
71
MPI_Finalized(int * flag)72 int MPI_Finalized(int *flag)
73 {
74 *flag = (_mpi_is_initialized < 0) ? 1 : 0;
75 return 0;
76 }
77
78 /* ---------------------------------------------------------------------- */
79
80 /* return "localhost" as name of the processor */
81
MPI_Get_processor_name(char * name,int * resultlen)82 int MPI_Get_processor_name(char *name, int *resultlen)
83 {
84 const char host[] = "localhost";
85 int len;
86
87 if (!name || !resultlen) return MPI_ERR_ARG;
88
89 len = strlen(host);
90 memcpy(name,host,len+1);
91 *resultlen = len;
92 return MPI_SUCCESS;
93 }
94
95 /* ---------------------------------------------------------------------- */
96
97 /* return MPI version level. v1.2 is not 100% correct, but close enough */
98
MPI_Get_version(int * major,int * minor)99 int MPI_Get_version(int *major, int *minor)
100 {
101 if (!major || !minor) return MPI_ERR_ARG;
102
103 *major = 1;
104 *minor = 2;
105 return MPI_SUCCESS;
106 }
107
108 /* ---------------------------------------------------------------------- */
109
MPI_Comm_rank(MPI_Comm comm,int * me)110 int MPI_Comm_rank(MPI_Comm comm, int *me)
111 {
112 *me = 0;
113 return 0;
114 }
115
116 /* ---------------------------------------------------------------------- */
117
MPI_Comm_size(MPI_Comm comm,int * nprocs)118 int MPI_Comm_size(MPI_Comm comm, int *nprocs)
119 {
120 *nprocs = 1;
121 return 0;
122 }
123
124 /* ---------------------------------------------------------------------- */
125
MPI_Abort(MPI_Comm comm,int errorcode)126 int MPI_Abort(MPI_Comm comm, int errorcode)
127 {
128 exit(1);
129 return 0;
130 }
131
132 /* ---------------------------------------------------------------------- */
133
MPI_Finalize()134 int MPI_Finalize()
135 {
136 if (_mpi_is_initialized == 0) {
137 printf("MPI Stub WARNING: MPI not yet initialized\n");
138 return 1;
139 }
140 if (_mpi_is_initialized < 0) {
141 printf("MPI Stub WARNING: MPI already finalized\n");
142 return 1;
143 }
144 _mpi_is_initialized = -1;
145 return 0;
146 }
147
148 /* ---------------------------------------------------------------------- */
149
MPI_Wtime()150 double MPI_Wtime()
151 {
152 double time;
153 struct timeval tv;
154
155 gettimeofday(&tv,NULL);
156 time = 1.0 * tv.tv_sec + 1.0e-6 * tv.tv_usec;
157 return time;
158 }
159
160 /* ---------------------------------------------------------------------- */
161
162 /* include sizes of user defined datatypes, stored in extra lists */
163
stubtypesize(MPI_Datatype datatype)164 static int stubtypesize(MPI_Datatype datatype)
165 {
166 if (datatype == MPI_INT) return sizeof(int);
167 else if (datatype == MPI_FLOAT) return sizeof(float);
168 else if (datatype == MPI_DOUBLE) return sizeof(double);
169 else if (datatype == MPI_CHAR) return sizeof(char);
170 else if (datatype == MPI_BYTE) return sizeof(char);
171 else if (datatype == MPI_LONG) return sizeof(long);
172 else if (datatype == MPI_LONG_LONG) return sizeof(uint64_t);
173 else if (datatype == MPI_DOUBLE_INT) return sizeof(double_int);
174 else {
175 int i;
176 for (i = 0; i < nextra_datatype; i++)
177 if (datatype == index_datatype[i]) return size_datatype[i];
178 }
179 return 0;
180 }
181
182 /* ---------------------------------------------------------------------- */
183
MPI_Type_size(MPI_Datatype datatype,int * size)184 int MPI_Type_size(MPI_Datatype datatype, int *size)
185 {
186 if (size == NULL) return MPI_ERR_ARG;
187
188 *size = stubtypesize(datatype);
189 return 0;
190 }
191
192 /* ---------------------------------------------------------------------- */
193
MPI_Send(const void * buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)194 int MPI_Send(const void *buf, int count, MPI_Datatype datatype,
195 int dest, int tag, MPI_Comm comm)
196 {
197 printf("MPI Stub WARNING: Should not send message to self\n");
198 return 0;
199 }
200
201 /* ---------------------------------------------------------------------- */
202
MPI_Isend(const void * buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request * request)203 int MPI_Isend(const void *buf, int count, MPI_Datatype datatype,
204 int source, int tag, MPI_Comm comm, MPI_Request *request)
205 {
206 printf("MPI Stub WARNING: Should not send message to self\n");
207 return 0;
208 }
209
210 /* ---------------------------------------------------------------------- */
211
MPI_Rsend(const void * buf,int count,MPI_Datatype datatype,int dest,int tag,MPI_Comm comm)212 int MPI_Rsend(const void *buf, int count, MPI_Datatype datatype,
213 int dest, int tag, MPI_Comm comm)
214 {
215 printf("MPI Stub WARNING: Should not rsend message to self\n");
216 return 0;
217 }
218
219 /* ---------------------------------------------------------------------- */
220
MPI_Recv(void * buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Status * status)221 int MPI_Recv(void *buf, int count, MPI_Datatype datatype,
222 int source, int tag, MPI_Comm comm, MPI_Status *status)
223 {
224 printf("MPI Stub WARNING: Should not recv message from self\n");
225 return 0;
226 }
227
228 /* ---------------------------------------------------------------------- */
229
MPI_Irecv(void * buf,int count,MPI_Datatype datatype,int source,int tag,MPI_Comm comm,MPI_Request * request)230 int MPI_Irecv(void *buf, int count, MPI_Datatype datatype,
231 int source, int tag, MPI_Comm comm, MPI_Request *request)
232 {
233 printf("MPI Stub WARNING: Should not recv message from self\n");
234 return 0;
235 }
236
237 /* ---------------------------------------------------------------------- */
238
MPI_Wait(MPI_Request * request,MPI_Status * status)239 int MPI_Wait(MPI_Request *request, MPI_Status *status)
240 {
241 printf("MPI Stub WARNING: Should not wait on message from self\n");
242 return 0;
243 }
244
245 /* ---------------------------------------------------------------------- */
246
MPI_Waitall(int n,MPI_Request * request,MPI_Status * status)247 int MPI_Waitall(int n, MPI_Request *request, MPI_Status *status)
248 {
249 printf("MPI Stub WARNING: Should not wait on message from self\n");
250 return 0;
251 }
252
253 /* ---------------------------------------------------------------------- */
254
MPI_Waitany(int count,MPI_Request * request,int * index,MPI_Status * status)255 int MPI_Waitany(int count, MPI_Request *request, int *index,
256 MPI_Status *status)
257 {
258 printf("MPI Stub WARNING: Should not wait on message from self\n");
259 return 0;
260 }
261
262 /* ---------------------------------------------------------------------- */
263
MPI_Sendrecv(const void * sbuf,int scount,MPI_Datatype sdatatype,int dest,int stag,void * rbuf,int rcount,MPI_Datatype rdatatype,int source,int rtag,MPI_Comm comm,MPI_Status * status)264 int MPI_Sendrecv(const void *sbuf, int scount, MPI_Datatype sdatatype,
265 int dest, int stag, void *rbuf, int rcount,
266 MPI_Datatype rdatatype, int source, int rtag,
267 MPI_Comm comm, MPI_Status *status)
268 {
269 printf("MPI Stub WARNING: Should not send message to self\n");
270 return 0;
271 }
272
273 /* ---------------------------------------------------------------------- */
274
MPI_Get_count(MPI_Status * status,MPI_Datatype datatype,int * count)275 int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count)
276 {
277 printf("MPI Stub WARNING: Should not get count of message to self\n");
278 return 0;
279 }
280
281 /* ---------------------------------------------------------------------- */
282
MPI_Comm_split(MPI_Comm comm,int color,int key,MPI_Comm * comm_out)283 int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out)
284 {
285 *comm_out = comm;
286 return 0;
287 }
288
289 /* ---------------------------------------------------------------------- */
290
MPI_Comm_dup(MPI_Comm comm,MPI_Comm * comm_out)291 int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *comm_out)
292 {
293 *comm_out = comm;
294 return 0;
295 }
296
297 /* ---------------------------------------------------------------------- */
298
MPI_Comm_free(MPI_Comm * comm)299 int MPI_Comm_free(MPI_Comm *comm) {return 0;}
300
301 /* ---------------------------------------------------------------------- */
302
MPI_Comm_c2f(MPI_Comm comm)303 MPI_Fint MPI_Comm_c2f(MPI_Comm comm) { return comm; };
304
305 /* ---------------------------------------------------------------------- */
306
MPI_Comm_f2c(MPI_Fint comm)307 MPI_Comm MPI_Comm_f2c(MPI_Fint comm) { return comm; };
308
309 //* ---------------------------------------------------------------------- */
310
MPI_Comm_group(MPI_Comm comm,MPI_Group * group)311 int MPI_Comm_group(MPI_Comm comm, MPI_Group *group)
312 {
313 *group = comm;
314 return 0;
315 }
316
317 /* ---------------------------------------------------------------------- */
318
MPI_Comm_create(MPI_Comm comm,MPI_Group group,MPI_Comm * newcomm)319 int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm)
320 {
321 *newcomm = group;
322 return 0;
323 }
324
325 /* ---------------------------------------------------------------------- */
326
MPI_Group_incl(MPI_Group group,int n,int * ranks,MPI_Group * newgroup)327 int MPI_Group_incl(MPI_Group group, int n, int *ranks, MPI_Group *newgroup)
328 {
329 if (n > 0)
330 *newgroup = MPI_COMM_WORLD;
331 else
332 *newgroup = group;
333 return 0;
334 }
335 /* ---------------------------------------------------------------------- */
336
MPI_Cart_create(MPI_Comm comm_old,int ndims,int * dims,int * periods,int reorder,MPI_Comm * comm_cart)337 int MPI_Cart_create(MPI_Comm comm_old, int ndims, int *dims, int *periods,
338 int reorder, MPI_Comm *comm_cart)
339 {
340 *comm_cart = comm_old;
341 return 0;
342 }
343
344 /* ---------------------------------------------------------------------- */
345
MPI_Cart_get(MPI_Comm comm,int maxdims,int * dims,int * periods,int * coords)346 int MPI_Cart_get(MPI_Comm comm, int maxdims, int *dims, int *periods,
347 int *coords)
348 {
349 dims[0] = dims[1] = dims[2] = 1;
350 periods[0] = periods[1] = periods[2] = 1;
351 coords[0] = coords[1] = coords[2] = 0;
352 return 0;
353 }
354
355 /* ---------------------------------------------------------------------- */
356
MPI_Cart_shift(MPI_Comm comm,int direction,int displ,int * source,int * dest)357 int MPI_Cart_shift(MPI_Comm comm, int direction, int displ,
358 int *source, int *dest)
359 {
360 *source = *dest = 0;
361 return 0;
362 }
363
364 /* ---------------------------------------------------------------------- */
365
MPI_Cart_rank(MPI_Comm comm,int * coords,int * rank)366 int MPI_Cart_rank(MPI_Comm comm, int *coords, int *rank)
367 {
368 *rank = 0;
369 return 0;
370 }
371
372 /* ---------------------------------------------------------------------- */
373
374 /* store size of user datatype in extra lists */
375
MPI_Type_contiguous(int count,MPI_Datatype oldtype,MPI_Datatype * newtype)376 int MPI_Type_contiguous(int count, MPI_Datatype oldtype,
377 MPI_Datatype *newtype)
378 {
379 if (nextra_datatype == MAXEXTRA_DATATYPE) return -1;
380 ptr_datatype[nextra_datatype] = newtype;
381 index_datatype[nextra_datatype] = -(nextra_datatype + 1);
382 size_datatype[nextra_datatype] = count * stubtypesize(oldtype);
383 nextra_datatype++;
384 return 0;
385 }
386
387 /* ---------------------------------------------------------------------- */
388
389 /* set value of user datatype to internal negative index,
390 based on match of ptr */
391
MPI_Type_commit(MPI_Datatype * datatype)392 int MPI_Type_commit(MPI_Datatype *datatype)
393 {
394 int i;
395 for (i = 0; i < nextra_datatype; i++)
396 if (datatype == ptr_datatype[i]) *datatype = index_datatype[i];
397 return 0;
398 }
399
400 /* ---------------------------------------------------------------------- */
401
402 /* remove user datatype from extra lists */
403
MPI_Type_free(MPI_Datatype * datatype)404 int MPI_Type_free(MPI_Datatype *datatype)
405 {
406 int i;
407 for (i = 0; i < nextra_datatype; i++)
408 if (datatype == ptr_datatype[i]) {
409 ptr_datatype[i] = ptr_datatype[nextra_datatype-1];
410 index_datatype[i] = index_datatype[nextra_datatype-1];
411 size_datatype[i] = size_datatype[nextra_datatype-1];
412 nextra_datatype--;
413 break;
414 }
415 return 0;
416 }
417
418 /* ---------------------------------------------------------------------- */
419
MPI_Op_create(MPI_User_function * function,int commute,MPI_Op * op)420 int MPI_Op_create(MPI_User_function *function, int commute, MPI_Op *op)
421 {
422 return 0;
423 }
424
425 /* ---------------------------------------------------------------------- */
426
MPI_Op_free(MPI_Op * op)427 int MPI_Op_free(MPI_Op *op)
428 {
429 return 0;
430 }
431
432 /* ---------------------------------------------------------------------- */
433
MPI_Barrier(MPI_Comm comm)434 int MPI_Barrier(MPI_Comm comm) {return 0;}
435
436 /* ---------------------------------------------------------------------- */
437
MPI_Bcast(void * buf,int count,MPI_Datatype datatype,int root,MPI_Comm comm)438 int MPI_Bcast(void *buf, int count, MPI_Datatype datatype,
439 int root, MPI_Comm comm) {return 0;}
440
441 /* ---------------------------------------------------------------------- */
442
443 /* copy values from data1 to data2 */
444
MPI_Allreduce(void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,MPI_Comm comm)445 int MPI_Allreduce(void *sendbuf, void *recvbuf, int count,
446 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
447 {
448 int n = count * stubtypesize(datatype);
449
450 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
451 memcpy(recvbuf,sendbuf,n);
452 return 0;
453 }
454
455 /* ---------------------------------------------------------------------- */
456
457 /* copy values from data1 to data2 */
458
MPI_Reduce(void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,int root,MPI_Comm comm)459 int MPI_Reduce(void *sendbuf, void *recvbuf, int count,
460 MPI_Datatype datatype, MPI_Op op,
461 int root, MPI_Comm comm)
462 {
463 int n = count * stubtypesize(datatype);
464
465 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
466 memcpy(recvbuf,sendbuf,n);
467 return 0;
468 }
469
470
471 /* ---------------------------------------------------------------------- */
472
MPI_Scan(void * sendbuf,void * recvbuf,int count,MPI_Datatype datatype,MPI_Op op,MPI_Comm comm)473 int MPI_Scan(void *sendbuf, void *recvbuf, int count,
474 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
475 {
476 int n = count * stubtypesize(datatype);
477
478 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
479 memcpy(recvbuf,sendbuf,n);
480 return 0;
481 }
482
483 /* ---------------------------------------------------------------------- */
484
485 /* copy values from data1 to data2 */
486
MPI_Allgather(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int recvcount,MPI_Datatype recvtype,MPI_Comm comm)487 int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
488 void *recvbuf, int recvcount, MPI_Datatype recvtype,
489 MPI_Comm comm)
490 {
491 int n = sendcount * stubtypesize(sendtype);
492
493 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
494 memcpy(recvbuf,sendbuf,n);
495 return 0;
496 }
497
498 /* ---------------------------------------------------------------------- */
499
500 /* copy values from data1 to data2 */
501
MPI_Allgatherv(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int * recvcounts,int * displs,MPI_Datatype recvtype,MPI_Comm comm)502 int MPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
503 void *recvbuf, int *recvcounts, int *displs,
504 MPI_Datatype recvtype, MPI_Comm comm)
505 {
506 int n = sendcount * stubtypesize(sendtype);
507
508 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
509 memcpy(recvbuf,sendbuf,n);
510 return 0;
511 }
512
513 /* ---------------------------------------------------------------------- */
514
515 /* copy values from data1 to data2 */
516
MPI_Reduce_scatter(void * sendbuf,void * recvbuf,int * recvcounts,MPI_Datatype datatype,MPI_Op op,MPI_Comm comm)517 int MPI_Reduce_scatter(void *sendbuf, void *recvbuf, int *recvcounts,
518 MPI_Datatype datatype, MPI_Op op, MPI_Comm comm)
519 {
520 int n = *recvcounts * stubtypesize(datatype);
521
522 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
523 memcpy(recvbuf,sendbuf,n);
524 return 0;
525 }
526
527 /* ---------------------------------------------------------------------- */
528
529 /* copy values from data1 to data2 */
530
MPI_Gather(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int recvcount,MPI_Datatype recvtype,int root,MPI_Comm comm)531 int MPI_Gather(void *sendbuf, int sendcount, MPI_Datatype sendtype,
532 void *recvbuf, int recvcount, MPI_Datatype recvtype,
533 int root, MPI_Comm comm)
534 {
535 int n = sendcount * stubtypesize(sendtype);
536
537 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
538 memcpy(recvbuf,sendbuf,n);
539 return 0;
540 }
541
542 /* ---------------------------------------------------------------------- */
543
544 /* copy values from data1 to data2 */
545
MPI_Gatherv(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int * recvcounts,int * displs,MPI_Datatype recvtype,int root,MPI_Comm comm)546 int MPI_Gatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
547 void *recvbuf, int *recvcounts, int *displs,
548 MPI_Datatype recvtype, int root, MPI_Comm comm)
549 {
550 int n = sendcount * stubtypesize(sendtype);
551
552 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
553 memcpy(recvbuf,sendbuf,n);
554 return 0;
555 }
556
557 /* ---------------------------------------------------------------------- */
558
559 /* copy values from data1 to data2 */
560
MPI_Scatter(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int recvcount,MPI_Datatype recvtype,int root,MPI_Comm comm)561 int MPI_Scatter(void *sendbuf, int sendcount, MPI_Datatype sendtype,
562 void *recvbuf, int recvcount, MPI_Datatype recvtype,
563 int root, MPI_Comm comm)
564 {
565 int n = recvcount * stubtypesize(recvtype);
566
567 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
568 memcpy(recvbuf,sendbuf,n);
569 return 0;
570 }
571
572
573 /* ---------------------------------------------------------------------- */
574
575 /* copy values from data1 to data2 */
576
MPI_Scatterv(void * sendbuf,int * sendcounts,int * displs,MPI_Datatype sendtype,void * recvbuf,int recvcount,MPI_Datatype recvtype,int root,MPI_Comm comm)577 int MPI_Scatterv(void *sendbuf, int *sendcounts, int *displs,
578 MPI_Datatype sendtype, void *recvbuf, int recvcount,
579 MPI_Datatype recvtype, int root, MPI_Comm comm)
580 {
581 int n = recvcount * stubtypesize(recvtype);
582
583 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
584 memcpy(recvbuf,sendbuf,n);
585 return 0;
586 }
587
588 /* ---------------------------------------------------------------------- */
589
590 /* copy values from data1 to data2 */
591
MPI_Alltoall(void * sendbuf,int sendcount,MPI_Datatype sendtype,void * recvbuf,int recvcount,MPI_Datatype recvtype,MPI_Comm comm)592 int MPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
593 void *recvbuf, int recvcount, MPI_Datatype recvtype,
594 MPI_Comm comm)
595 {
596 int n = sendcount * stubtypesize(sendtype);
597
598 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
599 memcpy(recvbuf,sendbuf,n);
600 return 0;
601 }
602
603 /* ---------------------------------------------------------------------- */
604
605 /* copy values from data1 to data2 */
606
MPI_Alltoallv(void * sendbuf,int * sendcounts,int * sdispls,MPI_Datatype sendtype,void * recvbuf,int * recvcounts,int * rdispls,MPI_Datatype recvtype,MPI_Comm comm)607 int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
608 MPI_Datatype sendtype,
609 void *recvbuf, int *recvcounts, int *rdispls,
610 MPI_Datatype recvtype, MPI_Comm comm)
611 {
612 int n = *sendcounts * stubtypesize(sendtype);
613
614 if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE) return 0;
615 memcpy(recvbuf,sendbuf,n);
616 return 0;
617 }
618
619 /* ---------------------------------------------------------------------- */
620