program cartesian use mpi implicit none INTEGER :: world_rank, row_rank, col_rank, cart_rank INTEGER :: nprocs, row_size, col_size INTEGER :: dims(2), coords(2) LOGICAL :: period(2), sub_coords(2) INTEGER :: src_rank, dst_rank INTEGER :: sum, temp REAL :: avg INTEGER :: cart_grid, cart_row, cart_col, status, ierr !$ MPI Initialization CALL MPI_Init(ierr) CALL MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr) CALL MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr) !$ Cartesian grid creation: ! - the function MPI_Dims_create may be used to compute dimensions in both directions ! - MPI_Cart_create must be used to create the new topology ! - cart_grid will be the handle of the new topology dims(1) = 0 dims(2) = 0 period(1) = .true. period(2) = .true. --- !$ Local world_rank initialization and comparison to global world_rank: ! - how can you get 'cart_rank'? --- WRITE (*,'(a,i1,a,i1,a)') 'I am world_rank ', world_rank, ' in MPI_COMM_WORLD and world_rank ', cart_rank , ' in the & cartesian communicator' !$ Coordinates creation and neighbour communication: ! - get process cartesian coordinates 'coords' with function MPI_Cart_coords --- !$ Communication south: ! - use MPI_Cart_shift and MPI_Sendrecv properly to send local rank to the neighbours ! - receive neighbour rank in 'temp' variable and store sum in 'sum' --- !$ Communication north --- !$ Communication east --- !$ Communication west --- !$ Neighbour's average avg = REAL(sum)/5 WRITE (*,'(a,i2,a,i1,a,i1,a,f6.2)') 'Cart rank ', cart_rank, ' (', coords(1), ', ', coords(2), & '), neighbours average: ', avg !$ Row sub-communicator creation: ! - how would you create a "row sub-communicator" ? ! - use the function MPI_Cart_sub to get 'cart_row' communicator handle ! - use the proper functions to get 'row_size' and 'row_rank' sum = 0 sub_coords(1) = .false. sub_coords(2) = .true. --- !$ Use MPI_Reduce to sum up ranks in row sub-communicator --- if (row_rank.eq.0) then avg = REAL(sum) /row_size WRITE (*,'(a,i1,a,f6.2)') 'Row ',coords(1),' row average: ',avg endif !$ Column sub-communicator creation: ! - repeate to obtain 'cart-col' comm-handle and 'col_size' and 'col_rank' sum = 0 sub_coords(1) = .true. sub_coords(2) = .false. --- !$ Use MPI_Reduce to sum up ranks in column sub-communicator's average calculation --- if (col_rank.eq.0) then avg = REAL(sum) / col_size WRITE (*,'(a,i1,a,f6.2)') 'Column ',coords(2),' column average: ',avg endif !$ Finalization operations CALL MPI_Comm_free(cart_grid, ierr) CALL MPI_Comm_free(cart_col, ierr) CALL MPI_Comm_free(cart_row, ierr) CALL MPI_Finalize(ierr) end program cartesian