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