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
|
C Copyright (c) 2003-2010 University of Florida
C
C This program is free software; you can redistribute it and/or modify
C it under the terms of the GNU General Public License as published by
C the Free Software Foundation; either version 2 of the License, or
C (at your option) any later version.
C This program is distributed in the hope that it will be useful,
C but WITHOUT ANY WARRANTY; without even the implied warranty of
C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
C GNU General Public License for more details.
C The GNU General Public License is included in this distribution
C in the file COPYRIGHT.
c This routine returns the number of elements and the offset of the first
c element that a numbered process would control in a parallel environment.
c The main purpose of this routine is to localize the load-balancing algorithm.
c INPUT
c int iNode : the node ID (from 0) whose statistics are to be measured
c int nNodes : the total number of nodes in the workspace
c int iRoot : the node ID of the virtual root (who gets extra elements)
c int nTotal : the total number of elements to divvy up
c OUTPUT
c int iOff : the offset of the first element in the batch
c int nEls : the number of elements in the batch
subroutine paces_batch_stat(iNode,nNodes,iRoot,nTotal,iOff,nEls)
implicit none
c ARGUMENTS
integer iNode, nNodes, iRoot, nTotal, iOff, nEls
c INTERNAL VARIABLES
integer iFloor, iLeft
integer iNode2
integer iTmp
c ----------------------------------------------------------------------
#ifdef _ASSERT
iTmp = 0
c o assert 0 <= (iNode|iRoot) < nNodes
if ((nNodes.le.iNode).or.(iNode.lt.0).or.
& (nNodes.le.iRoot).or.(iRoot.lt.0) ) then
print *, '@PACES_BATCH_STAT: Assertion failed.'
print *, ' nNodes = ',nNodes
print *, ' iNode = ',iNode
print *, ' iRoot = ',iRoot
iTmp = 1
end if
if (iTmp.ne.0) call aces_exit(iTmp)
#endif
c ----------------------------------------------------------------------
if (nTotal.lt.0) then
print *, '@PACES_BATCH_STAT: The total number of elements ',
& 'must be >= 0.'
print *, ' nTotal = ',nTotal
call aces_exit(1)
end if
iFloor = nTotal/nNodes
iLeft = mod(nTotal,nNodes)
c o the sexy version
c iNode2 = mod(iNode+nNodes-iRoot,nNodes)
c iOff = iFloor*iNode2 + min(iNode2,iLeft)
c nEls = iFloor + min(1,(iLeft/(1+iNode2)))
c o the naive version is a lot faster w/o the mod and integer divide
iNode2 = iNode-iRoot
if (iNode.lt.iRoot) iNode2 = iNode2+nNodes
nEls = iFloor
iOff = iFloor*iNode2 + iLeft
if (iNode2.lt.iLeft) then
nEls = iFloor+1
iOff = nEls*iNode2
end if
return
c end subroutine paces_batch_stat
end
|