Skip to content
Snippets Groups Projects
Commit a2891cfc authored by Anthony's avatar Anthony
Browse files

Implementation of a more balanced partition

parent ad5e0ade
No related branches found
No related tags found
No related merge requests found
...@@ -6,41 +6,65 @@ log_master, log_world = getargs.getLogger(__name__) ...@@ -6,41 +6,65 @@ log_master, log_world = getargs.getLogger(__name__)
INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error INFO, DEBUG, ERROR = log_master.info, log_master.debug, log_world.error
INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug INFO_ALL, DEBUG_ALL = log_world.info, log_world.debug
# #
def halfpartition(partin) : def halfpartition(partin, land) :
partout=[] """
if partin[0]["nbi"] > partin[0]["nbj"] : First partition of the domain
for dom in partin : The domain with more land points is halved
h=int(np.trunc(dom["nbi"]/2)) """
partout.append({"nbi":h, "nbj":dom["nbj"],"istart":dom["istart"], "jstart":dom["jstart"]}) A = [p["nbland"] for p in partin]
partout.append({"nbi":dom["nbi"]-h,"nbj":dom["nbj"],"istart":dom["istart"]+h,"jstart":dom["jstart"]}) i = np.argmax(A)
partout = []
partout = [partin[k] for k in range(len(partin)) if k != i]
dom = partin[i]
if dom["nbi"] > dom["nbj"] :
hh = [h for h in range(dom["nbi"])]
nb = np.array([np.ma.sum(np.ma.filled(land[dom["jstart"]:dom["jstart"]+dom["nbj"],dom["istart"]:dom["istart"]+h],0)) - dom['nbland']/2. for h in hh])
i = np.nanargmin(np.abs(nb))
new_dom = {"nbi":dom["nbi"]-hh[i],"nbj":dom["nbj"], \
"istart":dom["istart"]+hh[i],"jstart":dom["jstart"]}
dom["nbi"] = hh[i]
else : else :
for dom in partin : hh = [h for h in range(dom["nbj"])]
h=int(np.trunc(dom["nbj"]/2)) nb = np.array([np.ma.sum(np.ma.filled(land[dom["jstart"]:dom["jstart"]+h,dom["istart"]:dom["istart"]+dom["nbi"]],0)) - int(dom['nbland']/2.) for h in hh])
partout.append({"nbi":dom["nbi"],"nbj":h, "istart":dom["istart"],"jstart":dom["jstart"]}) i = np.nanargmin(np.abs(nb))
partout.append({"nbi":dom["nbi"],"nbj":dom["nbj"]-h,"istart":dom["istart"],"jstart":dom["jstart"]+h}) new_dom = {"nbi":dom["nbi"],"nbj":dom["nbj"]-hh[i], \
"istart":dom["istart"],"jstart":dom["jstart"]+hh[i]}
dom["nbj"] = hh[i]
new_dom['nbland'] = int(np.nansum(land[new_dom["jstart"]:new_dom["jstart"]+new_dom["nbj"],new_dom["istart"]:new_dom["istart"]+new_dom["nbi"]]))
dom['nbland'] = dom['nbland']-new_dom['nbland']
partout.append(dom)
partout.append(new_dom)
return partout return partout
# #
# Add number of land points to partitions
#
def addnbland(partin, land) :
for dom in partin :
dom['nbland']=int(np.sum(land[dom["jstart"]:dom["jstart"]+dom["nbj"],dom["istart"]:dom["istart"]+dom["nbi"]]))
#
# Divide in two the domain with the most number of land points # Divide in two the domain with the most number of land points
# #
def halflargest(part) : def fit_partition(partin, land):
nbland=np.array([dom['nbland'] for dom in part]) partout = []
imax = np.argmax(nbland) for i, dom in enumerate(partin):
if part[imax]["nbi"] > part[imax]["nbj"] : l = land[dom["jstart"]:dom["jstart"]+dom["nbj"],dom["istart"]:dom["istart"]+dom["nbi"]]
h=int(np.trunc(part[imax]["nbi"]/2)) l1 = np.sum(l, axis = 0)
part.append({"nbi":part[imax]["nbi"]-h,"nbj":part[imax]["nbj"],"istart":part[imax]["istart"]+h,"jstart":part[imax]["jstart"]})
part[imax]["nbi"]=h i0 = np.where(l1>0)[0][0]
else : i1 = np.where(l1>0)[0][-1]
h=int(np.trunc(part[imax]["nbj"]/2))
part.append({"nbi":part[imax]["nbi"],"nbj":part[imax]["nbj"]-h,"istart":part[imax]["istart"],"jstart":part[imax]["jstart"]+h})
part[imax]["nbj"]=h
return l2 = np.ma.sum(l, axis = 1)
j0 = np.where(l2>0)[0][0]
j1 = np.where(l2>0)[0][-1]
dom["jstart"] = j0 + dom["jstart"]
dom["nbj"] = j1-j0+1
dom["istart"] = i0 + dom["istart"]
dom["nbi"] = i1-i0+1
dom["nbland"] = int(np.nansum(land[dom["jstart"]:dom["jstart"]+dom["nbj"],dom["istart"]:dom["istart"]+dom["nbi"]]))
partout.append(dom)
return partout
# #
# #
# #
...@@ -56,30 +80,37 @@ def adjustpart(partin, land, nbcore) : ...@@ -56,30 +80,37 @@ def adjustpart(partin, land, nbcore) :
# #
# Divide domains with the largest number of land points # Divide domains with the largest number of land points
# #
nbptproc=np.array([dom['nbi']*dom['nbj'] for dom in partin])
freecores = nbcore-len(partin) freecores = nbcore-len(partin)
while nbcore-len(partin) > 0 :
halflargest(partin) while nbcore-len(partin) > 0:
addnbland(partin, land) partin = halfpartition(partin, land)
partin = fit_partition(partin, land)
nbptproc=np.array([dom['nbi']*dom['nbj'] for dom in partin]) nbptproc=np.array([dom['nbi']*dom['nbj'] for dom in partin])
nbland = [dom["nbland"] for dom in partin]
if np.min(nbptproc) < 3 : if np.min(nbptproc) < 3 :
ERROR("The smallest domain in the partition is of a size less than 5. This will probably not work.") ERROR("The smallest domain in the partition is of a size less than 5. This will probably not work.")
sys.exit() sys.exit()
return
return partin
# #
# Partition domain in two steps : 1) halving, 2) adjusting by nb land points # Partition domain in two steps : 1) halving, 2) adjusting by nb land points
# #
def partitiondom(land, nbcore, rank) : def partitiondom(land, nbcore, rank) :
njg,nig = land.shape njg,nig = land.shape
partout=[{"nbi":nig,"nbj":njg,"istart":0,"jstart":0, "nbland":int(np.sum(land))}] partout=[{"nbi":nig,"nbj":njg,"istart":0,"jstart":0, "nbland":int(np.sum(land))}]
while len(partout) <= nbcore/2 : while len(partout) < nbcore :
partout = halfpartition(partout) partout = halfpartition(partout, land)
addnbland(partout, land)
# #
adjustpart(partout, land, nbcore) partout = adjustpart(partout, land, nbcore)
# #
gindland=np.zeros((njg,nig), dtype=np.int32) gindland=np.zeros((njg,nig), dtype=np.int32)
gindland[:,:]=-1 gindland[:,:]=-1
test = np.zeros((njg,nig), dtype=np.int32)
test[:,:] = land[:,:]
n=0 n=0
for i in range(nig) : for i in range(nig) :
for j in range(njg) : for j in range(njg) :
...@@ -95,10 +126,17 @@ def partitiondom(land, nbcore, rank) : ...@@ -95,10 +126,17 @@ def partitiondom(land, nbcore, rank) :
locgind=np.copy(gindland[jstart:jstart+nbj,istart:istart+nbi]) locgind=np.copy(gindland[jstart:jstart+nbj,istart:istart+nbi])
loccore=np.copy(gindland[jstart:jstart+nbj,istart:istart+nbi]) loccore=np.copy(gindland[jstart:jstart+nbj,istart:istart+nbi])
loccore[loccore >= 0] = ic loccore[loccore >= 0] = ic
test[jstart:jstart+nbj,istart:istart+nbi] = test[jstart:jstart+nbj,istart:istart+nbi] - land[jstart:jstart+nbj,istart:istart+nbi]
partout[ic]["glandindex"] = locgind partout[ic]["glandindex"] = locgind
partout[ic]["corenb"] = loccore partout[ic]["corenb"] = loccore
partout[ic]["nblocland"] = np.count_nonzero(locgind >= 0) partout[ic]["nblocland"] = np.count_nonzero(locgind >= 0)
# #
nbland = [part["nbland"] for part in partout]
if rank == 0:
INFO("Distribution of the domain : {}".format(nbland))
INFO("Test number of error on domain distribution: {0}".format(len(np.where(test == 1)[0])))
INFO("Test domain partition (only value must be 0): {0}".format(np.unique(test)))
#
return partout return partout
# #
# Build global map of processors # Build global map of processors
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment