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