159599516SKenneth E. Jansen subroutine ctypes (ilwork) 259599516SKenneth E. Jansen 359599516SKenneth E. Jansen parameter (maxseg = 30000) 459599516SKenneth E. Jansen 559599516SKenneth E. Jansen include "common.h" 659599516SKenneth E. Jansen include "mpif.h" 759599516SKenneth E. Jansen include "auxmpi.h" 859599516SKenneth E. Jansen 9*513954efSKenneth E. Jansen integer sizeofdouble,sizeofInt64 1059599516SKenneth E. Jansen 1159599516SKenneth E. Jansen dimension ilwork(nlwork) 1259599516SKenneth E. Jansen dimension isbegin(maxseg), lenseg(maxseg), ioffset(maxseg) 1359599516SKenneth E. Jansen 1459599516SKenneth E. Jansen CALL MPI_TYPE_EXTENT (MPI_DOUBLE_PRECISION,sizeofdouble,ierr) 1559599516SKenneth E. Jansen lstride = nshg * sizeofdouble 1659599516SKenneth E. Jansenc 17*513954efSKenneth E. Jansenc you would need the next two lines if you commu-ed vectors of integers 18*513954efSKenneth E. Jansenc 19*513954efSKenneth E. Jansenc CALL MPI_TYPE_EXTENT (MPI_LONG_LONG,sizeofInt64,ierr) 20*513954efSKenneth E. Jansenc lstrideInt = nshg * sizeofInt64 21*513954efSKenneth E. Jansenc 2259599516SKenneth E. Jansenc.... maxfront is a common variable being set in this routine 2359599516SKenneth E. Jansenc 2459599516SKenneth E. Jansen maxfront = 0 2559599516SKenneth E. Jansen numtask = ilwork (1) 2659599516SKenneth E. Jansen itkbeg = 1 2759599516SKenneth E. Jansen 2859599516SKenneth E. Jansen if (numtask .gt. maxtask) 2959599516SKenneth E. Jansen & call error('ctypes ','numtask ',numtask) 3059599516SKenneth E. Jansen 3159599516SKenneth E. Jansen nshg0 = nshg 3259599516SKenneth E. Jansen 3359599516SKenneth E. Jansen do itask = 1,numtask 3459599516SKenneth E. Jansenc 3559599516SKenneth E. Jansenc.... iacc = 0 ==> this task is a send 3659599516SKenneth E. Jansenc = 1 ==> this task is a recieve 3759599516SKenneth E. Jansenc 3859599516SKenneth E. Jansen iacc = ilwork (itkbeg + 2) 3959599516SKenneth E. Jansenc 4059599516SKenneth E. Jansenc.... numseg : number of data segments to be communicated 4159599516SKenneth E. Jansenc 4259599516SKenneth E. Jansen numseg = ilwork (itkbeg + 4) 4359599516SKenneth E. Jansenc 4459599516SKenneth E. Jansenc.... adjust the number of the other processor, since processors 4559599516SKenneth E. Jansenc are numbered here starting from 0, not 1. 4659599516SKenneth E. Jansenc 4759599516SKenneth E. Jansen ilwork (itkbeg + 3) = ilwork (itkbeg + 3) - 1 4859599516SKenneth E. Jansen if (numseg .gt. maxseg) 4959599516SKenneth E. Jansen & call error('ctypes ','numseg ',numseg ) 5059599516SKenneth E. Jansenc 5159599516SKenneth E. Jansenc.... lfront = total number of nodes involved in this task 5259599516SKenneth E. Jansenc 5359599516SKenneth E. Jansen lfront = 0 5459599516SKenneth E. Jansen do is = 1,numseg 5559599516SKenneth E. Jansenc 5659599516SKenneth E. Jansenc.... isbegin(is): starting node number for each segment 5759599516SKenneth E. Jansenc 5859599516SKenneth E. Jansen isbegin (is) = ilwork (itkbeg + 3 + 2*is) 5959599516SKenneth E. Jansenc 6059599516SKenneth E. Jansenc.... lenseg(is): length of each segment (number of nodes) 6159599516SKenneth E. Jansenc 6259599516SKenneth E. Jansen lenseg (is) = ilwork (itkbeg + 4 + 2*is) 6359599516SKenneth E. Jansenc 6459599516SKenneth E. Jansenc.... increment the total node counter 6559599516SKenneth E. Jansenc 6659599516SKenneth E. Jansen lfront = lfront + lenseg(is) 6759599516SKenneth E. Jansenc 6859599516SKenneth E. Jansenc.... nshg0: number of nodes to be assembled on this processor, 6959599516SKenneth E. Jansenc i.e. subtract the number of nodes which will be 7059599516SKenneth E. Jansenc sent to another processor. 7159599516SKenneth E. Jansenc 7259599516SKenneth E. Jansen if (iacc .eq. 0) nshg0 = nshg0 - lenseg(is) 7359599516SKenneth E. Jansen enddo 7459599516SKenneth E. Jansenc 7559599516SKenneth E. Jansenc.... maxfront: number of nodes which will be communicated, including 7659599516SKenneth E. Jansenc all segments. Note that after the loop over tasks 7759599516SKenneth E. Jansenc is complete, maxfront will contain the maximum number 7859599516SKenneth E. Jansenc of nodes for any of the tasks. 7959599516SKenneth E. Jansenc 8059599516SKenneth E. Jansen maxfront = MAX(maxfront,lfront) 8159599516SKenneth E. Jansenc 8259599516SKenneth E. Jansenc.... ioffset: array offset from the first node in the first segment 8359599516SKenneth E. Jansenc 8459599516SKenneth E. Jansen ioffset(1:numseg) = isbegin(1:numseg) - isbegin(1) 8559599516SKenneth E. Jansenc 8659599516SKenneth E. Jansenc.... now set up the MPI data types which will be used in commu.f. 8759599516SKenneth E. Jansenc These data types represent the indexed sets that will be sent 8859599516SKenneth E. Jansenc and recieved. 8959599516SKenneth E. Jansenc 9059599516SKenneth E. Jansenc 9159599516SKenneth E. Jansenc.... the following call to MPI_TYPE_INDEXED will create a new data 9259599516SKenneth E. Jansenc type which will represent the blocks of data we wish to transfer 9359599516SKenneth E. Jansenc for this task. A handle to the new type is returned 9459599516SKenneth E. Jansenc (sevsegtype(itask,1)). This data type describes the blocks of 9559599516SKenneth E. Jansenc data to be transferred in terms of segments. 9659599516SKenneth E. Jansenc Input to this routine: 9759599516SKenneth E. Jansenc numseg: number of segments in this task 9859599516SKenneth E. Jansenc lenseg: length of each segment (number of nodes) 9959599516SKenneth E. Jansenc ioffset: where to begin each block with respect to the 10059599516SKenneth E. Jansenc first segment 10159599516SKenneth E. Jansenc MPI_DOUBLE_PRECISION: type to set for each of the blocks 10259599516SKenneth E. Jansenc 10359599516SKenneth E. Jansen call MPI_TYPE_INDEXED (numseg, lenseg, ioffset, 104*513954efSKenneth E. Jansen & MPI_LONG_LONG_INT, sevsegtype(itask,16), ierr) 105*513954efSKenneth E. Jansen 106*513954efSKenneth E. Jansen call MPI_TYPE_INDEXED (numseg, lenseg, ioffset, 10759599516SKenneth E. Jansen & MPI_DOUBLE_PRECISION, sevsegtype(itask,1), ierr) 10859599516SKenneth E. Jansenc 10959599516SKenneth E. Jansenc.... now create a new data type for each of the types of arrays we 11059599516SKenneth E. Jansenc may wish to communicate with. For example ndof will be used when 11159599516SKenneth E. Jansenc communicating the residual vector. Each one of these is derived 11259599516SKenneth E. Jansenc from the first data type defined above, sevsegtype(itask,1). 11359599516SKenneth E. Jansenc 11459599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(nsd, 1, lstride, sevsegtype(itask,1), 11559599516SKenneth E. Jansen & sevsegtype(itask,2), ierr) 11659599516SKenneth E. Jansenc 11759599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(ndof, 1, lstride, sevsegtype(itask,1), 11859599516SKenneth E. Jansen & sevsegtype(itask,3), ierr) 11959599516SKenneth E. Jansenc 12059599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(nflow*nflow,1, lstride, 12159599516SKenneth E. Jansen & sevsegtype(itask,1),sevsegtype(itask,4), ierr) 12259599516SKenneth E. Jansen call MPI_TYPE_HVECTOR((nflow-1)*nsd,1,lstride, 12359599516SKenneth E. Jansen & sevsegtype(itask,1),sevsegtype(itask,5), ierr) 12459599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(nflow,1,lstride,sevsegtype(itask,1), 12559599516SKenneth E. Jansen & sevsegtype(itask,6), ierr) 12659599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(24,1,lstride,sevsegtype(itask,1), 12759599516SKenneth E. Jansen & sevsegtype(itask,7), ierr) 12859599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(9,1,lstride,sevsegtype(itask,1), 12959599516SKenneth E. Jansen & sevsegtype(itask,8), ierr) 13059599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(11,1,lstride,sevsegtype(itask,1), 13159599516SKenneth E. Jansen & sevsegtype(itask,9), ierr) 13259599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(7,1,lstride,sevsegtype(itask,1), 13359599516SKenneth E. Jansen & sevsegtype(itask,10), ierr) 13459599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(33,1,lstride,sevsegtype(itask,1), 13559599516SKenneth E. Jansen & sevsegtype(itask,11), ierr) 13659599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(22,1,lstride,sevsegtype(itask,1), 13759599516SKenneth E. Jansen & sevsegtype(itask,12), ierr) 13859599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(16,1,lstride,sevsegtype(itask,1), 13959599516SKenneth E. Jansen & sevsegtype(itask,13), ierr) 14059599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(10,1,lstride,sevsegtype(itask,1), 14159599516SKenneth E. Jansen & sevsegtype(itask,14), ierr) 14259599516SKenneth E. Jansen call MPI_TYPE_HVECTOR(nflow*nsd,1,lstride,sevsegtype(itask,1), 14359599516SKenneth E. Jansen & sevsegtype(itask,15), ierr) 14459599516SKenneth E. Jansenc 14559599516SKenneth E. Jansenc 14659599516SKenneth E. Jansenc.... now this must be done to make MPI recognize each of the data 14759599516SKenneth E. Jansenc types that were just defined 14859599516SKenneth E. Jansenc 149*513954efSKenneth E. Jansen do kdof = 1,16 15059599516SKenneth E. Jansen call MPI_TYPE_COMMIT (sevsegtype(itask,kdof), ierr) 15159599516SKenneth E. Jansen enddo 15259599516SKenneth E. Jansenc 15359599516SKenneth E. Jansenc.... set the counter to the index in ilwork where the next task 15459599516SKenneth E. Jansenc begins 15559599516SKenneth E. Jansenc 15659599516SKenneth E. Jansen 15759599516SKenneth E. Jansen itkbeg = itkbeg + 4 + 2*numseg 15859599516SKenneth E. Jansenc 15959599516SKenneth E. Jansenc.... end loop over tasks 16059599516SKenneth E. Jansenc 16159599516SKenneth E. Jansen enddo 16259599516SKenneth E. Jansen 16359599516SKenneth E. Jansen return 16459599516SKenneth E. Jansen end 165fcc77cc2SCameron Smith 166fcc77cc2SCameron Smith subroutine Dctypes(numtask) ! { 167fcc77cc2SCameron Smith include "auxmpi.h" 168fcc77cc2SCameron Smith integer numtask 169fcc77cc2SCameron Smith do itask = 1,numtask 170*513954efSKenneth E. Jansen do kdof = 1,16 171fcc77cc2SCameron Smith call MPI_TYPE_FREE(sevsegtype(itask,kdof), ierr) 172fcc77cc2SCameron Smith enddo 173fcc77cc2SCameron Smith enddo 174fcc77cc2SCameron Smith end !} 175