HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
MPIGatherArray1D.c File Reference

Gathers local 1D arrays to a global 1D array. More...

#include <stdio.h>
#include <stdlib.h>
#include <basic.h>
#include <arrayfunctions.h>
#include <mpivars.h>

Go to the source code of this file.

Functions

int MPIGatherArray1D (void *m, double *xg, double *x, int istart, int iend, int N_local, int ghosts)
 

Detailed Description

Gathers local 1D arrays to a global 1D array.

Author
Debojyoti Ghosh

Definition in file MPIGatherArray1D.c.

Function Documentation

int MPIGatherArray1D ( void *  m,
double *  xg,
double *  x,
int  istart,
int  iend,
int  N_local,
int  ghosts 
)

Gathers the contents of a 1D array (partitioned amongst MPI ranks) into a global 1D array on the root rank (rank 0). See documentation of MPIExchangeBoundaries1D() on what a "1D array" is in the context of a multidimensional simulation. The 1D array must be the same along spatial dimensions normal to the one it represents.

Notes:

  • The global array must not have ghost points.
  • The global array must be preallocated on only rank 0. On other ranks, it must be NULL.
  • Since this function deals with a 1D array, more than one rank may be sending the same piece of data to rank 0 (i.e. if there are more than one MPI rank along the dimensions normal to one corresponding to x ). The implementation of this function ignores this and overwrites that portion with the latest data sent.
Parameters
mMPI object of type MPIVariables
xgGlobal 1D array (must be preallocated) without ghost points
xLocal 1D array to be gathered
istartStarting index (global) of this rank's portion of the array
iendEnding index (global) of this rank's portion of the array + 1
N_localLocal size of the array
ghostsNumber of ghost points

Definition at line 26 of file MPIGatherArray1D.c.

35 {
36  MPIVariables *mpi = (MPIVariables*) m;
37  int ierr = 0;
38 
39  /* xg should be non-null only on root */
40  if (mpi->rank && xg) {
41  fprintf(stderr,"Error in MPIGatherArray1D(): global array exists on non-root processors (rank %d).\n",
42  mpi->rank);
43  ierr = 1;
44  }
45  if ((!mpi->rank) && (!xg)) {
46  fprintf(stderr,"Error in MPIGatherArray1D(): global array is not allocated on root processor.\n");
47  ierr = 1;
48  }
49 
50  /* create and copy data to a buffer to send to the root process */
51  double *buffer = (double*) calloc (N_local,sizeof(double));
52  _ArrayCopy1D_((x+ghosts),(buffer),N_local);
53 
54  if (!mpi->rank) {
55 #ifndef serial
56  MPI_Status status;
57 #endif
58  int proc;
59  for (proc = 0; proc < mpi->nproc; proc++) {
60  /* Find out the domain limits for each process */
61  int is,ie;
62  if (proc) {
63 #ifndef serial
64  MPI_Recv(&is,1,MPI_INT,proc,1442,mpi->world,&status);
65  MPI_Recv(&ie,1,MPI_INT,proc,1443,mpi->world,&status);
66 #endif
67  } else { is = istart; ie = iend; }
68  int size = ie - is;
69  if (proc) {
70 #ifndef serial
71  double *recvbuf = (double*) calloc (size,sizeof(double));
72  MPI_Recv(recvbuf,size,MPI_DOUBLE,proc,1916,mpi->world,&status);
73  _ArrayCopy1D_((recvbuf),(xg+is),size);
74  free(recvbuf);
75 #endif
76  } else _ArrayCopy1D_(buffer,(xg+is),size);
77  }
78 
79  } else {
80 #ifndef serial
81  /* Meanwhile, on other processes - send stuff to root */
82  MPI_Send(&istart,1 ,MPI_INT ,0,1442,mpi->world);
83  MPI_Send(&iend ,1 ,MPI_INT ,0,1443,mpi->world);
84  MPI_Send(buffer ,N_local,MPI_DOUBLE,0,1916,mpi->world);
85 #endif
86  }
87 
88  free(buffer);
89  return(ierr);
90 }
MPI_Comm world
#define _ArrayCopy1D_(x, y, size)
Structure of MPI-related variables.