In the following example, we see how to implement a Cartesian topology of the size M×N. Also, we define a set of coordinates to understand how all the processes are disposed of:
- Import all the relevant libraries:
from mpi4py import MPI import numpy as np
- Define the following parameter in order to move along the topology:
UP = 0 DOWN = 1 LEFT = 2 RIGHT = 3
- For each process, the following array defines the neighbor processes:
neighbour_processes = [0,0,0,0]
- In the main program, the comm.rank and size parameters are then defined:
if __name__ == "__main__": comm = MPI.COMM_WORLD rank = comm.rank size = comm.size
- Now, let's build the topology:
grid_rows = int(np.floor(np.sqrt(comm.size))) grid_column = comm.size // grid_rows
- The following conditions ensure that the processes are always within the topology:
if grid_rows*grid_column > size: grid_column -= 1 if grid_rows*grid_column > size: grid_rows -= 1
- The rank equal to 0 process starts the topology construction:
if (rank == 0) : print("Building a %d x %d grid topology:" % (grid_rows, grid_column) ) cartesian_communicator = comm.Create_cart( (grid_rows, grid_column), periods=(False, False),
reorder=True) my_mpi_row, my_mpi_col = cartesian_communicator.Get_coords ( cartesian_communicator.rank ) neighbour_processes[UP], neighbour_processes[DOWN] = cartesian_communicator.Shift(0, 1) neighbour_processes[LEFT], neighbour_processes[RIGHT] = cartesian_communicator.Shift(1, 1) print ("Process = %s
ow = %s column = %s ----> neighbour_processes[UP] = %s neighbour_processes[DOWN] = %s neighbour_processes[LEFT] =%s neighbour_processes[RIGHT]=%s" %(rank, my_mpi_row, my_mpi_col,neighbour_processes[UP], neighbour_processes[DOWN], neighbour_processes[LEFT] , neighbour_processes[RIGHT]))