2025-09-05 09:42:21 +02:00

221 lines
7.6 KiB
Python
Executable File

"""
script to sort and select processor layout from MPP_PREP output
wrote by P. Mathiot 10/2018
"""
# import module
from __future__ import print_function
import argparse
import sys
# define class layout
class layout(object):
"""
Class containing all the information about a specific model layout
Output:
self.jpnij = (i domain along i dimension, j domain along j dimension, total number of domain (land+ocean))
self.nproc = (total number of domain (land+ocean), n ocean domain, nland domain)
self.jpij = (dimension along i, dimension along j) of a domain
self.ratio = (total computed point, overhead, ratio computed point / global)
"""
def __init__(self, txtlst):
"""
Initialisation of a layout class object:
Input: list of string containing 1 layout description
extracted from the processor layout file
"""
self.jpnij = extract_jpnij(txtlst) # (jpni, jpnj, jpnij)
self.nproc = extract_nproc(txtlst) # (ntot, noce, nland)
self.jpij = extract_jpij(txtlst) # (jpi , jpj)
self.ratio = extract_point(txtlst) # (total computed point, overhead, ratio computed point / global)
def test_criterion(self, rmax, nocemin, nocemax):
"""
function to decide if yes or no a specific layout has to be selected
Input:
float rmax: maximal ratio (computed/global) accepted
int nocemin and nocemax: range of number of ocean processor accepted
output: logical
"""
if ( nocemin <= self.nproc[1] <= nocemax ) and ( self.ratio[2] <= rmax ):
return True
else:
return False
def print_layout(self, cidx):
"""
function to print specific information about a specific layout
"""
print( 'Domain decomposition {}'.format(cidx) )
print( 'domain decomposition (jpni, jpnj) = {}'.format((self.jpnij[0], self.jpnij[1])) )
print( 'number of ocean domain = {}'.format(self.nproc[1]) )
print( 'ratio computed/global = {}'.format(self.ratio[2]) )
print( 'domain size (jpi, jpj) = {}'.format(self.jpij) )
print('')
# define sorting function
def noce_proc(elem):
"""
function used as key to sort list of layout
by number of ocean domain in the list sorting algorithm
"""
return elem.nproc[1]
def ratio_proc(elem):
"""
function used as key to sort list of layout
by ratio (computed/global) in the list sorting algorithm
"""
return elem.ratio[2]
def jpij_proc(elem):
"""
function used as key to sort list of layout
by domain size in the list sorting algorithm
"""
return elem.jpij[0]*elem.jpij[1]
# txt extraction function to feed class layout
def extract_jpnij(txtlst):
"""
function to extract total number of domain
for a specific domain layout txt output
Input: list of string containing 1 layout description
extracted from the processor layout file
Output: tuple (jpni, jpnj, jpni*jpnj)
"""
jpnij = int(txtlst[1].split()[-1])
ctmp = txtlst[3].split()
jpni = int(ctmp[1])
jpnj = int(ctmp[3])
return (jpni, jpnj, jpnij)
def extract_nproc(txtlst):
"""
function to extract total number of ocean domain
for a specific domain layout txt output
Input: list of string containing 1 layout description
extracted from the processor layout file
Output: tuple (jpni*jpnj, n oce domain, n land domain)
"""
ntot = int(txtlst[1].split()[-1])
noce = int(txtlst[5].split()[-1])
nland = int(txtlst[6].split()[-1])
return (ntot, noce, nland)
def extract_jpij(txtlst):
"""
function to extract domain dimension
for a specific domain layout txt output
Input: list of string containing 1 layout description
extracted from the processor layout file
Output: tuple (jpi, jpj)
"""
ctmp = txtlst[4].split()
jpi = int(ctmp[1])
jpj = int(ctmp[3])
return (jpi, jpj)
def extract_point(txtlst):
"""
function to extract ration (computed/global)
for a specific domain layout txt output
Input: list of string containing 1 layout description
extracted from the processor layout file
Output: tuple (total number of point, overhead, ratio (computed/global))
"""
npoint = int(txtlst[13].split()[-1])
noverh = int(txtlst[14].split()[-1])
ratio = float(txtlst[15].split()[-1])
return (npoint, noverh, ratio)
# main
def main():
"""
script to sort and select processor layout from MPP_PREP output based on user constrains
"""
parser = argparse.ArgumentParser()
parser.add_argument("-f", metavar='layout_file' , help="names of domain layout file to sort", type=str, nargs=1, required=True)
parser.add_argument("--rmax", metavar='max_ratio' , help="max ratio allowed (computed/global)", type=float, nargs=1, required=True)
parser.add_argument("--noce", metavar='min/max_noce' , help="min and max number of ocean domain allowed", type=int, nargs=2, required=True)
args = parser.parse_args()
# read file
filein = args.f[0]
fid = open(filein,"r") #opens file with name of "test.txt"
txtdata = []
for cline in fid:
txtdata.extend([cline])
# skip header and tail of file
txtdata = txtdata[4:-20]
# loop on different domain decomposition
ilinepl = 17 # number of line of a specific decomposition
ilayout = 0
lst_layout = []
ratio_min = 9999.0
noce_min = 9999999
noce_max = 0
for iline in range(0, len(txtdata)):
if iline % ilinepl == 0:
# initialise layout
conf_layout = layout( txtdata[iline:iline+ilinepl] )
ratio_min = min( conf_layout.ratio[2], ratio_min )
noce_min = min( conf_layout.nproc[1], noce_min )
noce_max = max( conf_layout.nproc[1], noce_max )
# select layout based on condition
if conf_layout.test_criterion(args.rmax[0], args.noce[0], args.noce[1]):
ilayout = ilayout + 1
lst_layout.extend([conf_layout])
if lst_layout == []:
print('')
print( 'E R R O R: constrains are too strong, no domain are found' )
print('')
if ratio_min > args.rmax[0] :
print( 'min ratio is {} and you ask for a ratio smaller than {}'.format(ratio_min, args.rmax[0]) )
if noce_min > args.noce[1] :
print( 'min ocean proc is {} and you ask for a number of ocean proc lower than {}'.format(noce_min, args.noce[1]) )
if noce_max < args.noce[0] :
print( 'max ocean proc is {} and you ask for a number of ocean proc larger than {}'.format(noce_max, args.noce[0]) )
print('')
sys.exit()
lst_layout.sort(key=noce_proc)
for idx, ilayout in enumerate(lst_layout):
ilayout.print_layout(str(idx))
print( '=====================================================================' )
print('')
print( 'Among the layouts fitting the constraint on : ratio (computed/global) < {} and {} <= number of ocean domain <= {}' \
.format(args.rmax[0], args.noce[0], args.noce[1]) )
print('')
print( ' 3 layouts are highlighted : ' )
print('')
lst_layout.sort(key=ratio_proc)
lst_layout[0].print_layout('SMALLEST RATIO')
#
lst_layout.sort(key=noce_proc)
lst_layout[-1].print_layout('LARGEST NUMBER OF OCEAN DOMAINS')
#
lst_layout.sort(key=jpij_proc)
lst_layout[0].print_layout('SMALLEST COMPUTED DOMAIN')
if __name__ == "__main__":
main()