File: dgraph_unwgtf.f

package info (click to toggle)
mpich 3.2-7
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 81,040 kB
  • ctags: 68,664
  • sloc: ansic: 358,905; f90: 54,597; perl: 18,527; cpp: 10,203; sh: 9,839; xml: 8,195; fortran: 7,799; makefile: 4,868; ruby: 53; sed: 9; php: 8
file content (216 lines) | stat: -rw-r--r-- 7,590 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
C -*- Mode: Fortran; -*- 
C
C  (C) 2011 by Argonne National Laboratory.
C      See COPYRIGHT in top-level directory.
C
C     This program is Fortran version of dgraph_unwgt.c
C     Specify a distributed graph of a bidirectional ring of the MPI_COMM_WORLD,
C     i.e. everyone only talks to left and right neighbors.

      logical function validate_dgraph(dgraph_comm)
      implicit none
      include 'mpif.h'

      integer     dgraph_comm
      integer     comm_topo
      integer     src_sz, dest_sz
      integer     ierr;
      logical     wgt_flag;
      integer     srcs(2), dests(2)

      integer     world_rank, world_size;
      integer     idx, nbr_sep

      comm_topo = MPI_UNDEFINED
      call MPI_Topo_test(dgraph_comm, comm_topo, ierr);
      if (comm_topo .ne. MPI_DIST_GRAPH) then
          validate_dgraph = .false.
          write(6,*) "dgraph_comm is NOT of type MPI_DIST_GRAPH."
          return
      endif

      call MPI_Dist_graph_neighbors_count(dgraph_comm,
     &                                    src_sz, dest_sz, wgt_flag,
     &                                    ierr)
      if (ierr .ne. MPI_SUCCESS) then
          validate_dgraph = .false.
          write(6,*) "MPI_Dist_graph_neighbors_count() fails!"
          return
      endif
      if (wgt_flag) then
          validate_dgraph = .false.
          write(6,*) "dgraph_comm is NOT created with MPI_UNWEIGHTED."
          return
      endif

      if (src_sz .ne. 2 .or. dest_sz .ne. 2) then
          validate_dgraph = .false.
          write(6,*) "source or destination edge array is not size 2." 
          write(6,"('src_sz = ',I3,', dest_sz = ',I3)") src_sz, dest_sz
          return
      endif

      call MPI_Dist_graph_neighbors(dgraph_comm,
     &                              src_sz, srcs, MPI_UNWEIGHTED,
     &                              dest_sz, dests, MPI_UNWEIGHTED,
     &                              ierr)
      if (ierr .ne. MPI_SUCCESS) then
          validate_dgraph = .false.
          write(6,*) "MPI_Dist_graph_neighbors() fails!"
          return
      endif

