MPI_Cart_shift finds the resulting source and destination ranks – given a shift direction and amount.

Fortran Syntax

Subroutine MPI_Cart_shift(comm, direction, displ, source, dest, ierr)

C Syntax

int MPI_Cart_shift(MPI_Comm comm, int direction, int displ, int *source, int *dest)

Loosely speaking, MPI_Cart_shift is used to find two “nearby”
neighbors of the calling process along a specific direction of an N-dimensional cartesian topology. This direction is specified by the input argument, direction, to MPI_Cart_shift. The two neighbors are called source and destination ranks and the proximity of these two neighbors to the calling process is determined by the input parameter displ. If displ = 1, the neighbors are the two adjoining processes along the specified direction and the source is the process with the lower rank number while the destination rank is the process with the higher rank. On the other hand, if displ = -1, the reverse is true. A simple code fragment and a complete sample code are shown below to demonstrate the usage. A more practical example is shown in the iterative solvers application.

Example in Fortran

!**create cartesian topology for processes
      dims(1) = nrow      ! number of rows
      dims(2) = mcol      ! number of columns
      period(0) = .true.  ! cyclic in this direction
      period(1) = .false. ! no cyclic in this direction
      call MPI_Cart_create(MPI_COMM_WORLD, ndim, dims,
     &       period, reorder, comm2D, ierr)
      call MPI_Comm_rank(comm2D, me, ierr)
      call MPI_Cart_coords(comm2D, me, ndim, coords, ierr)

      direction =  0   ! shift along the 1st index (0 or 1)
      displ =  1       ! shift by  1

      call MPI_Cart_shift(comm2D, direction, displ, source, dest, ierr)

Example in C

/* create cartesian topology for processes */
  dims[0] = nrow;     /* number of rows     */
  dims[1] = mcol;     /* number of columns  */
  period[0] = 1;      /* cyclic in this direction */
  period[1] = 0;      /* no cyclic in this direction */
  MPI_Cart_create(MPI_COMM_WORLD, ndim, dims, period, reorder, &comm2D);
  MPI_Comm_rank(comm2D, &me);
  MPI_Cart_coords(comm2D, me, ndim, coords);

  source = me;   /* calling process rank in 2D communicator */
  index =  0;    /* shift along the 1st index (out of 2) */
  displ =  1;    /* shift by  1 */

  MPI_Cart_shift(comm2D, index, displ, source, &dest1);

In the above example, we demonstrate the application of MPI_Cart_shift to obtain the source and destination rank numbers of the calling process, me, resulting from shifting it along the first direction of the 2D cartesian grid by one.

Shown in Figure a below is a 3×2 cartesian topology (grid) where the index pair “i,j” represent row “i” and column “j”. The number in parentheses represents the rank number associated with the cartesian coordinates.

Figure a. Cartesian Grid
0,0 (0) 0,1 (1)
1,0 (2) 1,1 (3)
2,0 (4) 2,1 (5)

With the input as specified above and if the calling process were, say 2, the source and destination ranks as a result of the shift would be 0 and 4, respectively. Similarly, if the calling process were 1, the source rank would be 5 and destination rank would be 3. The source rank of 5 is the consequence of period(0) = .true. More examples are included in this sample code.

Note that:

  • direction, the cartesian grid index, has range (0, 1, …, ndim-1). For a 2D grid, the 2 choices for direction are 0 and 1.
  • the returned rank number resulting from the MPI_Cart_shift call is informational only. It does not result in the calling process rank to change.
  • a negative returned value (MPI_UNDEFINED) signifies that the shift is out of bound.
  • if cyclic condition is present along the shift direction, out of bound would not result. (see sample code).