xref: /phasta/M2NFixBnd/src/ctypes.f (revision 595995161822a203c8467e0e4a253d7bd7d6df32)
1*59599516SKenneth E. Jansen      subroutine ctypes (ilwork)
2*59599516SKenneth E. Jansen
3*59599516SKenneth E. Jansen      parameter (maxseg = 60000)
4*59599516SKenneth E. Jansen
5*59599516SKenneth E. Jansen      include "commonM2NFixBnd.h"
6*59599516SKenneth E. Jansen      include "mpif.h"
7*59599516SKenneth E. Jansen      include "auxmpiM2NFixBnd.h"
8*59599516SKenneth E. Jansen
9*59599516SKenneth E. Jansen      integer  sizeofdouble
10*59599516SKenneth E. Jansen
11*59599516SKenneth E. Jansen      dimension ilwork(nlwork)
12*59599516SKenneth E. Jansen      dimension isbegin(maxseg), lenseg(maxseg), ioffset(maxseg)
13*59599516SKenneth E. Jansen
14*59599516SKenneth E. Jansen      real*8 timer1,timer2,time_ellapsed
15*59599516SKenneth E. Jansen      integer istatRanks(2)
16*59599516SKenneth E. Jansen      real*8 rStats(4)
17*59599516SKenneth E. Jansen
18*59599516SKenneth E. Jansen!      timer1 = TMRC()
19*59599516SKenneth E. Jansen
20*59599516SKenneth E. Jansen      CALL MPI_TYPE_EXTENT (MPI_DOUBLE_PRECISION,sizeofdouble,ierr)
21*59599516SKenneth E. Jansen      lstride = nshg * sizeofdouble
22*59599516SKenneth E. Jansenc
23*59599516SKenneth E. Jansenc.... maxfront is a common variable being set in this routine
24*59599516SKenneth E. Jansenc
25*59599516SKenneth E. Jansen      maxfront = 0
26*59599516SKenneth E. Jansen      numtask = ilwork (1)
27*59599516SKenneth E. Jansen      itkbeg  = 1
28*59599516SKenneth E. Jansen
29*59599516SKenneth E. Jansen
30*59599516SKenneth E. Jansen      if (numtask .gt. maxtask)
31*59599516SKenneth E. Jansen     &  call error('ctypes  ','numtask ',numtask)
32*59599516SKenneth E. Jansen
33*59599516SKenneth E. Jansen      nshg0 = nshg
34*59599516SKenneth E. Jansen
35*59599516SKenneth E. Jansen      do itask = 1,numtask
36*59599516SKenneth E. Jansenc
37*59599516SKenneth E. Jansenc.... iacc = 0 ==> this task is a send
38*59599516SKenneth E. Jansenc          = 1 ==> this task is a recieve
39*59599516SKenneth E. Jansenc
40*59599516SKenneth E. Jansen        iacc   = ilwork (itkbeg + 2)
41*59599516SKenneth E. Jansenc
42*59599516SKenneth E. Jansenc.... numseg : number of data segments to be communicated
43*59599516SKenneth E. Jansenc
44*59599516SKenneth E. Jansen        numseg = ilwork (itkbeg + 4)
45*59599516SKenneth E. Jansenc
46*59599516SKenneth E. Jansenc.... adjust the number of the other processor, since processors
47*59599516SKenneth E. Jansenc     are numbered here starting from 0, not 1.
48*59599516SKenneth E. Jansenc
49*59599516SKenneth E. Jansen        ilwork (itkbeg + 3) = ilwork (itkbeg + 3) - 1
50*59599516SKenneth E. Jansen        if (numseg .gt. maxseg)
51*59599516SKenneth E. Jansen     &    call error('ctypes  ','numseg  ',numseg )
52*59599516SKenneth E. Jansenc
53*59599516SKenneth E. Jansenc.... lfront = total number of nodes involved in this task
54*59599516SKenneth E. Jansenc
55*59599516SKenneth E. Jansen        lfront = 0
56*59599516SKenneth E. Jansen        do is = 1,numseg
57*59599516SKenneth E. Jansenc
58*59599516SKenneth E. Jansenc.... isbegin(is): starting node number for each segment
59*59599516SKenneth E. Jansenc
60*59599516SKenneth E. Jansen          isbegin (is) = ilwork (itkbeg + 3 + 2*is)
61*59599516SKenneth E. Jansenc
62*59599516SKenneth E. Jansenc.... lenseg(is): length of each segment (number of nodes)
63*59599516SKenneth E. Jansenc
64*59599516SKenneth E. Jansen          lenseg  (is) = ilwork (itkbeg + 4 + 2*is)
65*59599516SKenneth E. Jansenc
66*59599516SKenneth E. Jansenc.... increment the total node counter
67*59599516SKenneth E. Jansenc
68*59599516SKenneth E. Jansen          lfront       = lfront + lenseg(is)
69*59599516SKenneth E. Jansenc
70*59599516SKenneth E. Jansenc.... nshg0: number of nodes to be assembled on this processor,
71*59599516SKenneth E. Jansenc             i.e. subtract the number of nodes which will be
72*59599516SKenneth E. Jansenc             sent to another processor.
73*59599516SKenneth E. Jansenc
74*59599516SKenneth E. Jansen          if (iacc .eq. 0) nshg0 = nshg0 - lenseg(is)
75*59599516SKenneth E. Jansen        enddo
76*59599516SKenneth E. Jansenc
77*59599516SKenneth E. Jansenc.... maxfront: number of nodes which will be communicated, including
78*59599516SKenneth E. Jansenc               all segments. Note that after the loop over tasks
79*59599516SKenneth E. Jansenc               is complete, maxfront will contain the maximum number
80*59599516SKenneth E. Jansenc               of nodes for any of the tasks.
81*59599516SKenneth E. Jansenc
82*59599516SKenneth E. Jansen        maxfront = MAX(maxfront,lfront)
83*59599516SKenneth E. Jansenc
84*59599516SKenneth E. Jansenc.... ioffset: array offset from the first node in the first segment
85*59599516SKenneth E. Jansenc
86*59599516SKenneth E. Jansen        ioffset(1:numseg) = isbegin(1:numseg) - isbegin(1)
87*59599516SKenneth E. Jansenc
88*59599516SKenneth E. Jansenc.... now set up the MPI data types which will be used in commu.f.
89*59599516SKenneth E. Jansenc     These data types represent the indexed sets that will be sent
90*59599516SKenneth E. Jansenc     and recieved.
91*59599516SKenneth E. Jansenc
92*59599516SKenneth E. Jansenc
93*59599516SKenneth E. Jansenc.... the following call to MPI_TYPE_INDEXED will create a new data
94*59599516SKenneth E. Jansenc     type which will represent the blocks of data we wish to transfer
95*59599516SKenneth E. Jansenc     for this task. A handle to the new type is returned
96*59599516SKenneth E. Jansenc     (sevsegtype(itask,1)). This data type describes the blocks of
97*59599516SKenneth E. Jansenc     data to be transferred in terms of segments.
98*59599516SKenneth E. Jansenc     Input to this routine:
99*59599516SKenneth E. Jansenc          numseg: number of segments in this task
100*59599516SKenneth E. Jansenc          lenseg: length of each segment (number of nodes)
101*59599516SKenneth E. Jansenc          ioffset: where to begin each block with respect to the
102*59599516SKenneth E. Jansenc                   first segment
103*59599516SKenneth E. Jansenc          MPI_DOUBLE_PRECISION: type to set for each of the blocks
104*59599516SKenneth E. Jansenc
105*59599516SKenneth E. Jansen        call MPI_TYPE_INDEXED (numseg, lenseg, ioffset,
106*59599516SKenneth E. Jansen     &                  MPI_DOUBLE_PRECISION, sevsegtype(itask,1), ierr)
107*59599516SKenneth E. Jansenc
108*59599516SKenneth E. Jansenc.... now create a new data type for each of the types of arrays we
109*59599516SKenneth E. Jansenc     may wish to communicate with. For example ndof will be used when
110*59599516SKenneth E. Jansenc     communicating the residual vector. Each one of these is derived
111*59599516SKenneth E. Jansenc     from the first data type defined above, sevsegtype(itask,1).
112*59599516SKenneth E. Jansenc
113*59599516SKenneth E. Jansen        call MPI_TYPE_HVECTOR(nsd,    1, lstride, sevsegtype(itask,1),
114*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,2), ierr)
115*59599516SKenneth E. Jansenc
116*59599516SKenneth E. Jansen        call MPI_TYPE_HVECTOR(ndof,   1, lstride, sevsegtype(itask,1),
117*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,3), ierr)
118*59599516SKenneth E. Jansenc
119*59599516SKenneth E. Jansen        call MPI_TYPE_HVECTOR(nflow*nflow,1, lstride,
120*59599516SKenneth E. Jansen     &                    sevsegtype(itask,1),sevsegtype(itask,4), ierr)
121*59599516SKenneth E. Jansen        call MPI_TYPE_HVECTOR((nflow-1)*nsd,1,lstride,
122*59599516SKenneth E. Jansen     &                    sevsegtype(itask,1),sevsegtype(itask,5), ierr)
123*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(nflow,1,lstride,sevsegtype(itask,1),
124*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,6), ierr)
125*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(24,1,lstride,sevsegtype(itask,1),
126*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,7), ierr)
127*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(9,1,lstride,sevsegtype(itask,1),
128*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,8), ierr)
129*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(11,1,lstride,sevsegtype(itask,1),
130*59599516SKenneth E. Jansen     &                                        sevsegtype(itask,9), ierr)
131*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(7,1,lstride,sevsegtype(itask,1),
132*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,10), ierr)
133*59599516SKenneth E. Jansen!       call MPI_TYPE_HVECTOR(33,1,lstride,sevsegtype(itask,1),
134*59599516SKenneth E. Jansen!     &                                   sevsegtype(itask,11), ierr)
135*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(13,1,lstride,sevsegtype(itask,1),
136*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,11), ierr)
137*59599516SKenneth E. Jansen!       call MPI_TYPE_HVECTOR(22,1,lstride,sevsegtype(itask,1),
138*59599516SKenneth E. Jansen!     &                                   sevsegtype(itask,12), ierr)
139*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(17,1,lstride,sevsegtype(itask,1),
140*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,12), ierr)
141*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(16,1,lstride,sevsegtype(itask,1),
142*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,13), ierr)
143*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(10,1,lstride,sevsegtype(itask,1),
144*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,14), ierr)
145*59599516SKenneth E. Jansen       call MPI_TYPE_HVECTOR(nflow*nsd,1,lstride,sevsegtype(itask,1),
146*59599516SKenneth E. Jansen     &                                   sevsegtype(itask,15), ierr)
147*59599516SKenneth E. Jansenc
148*59599516SKenneth E. Jansenc
149*59599516SKenneth E. Jansenc.... now this must be done to make MPI recognize each of the data
150*59599516SKenneth E. Jansenc     types that were just defined
151*59599516SKenneth E. Jansenc
152*59599516SKenneth E. Jansen        do kdof = 1,15
153*59599516SKenneth E. Jansen          call MPI_TYPE_COMMIT (sevsegtype(itask,kdof), ierr)
154*59599516SKenneth E. Jansen        enddo
155*59599516SKenneth E. Jansenc
156*59599516SKenneth E. Jansenc.... set the counter to the index in ilwork where the next task
157*59599516SKenneth E. Jansenc     begins
158*59599516SKenneth E. Jansenc
159*59599516SKenneth E. Jansen
160*59599516SKenneth E. Jansen        itkbeg = itkbeg + 4 + 2*numseg
161*59599516SKenneth E. Jansenc
162*59599516SKenneth E. Jansenc.... end loop over tasks
163*59599516SKenneth E. Jansenc
164*59599516SKenneth E. Jansen      enddo
165*59599516SKenneth E. Jansen
166*59599516SKenneth E. Jansen!      timer2 = TMRC()
167*59599516SKenneth E. Jansen!      time_ellapsed = timer2 - timer1
168*59599516SKenneth E. Jansen      !write(*,*) 'myrank: ', myrank, '- time in ctype: ',time_ellapsed
169*59599516SKenneth E. Jansenc      call rgetMinMaxAvg(time_ellapsed,rStats,istatRanks)
170*59599516SKenneth E. Jansen!      if(myrank == 0) then
171*59599516SKenneth E. Jansen!         write(*,811) istatRanks(1),rStats(1),istatRanks(2),rStats(2),
172*59599516SKenneth E. Jansen!     &             rStats(3),rStats(4)
173*59599516SKenneth E. Jansen!      endif
174*59599516SKenneth E. Jansen
175*59599516SKenneth E. Jansen811   format('Time in ctype: ',
176*59599516SKenneth E. Jansen     &                'min [',I6,',',F10.5,'], ',
177*59599516SKenneth E. Jansen     &                'max [',I6,',',F10.5,'], ',
178*59599516SKenneth E. Jansen     &                'and avg [.,',F10.5,'], (rms=',F10.5,')')
179*59599516SKenneth E. Jansen
180*59599516SKenneth E. Jansen
181*59599516SKenneth E. Jansen      return
182*59599516SKenneth E. Jansen      end
183