C     Check if the neighbors returned from MPI are really
C     the nearest neighbors that within a ring.
      call MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr)
      call MPI_Comm_size(MPI_COMM_WORLD, world_size, ierr)
 
      do idx = 1, src_sz
          nbr_sep = iabs(srcs(idx) - world_rank)
          if (nbr_sep .ne. 1 .and. nbr_sep .ne. (world_size-1)) then
              validate_dgraph = .false.
              write(6,"('srcs[',I3,']=',I3,
     &                  ' is NOT a neighbor of my rank',I3)")
     &              idx, srcs(idx), world_rank
              return
          endif
      enddo
      do idx = 1, dest_sz
          nbr_sep = iabs(dests(idx) - world_rank)
          if (nbr_sep .ne. 1 .and. nbr_sep .ne. (world_size-1)) then
              validate_dgraph = .false.
              write(6,"('dests[',I3,']=',I3,
     &                  ' is NOT a neighbor of my rank',I3)")
     &              idx, dests(idx), world_rank
              return
          endif
      enddo

      validate_dgraph = .true.
      return
      end

      integer function ring_rank(world_size, in_rank)
      implicit none
      integer world_size, in_rank
      if (in_rank .ge. 0 .and. in_rank .lt. world_size) then
          ring_rank = in_rank
          return
      endif
      if (in_rank .lt. 0 ) then
          ring_rank = in_rank + world_size
          return
      endif
      if (in_rank .ge. world_size) then
          ring_rank = in_rank - world_size
          return
      endif
      ring_rank = -99999
      return
      end



      program dgraph_unwgt
      implicit none
      include 'mpif.h'

      integer    ring_rank
      external   ring_rank
      logical    validate_dgraph
      external   validate_dgraph
      integer    errs, ierr

      integer    dgraph_comm
      integer    world_size, world_rank
      integer    src_sz, dest_sz
      integer    degs(1)
      integer    srcs(2), dests(2)

      errs = 0
      call MTEST_Init(ierr) 
      call MPI_Comm_rank(MPI_COMM_WORLD, world_rank, ierr)
      call MPI_Comm_size(MPI_COMM_WORLD, world_size, ierr)

      srcs(1) = world_rank
      degs(1) = 2;
      dests(1) = ring_rank(world_size, world_rank-1)
      dests(2) = ring_rank(world_size, world_rank+1)
      call MPI_Dist_graph_create(MPI_COMM_WORLD, 1, srcs, degs, dests,
     &                           MPI_UNWEIGHTED, MPI_INFO_NULL,
     &                          .true., dgraph_comm, ierr)
      if (ierr .ne. MPI_SUCCESS) then
          write(6,*) "MPI_Dist_graph_create() fails!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      if (.not. validate_dgraph(dgraph_comm)) then
          write(6,*) "MPI_Dist_graph_create() does not create"
     &               //"a bidirectional ring graph!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      call MPI_Comm_free(dgraph_comm, ierr)

C now create one with MPI_WEIGHTS_EMPTY
C NOTE that MPI_WEIGHTS_EMPTY was added in MPI-3 and does not 
C appear before then.  Incluing this test means that this test cannot
C be compiled if the MPI version is less than 3 (see the testlist file)

      degs(1) = 0;
      call MPI_Dist_graph_create(MPI_COMM_WORLD, 1, srcs, degs, dests,
     &                           MPI_WEIGHTS_EMPTY, MPI_INFO_NULL,
     &                          .true., dgraph_comm, ierr)
      if (ierr .ne. MPI_SUCCESS) then
          write(6,*) "MPI_Dist_graph_create() fails!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      call MPI_Comm_free(dgraph_comm, ierr)

      src_sz   = 2
      srcs(1)  = ring_rank(world_size, world_rank-1)
      srcs(2)  = ring_rank(world_size, world_rank+1)
      dest_sz  = 2
      dests(1) = ring_rank(world_size, world_rank-1)
      dests(2) = ring_rank(world_size, world_rank+1)
      call MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD,
     &                                    src_sz, srcs,
     &                                    MPI_UNWEIGHTED,
     &                                    dest_sz, dests,
     &                                    MPI_UNWEIGHTED,
     &                                    MPI_INFO_NULL, .true.,
     &                                    dgraph_comm, ierr)
      if (ierr .ne. MPI_SUCCESS) then
          write(6,*) "MPI_Dist_graph_create_adjacent() fails!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      if (.not. validate_dgraph(dgraph_comm)) then
          write(6,*) "MPI_Dist_graph_create_adjacent() does not create"
     &               //"a bidirectional ring graph!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      call MPI_Comm_free(dgraph_comm, ierr)

C now create one with MPI_WEIGHTS_EMPTY
      src_sz   = 0
      dest_sz  = 0
      call MPI_Dist_graph_create_adjacent(MPI_COMM_WORLD,
     &                                    src_sz, srcs,
     &                                    MPI_WEIGHTS_EMPTY,
     &                                    dest_sz, dests,
     &                                    MPI_WEIGHTS_EMPTY,
     &                                    MPI_INFO_NULL, .true.,
     &                                    dgraph_comm, ierr)
      if (ierr .ne. MPI_SUCCESS) then
          write(6,*) "MPI_Dist_graph_create_adjacent() fails!"
          call MPI_Abort(MPI_COMM_WORLD, 1, ierr)
          stop
      endif
      call MPI_Comm_free(dgraph_comm, ierr)

      call MTEST_Finalize(errs)
      call MPI_Finalize(ierr)
      end