New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
find_layout.py in utils/tools/MPP_PREP – NEMO

source: utils/tools/MPP_PREP/find_layout.py @ 10335

Last change on this file since 10335 was 10335, checked in by mathiot, 5 years ago

Update of MPP_PREP. Fix #2164

File size: 7.6 KB
Line 
1"""
2 script to sort and select processor layout from MPP_PREP output
3 wrote by P. Mathiot 10/2018
4"""
5
6# import module
7from __future__ import print_function
8import argparse
9import sys
10
11# define class layout
12class layout(object):
13    """
14    Class containing all the information about a specific model layout
15   
16    Output:
17    self.jpnij = (i domain along i dimension, j domain along j dimension, total number of domain (land+ocean))
18    self.nproc = (total number of domain (land+ocean), n ocean domain, nland domain)
19    self.jpij  = (dimension along i, dimension along j) of a domain
20    self.ratio = (total computed point, overhead, ratio computed point / global)
21    """
22    def __init__(self, txtlst):
23        """
24        Initialisation of a layout class object:
25
26        Input: list of string containing 1 layout description
27           extracted from the processor layout file
28        """
29        self.jpnij = extract_jpnij(txtlst)  # (jpni, jpnj, jpnij)
30        self.nproc = extract_nproc(txtlst)  # (ntot, noce, nland)
31        self.jpij = extract_jpij(txtlst)    # (jpi , jpj)
32        self.ratio = extract_point(txtlst)  # (total computed point, overhead, ratio computed point / global)
33
34    def test_criterion(self, rmax, nocemin, nocemax):
35        """
36        function to decide if yes or no a specific layout has to be selected
37        Input:
38        float rmax: maximal ratio (computed/global) accepted
39        int   nocemin and nocemax: range of number of ocean processor accepted
40
41        output: logical
42        """
43        if ( nocemin <= self.nproc[1] <= nocemax ) and ( self.ratio[2] <= rmax ):
44            return True
45        else:
46            return False
47
48    def print_layout(self, cidx):
49        """
50        function to print specific information about a specific layout
51        """
52        print( 'Domain decomposition {}'.format(cidx) )
53        print( 'domain decomposition (jpni, jpnj) = {}'.format((self.jpnij[0], self.jpnij[1])) )
54        print( 'number of ocean domain            = {}'.format(self.nproc[1]) )
55        print( 'ratio computed/global             = {}'.format(self.ratio[2]) )
56        print( 'domain size (jpi, jpj)            = {}'.format(self.jpij) )
57        print('')
58
59# define sorting function
60def noce_proc(elem):
61    """
62    function used as key to sort list of layout
63    by number of ocean domain in the list sorting algorithm
64    """
65    return elem.nproc[1]
66
67def ratio_proc(elem):
68    """
69    function used as key to sort list of layout
70    by ratio (computed/global) in the list sorting algorithm
71    """
72    return elem.ratio[2]
73
74def jpij_proc(elem):
75    """
76    function used as key to sort list of layout
77    by domain size in the list sorting algorithm
78    """
79    return elem.jpij[0]*elem.jpij[1]
80
81# txt extraction function to feed class layout
82def extract_jpnij(txtlst):
83    """
84    function to extract total number of domain
85    for a specific domain layout txt output
86
87    Input: list of string containing 1 layout description
88           extracted from the processor layout file
89   
90    Output: tuple (jpni, jpnj, jpni*jpnj)
91    """
92    jpnij = int(txtlst[1].split()[-1])
93    ctmp = txtlst[3].split()
94    jpni = int(ctmp[1])
95    jpnj = int(ctmp[3])
96    return (jpni, jpnj, jpnij)
97
98def extract_nproc(txtlst):
99    """
100    function to extract total number of ocean domain
101    for a specific domain layout txt output
102   
103    Input: list of string containing 1 layout description
104           extracted from the processor layout file
105   
106    Output: tuple (jpni*jpnj, n oce domain, n land domain)
107    """
108    ntot = int(txtlst[1].split()[-1])
109    noce = int(txtlst[5].split()[-1])
110    nland = int(txtlst[6].split()[-1])
111    return (ntot, noce, nland)
112
113def extract_jpij(txtlst):
114    """
115    function to extract domain dimension
116    for a specific domain layout txt output
117
118    Input: list of string containing 1 layout description
119           extracted from the processor layout file
120
121    Output: tuple (jpi, jpj)
122    """
123    ctmp = txtlst[4].split()
124    jpi = int(ctmp[1])
125    jpj = int(ctmp[3])
126    return (jpi, jpj)
127
128def extract_point(txtlst):
129    """
130    function to extract ration (computed/global)
131    for a specific domain layout txt output
132
133    Input: list of string containing 1 layout description
134           extracted from the processor layout file
135
136    Output: tuple (total number of point, overhead, ratio (computed/global))
137    """
138    npoint = int(txtlst[13].split()[-1])
139    noverh = int(txtlst[14].split()[-1])
140    ratio = float(txtlst[15].split()[-1])
141    return (npoint, noverh, ratio)
142
143# main
144def main():
145    """
146    script to sort and select processor layout from MPP_PREP output based on user constrains
147    """
148   
149    parser = argparse.ArgumentParser()
150    parser.add_argument("-f", metavar='layout_file' , help="names of domain layout file to sort", type=str, nargs=1, required=True)
151    parser.add_argument("--rmax", metavar='max_ratio' , help="max ratio allowed (computed/global)", type=float, nargs=1, required=True)
152    parser.add_argument("--noce", metavar='min/max_noce' , help="min and max number of ocean domain allowed", type=int, nargs=2, required=True)
153   
154    args = parser.parse_args()
155   
156    # read file
157    filein = args.f[0]
158    fid = open(filein,"r") #opens file with name of "test.txt"
159    txtdata = []
160    for cline in fid:
161        txtdata.extend([cline])
162
163    # skip header and tail of file
164    txtdata = txtdata[4:-20]
165   
166    # loop on different domain decomposition
167    ilinepl = 17 # number of line of a specific decomposition
168    ilayout = 0
169    lst_layout = []
170    ratio_min = 9999.0
171    noce_min = 9999999
172    noce_max = 0
173    for iline in range(0, len(txtdata)):
174        if iline % ilinepl == 0:
175            # initialise layout
176            conf_layout = layout( txtdata[iline:iline+ilinepl] )
177            ratio_min = min( conf_layout.ratio[2], ratio_min )           
178            noce_min = min( conf_layout.nproc[1], noce_min )           
179            noce_max = max( conf_layout.nproc[1], noce_max )           
180 
181            # select layout based on condition
182            if conf_layout.test_criterion(args.rmax[0], args.noce[0], args.noce[1]): 
183                ilayout = ilayout + 1
184                lst_layout.extend([conf_layout])
185
186    if lst_layout == []:
187        print('')
188        print( 'E R R O R: constrains are too strong, no domain are found' )
189        print('')
190        if ratio_min > args.rmax[0] :
191            print( 'min ratio is      {} and you ask for a ratio smaller than {}'.format(ratio_min, args.rmax[0]) )
192        if noce_min > args.noce[1] :
193            print( 'min ocean proc is {} and you ask for a number of ocean proc lower than {}'.format(noce_min, args.noce[1]) )
194        if noce_max < args.noce[0] :
195            print( 'max ocean proc is {} and you ask for a number of ocean proc larger than {}'.format(noce_max, args.noce[0]) )
196        print('')
197        sys.exit()
198   
199    lst_layout.sort(key=noce_proc)
200    for idx, ilayout in enumerate(lst_layout):
201        ilayout.print_layout(str(idx))
202   
203    print( '=====================================================================' )
204    print('')
205    print( 'Among the layouts fitting the constraint on : ratio (computed/global) < {} and {} <= number of ocean domain <= {}' \
206        .format(args.rmax[0], args.noce[0], args.noce[1]) )
207    print('')
208    print( ' 3 layouts are highlighted : ' )
209    print('')
210    lst_layout.sort(key=ratio_proc)
211    lst_layout[0].print_layout('SMALLEST RATIO')
212#
213    lst_layout.sort(key=noce_proc)
214    lst_layout[-1].print_layout('LARGEST NUMBER OF OCEAN DOMAINS')
215#
216    lst_layout.sort(key=jpij_proc)
217    lst_layout[0].print_layout('SMALLEST COMPUTED DOMAIN')
218   
219if __name__ == "__main__":
220    main()
Note: See TracBrowser for help on using the repository browser.