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