|
Packit |
0848f5 |
C -*- Mode: Fortran; -*-
|
|
Packit |
0848f5 |
C
|
|
Packit |
0848f5 |
C (C) 2011 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
C See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
C
|
|
Packit |
0848f5 |
C This program is Fortran version of dgraph_unwgt.c
|
|
Packit |
0848f5 |
C Specify a distributed graph of a bidirectional ring of the MPI_COMM_WORLD,
|
|
Packit |
0848f5 |
C i.e. everyone only talks to left and right neighbors.
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
logical function validate_dgraph(dgraph_comm)
|
|
Packit |
0848f5 |
implicit none
|
|
Packit |
0848f5 |
include 'mpif.h'
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
integer dgraph_comm
|
|
Packit |
0848f5 |
integer comm_topo
|
|
Packit |
0848f5 |
integer src_sz, dest_sz
|
|
Packit |
0848f5 |
integer ierr;
|
|
Packit |
0848f5 |
logical wgt_flag;
|
|
Packit |
0848f5 |
integer srcs(2), dests(2)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
integer world_rank, world_size;
|
|
Packit |
0848f5 |
integer idx, nbr_sep
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
comm_topo = MPI_UNDEFINED
|
|
Packit |
0848f5 |
call MPI_Topo_test(dgraph_comm, comm_topo, ierr);
|
|
Packit |
0848f5 |
if (comm_topo .ne. MPI_DIST_GRAPH) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,*) "dgraph_comm is NOT of type MPI_DIST_GRAPH."
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
call MPI_Dist_graph_neighbors_count(dgraph_comm,
|
|
Packit |
0848f5 |
& src_sz, dest_sz, wgt_flag,
|
|
Packit |
0848f5 |
& ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_neighbors_count() fails!"
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
if (wgt_flag) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,*) "dgraph_comm is NOT created with MPI_UNWEIGHTED."
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (src_sz .ne. 2 .or. dest_sz .ne. 2) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,*) "source or destination edge array is not size 2."
|
|
Packit |
0848f5 |
write(6,"('src_sz = ',I3,', dest_sz = ',I3)") src_sz, dest_sz
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
call MPI_Dist_graph_neighbors(dgraph_comm,
|
|
Packit |
0848f5 |
& src_sz, srcs, MPI_UNWEIGHTED,
|
|
Packit |
0848f5 |
& dest_sz, dests, MPI_UNWEIGHTED,
|
|
Packit |
0848f5 |
& ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_neighbors() fails!"
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
C Check if the neighbors returned from MPI are really
|
|
Packit |
0848f5 |
C the nearest neighbors that within a ring.
|
|
Packit |
0848f5 |
call MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr)
|
|
Packit |
0848f5 |
call MPI_Comm_size(MPI_COMM_WORLD, world_size, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
do idx = 1, src_sz
|
|
Packit |
0848f5 |
nbr_sep = iabs(srcs(idx) - world_rank)
|
|
Packit |
0848f5 |
if (nbr_sep .ne. 1 .and. nbr_sep .ne. (world_size-1)) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,"('srcs[',I3,']=',I3,
|
|
Packit |
0848f5 |
& ' is NOT a neighbor of my rank',I3)")
|
|
Packit |
0848f5 |
& idx, srcs(idx), world_rank
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
enddo
|
|
Packit |
0848f5 |
do idx = 1, dest_sz
|
|
Packit |
0848f5 |
nbr_sep = iabs(dests(idx) - world_rank)
|
|
Packit |
0848f5 |
if (nbr_sep .ne. 1 .and. nbr_sep .ne. (world_size-1)) then
|
|
Packit |
0848f5 |
validate_dgraph = .false.
|
|
Packit |
0848f5 |
write(6,"('dests[',I3,']=',I3,
|
|
Packit |
0848f5 |
& ' is NOT a neighbor of my rank',I3)")
|
|
Packit |
0848f5 |
& idx, dests(idx), world_rank
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
enddo
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
validate_dgraph = .true.
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
end
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
integer function ring_rank(world_size, in_rank)
|
|
Packit |
0848f5 |
implicit none
|
|
Packit |
0848f5 |
integer world_size, in_rank
|
|
Packit |
0848f5 |
if (in_rank .ge. 0 .and. in_rank .lt. world_size) then
|
|
Packit |
0848f5 |
ring_rank = in_rank
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
if (in_rank .lt. 0 ) then
|
|
Packit |
0848f5 |
ring_rank = in_rank + world_size
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
if (in_rank .ge. world_size) then
|
|
Packit |
0848f5 |
ring_rank = in_rank - world_size
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
ring_rank = -99999
|
|
Packit |
0848f5 |
return
|
|
Packit |
0848f5 |
end
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
program dgraph_unwgt
|
|
Packit |
0848f5 |
implicit none
|
|
Packit |
0848f5 |
include 'mpif.h'
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
integer ring_rank
|
|
Packit |
0848f5 |
external ring_rank
|
|
Packit |
0848f5 |
logical validate_dgraph
|
|
Packit |
0848f5 |
external validate_dgraph
|
|
Packit |
0848f5 |
integer errs, ierr
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
integer dgraph_comm
|
|
Packit |
0848f5 |
integer world_size, world_rank
|
|
Packit |
0848f5 |
integer src_sz, dest_sz
|
|
Packit |
0848f5 |
integer degs(1)
|
|
Packit |
0848f5 |
integer srcs(2), dests(2)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
errs = 0
|
|
Packit |
0848f5 |
call MTEST_Init(ierr)
|
|
Packit |
0848f5 |
call MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr)
|
|
Packit |
0848f5 |
call MPI_Comm_size(MPI_COMM_WORLD, world_size, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
srcs(1) = world_rank
|
|
Packit |
0848f5 |
degs(1) = 2;
|
|
Packit |
0848f5 |
dests(1) = ring_rank(world_size, world_rank-1)
|
|
Packit |
0848f5 |
dests(2) = ring_rank(world_size, world_rank+1)
|
|
Packit |
0848f5 |
call MPI_Dist_graph_create(MPI_COMM_WORLD, 1, srcs, degs, dests,
|
|
Packit |
0848f5 |
& MPI_UNWEIGHTED, MPI_INFO_NULL,
|
|
Packit |
0848f5 |
& .true., dgraph_comm, ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create() fails!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
if (.not. validate_dgraph(dgraph_comm)) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create() does not create"
|
|
Packit |
0848f5 |
& //"a bidirectional ring graph!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
call MPI_Comm_free(dgraph_comm, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
C now create one with MPI_WEIGHTS_EMPTY
|
|
Packit |
0848f5 |
C NOTE that MPI_WEIGHTS_EMPTY was added in MPI-3 and does not
|
|
Packit |
0848f5 |
C appear before then. Incluing this test means that this test cannot
|
|
Packit |
0848f5 |
C be compiled if the MPI version is less than 3 (see the testlist file)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
degs(1) = 0;
|
|
Packit |
0848f5 |
call MPI_Dist_graph_create(MPI_COMM_WORLD, 1, srcs, degs, dests,
|
|
Packit |
0848f5 |
& MPI_WEIGHTS_EMPTY, MPI_INFO_NULL,
|
|
Packit |
0848f5 |
& .true., dgraph_comm, ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create() fails!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
call MPI_Comm_free(dgraph_comm, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
src_sz = 2
|
|
Packit |
0848f5 |
srcs(1) = ring_rank(world_size, world_rank-1)
|
|
Packit |
0848f5 |
srcs(2) = ring_rank(world_size, world_rank+1)
|
|
Packit |
0848f5 |
dest_sz = 2
|
|
Packit |
0848f5 |
dests(1) = ring_rank(world_size, world_rank-1)
|
|
Packit |
0848f5 |
dests(2) = ring_rank(world_size, world_rank+1)
|
|
Packit |
0848f5 |
call MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD,
|
|
Packit |
0848f5 |
& src_sz, srcs,
|
|
Packit |
0848f5 |
& MPI_UNWEIGHTED,
|
|
Packit |
0848f5 |
& dest_sz, dests,
|
|
Packit |
0848f5 |
& MPI_UNWEIGHTED,
|
|
Packit |
0848f5 |
& MPI_INFO_NULL, .true.,
|
|
Packit |
0848f5 |
& dgraph_comm, ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create_adjacent() fails!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
if (.not. validate_dgraph(dgraph_comm)) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create_adjacent() does not create"
|
|
Packit |
0848f5 |
& //"a bidirectional ring graph!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
call MPI_Comm_free(dgraph_comm, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
C now create one with MPI_WEIGHTS_EMPTY
|
|
Packit |
0848f5 |
src_sz = 0
|
|
Packit |
0848f5 |
dest_sz = 0
|
|
Packit |
0848f5 |
call MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD,
|
|
Packit |
0848f5 |
& src_sz, srcs,
|
|
Packit |
0848f5 |
& MPI_WEIGHTS_EMPTY,
|
|
Packit |
0848f5 |
& dest_sz, dests,
|
|
Packit |
0848f5 |
& MPI_WEIGHTS_EMPTY,
|
|
Packit |
0848f5 |
& MPI_INFO_NULL, .true.,
|
|
Packit |
0848f5 |
& dgraph_comm, ierr)
|
|
Packit |
0848f5 |
if (ierr .ne. MPI_SUCCESS) then
|
|
Packit |
0848f5 |
write(6,*) "MPI_Dist_graph_create_adjacent() fails!"
|
|
Packit |
0848f5 |
call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
|
|
Packit |
0848f5 |
stop
|
|
Packit |
0848f5 |
endif
|
|
Packit |
0848f5 |
call MPI_Comm_free(dgraph_comm, ierr)
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
call MTEST_Finalize(errs)
|
|
Packit |
0848f5 |
call MPI_Finalize(ierr)
|
|
Packit |
0848f5 |
end
|