HWRF  trunk@4391
forecast_procs.py
1 #! /usr/bin/env python
2 import sys,re,math
3 
4 babbling='''<!-- This file contains processor configurations for common node
5  sizes. It is used by the sites/*.ent to set processor counts for
6  each machine.
7 
8 DO NOT MODIFY THIS FILE! It is automatically generated by forecast_procs.py.
9 
10  Coupled forecast information:
11 
12  CPL_FCST_3KM_HYCOM_2IO_8PPN
13  | | | | |
14  | +=-=-=-=-=-=-=-=-=-= resolution: 2 or 3 km
15  | | | |
16  | | +=-=-=-=-= minimum number of dedicated I/O nodes
17  | | |
18  | | +=-=-= node size (processors per node)
19  | +=-=-=-=-=-=-=- ocean model: HYCOM or POM
20  +=-=-=-=-=-=-=-=-=-=-=-= FCST = processor configuration (12:ppn=8+23:ppn=8+2:ppn=8)
21  TASKS = task count (296)
22 
23  Uncoupled forecast information:
24 
25  ATM_FCST_2KM_2IO_12PPN
26  | | | |
27  | +=-=-=-=-=-=-=-=-=-= resolution: 2 or 3 km
28  | | |
29  | +=-=-=-=-= minimum number of dedicated I/O nodes
30  | |
31  | +=-=-= node size (processors per node)
32  |
33  +=-=-=-=-=-=-=-=-=-=-=-= FCST = processor configuration (12:ppn=8+23:ppn=8+2:ppn=8)
34  TASKS = task count (296)
35 -->
36 '''
37 
38 def pack(nodesize,count):
39  out=list()
40  n=count
41  if n<nodesize: # special case: smaller than one node
42  out.append([1,n])
43  elif nodesize*(n//nodesize)==n: #exact number of nodes
44  out.append([n//nodesize,nodesize])
45  else:
46  need=math.ceil(n/float(nodesize))
47  averagef=n/math.ceil(need)
48  af,ai = math.modf(averagef)
49  n1=need-round(af*need)
50  n2=round(af*need)
51  if n1: out.append([n1, ai])
52  if n2: out.append([n2, ai+1])
53  return out
54 
55 def gridproc(crayflag,n,*args):
56  #print 'gridproc(n,%s)'%(','.join([repr(s) for s in args]))
57  nodesize=int(n)
58  assert(nodesize>=8)
59  out=list()
60  requestproc=0
61  for arg in args:
62  if arg is None:
63  pass # Caller passes None for I/O servers on Theia
64  elif isinstance(arg,basestring) and re.match('^[0-9]+/[0-9]+$',arg):
65  c=arg.find('/')
66  n=int(arg[0:c],10)
67  requestproc+=n
68  nodemax=min(nodesize,int(arg[(c+1):],10))
69  out.extend(pack(nodemax,n))
70  elif arg==0:
71  continue # special case for no nodes: do nothing
72  elif arg>0:
73  n=arg
74  requestproc+=n
75  out.extend(pack(nodesize,n))
76  else:
77  sys.stderr.write('Bad argument '+repr(arg)+'\n')
78  exit(2)
79  sumproc=sum(x*y for x,y in out)
80  s='+'.join(['%d:ppn=%d'%(x,y) for x,y in out])
81  if requestproc!=sumproc:
82  sys.stderr.write('Logic error: requested %d proc got %d proc in %s.\n'%(
83  requestproc,sumproc,s))
84  exit(1)
85  #print 'Requested %d proc got %d proc'%(requestproc,sumproc)
86  #print s
87  return (sumproc,s)
88 
89 print babbling
90 
91 crayflag=False
92 for n in [8,12,16,24,1024,2024]:
93  crayflag=False
94  ww3=120
95  if n==1024:
96  io1=None # No I/O servers on Theia
97  io2=None
98  wrfcompute=16*30
99  n=24
100  elif n==2024: # Cray can only do one executable per node
101  io1='12/24'
102  io2=None
103  n=24
104  wrfcompute=16*30
105  crayflag=True
106  elif n==24:
107  io1='12/24' # WCOSS: one I/O node
108  io2=None
109  wrfcompute=16*30
110  else:
111  io1='8/8' # Everywhere else: two I/O nodes
112  io2='4/4' # Second node has one group
113  wrfcompute=16*28
114  for km in [3, 2]:
115  if km==3:
116  wrfcompute=23*8
117  cpl=1
118  pom=9
119  nio=1
120  elif n==24:
121  wrfcompute=16*30 # wcoss uses more ranks
122  nio=1
123  cpl=4
124  pom=9
125  else:
126  wrfcompute=16*28
127  cpl=4
128  pom=9
129  nio=1
130  if io1 is None:
131  nio=0
132  if crayflag:
133  proclist= [ ['NONE',0,0,0], ['POM',cpl,pom,0], ['HYCOM',6,90,0],
134  ['POMWW3',cpl,pom,ww3] ]
135  else:
136  proclist= [ ['NONE',0,0,0], ['POM',cpl,pom,0], ['HYCOM',0,96,0],
137  ['POMWW3',cpl,pom,ww3] ]
138  for om,cpl1,cpl2,cpl3 in proclist:
139  cray='_CRAY' if crayflag else ''
140  if om=='NONE':
141  pname='ATM_FCST_%dKM_%dIO_%dPPN%s'%(km,nio,n,cray)
142  tname='ATM_TASKS_%dKM_%dIO_%dPPN%s'%(km,nio,n,cray)
143  sumproc,procs = gridproc(crayflag,n,wrfcompute,io1,io2)
144  else:
145  pname='CPL_FCST_%dKM_%s_%dIO_%dPPN%s'%(km,om,nio,n,cray)
146  tname='CPL_TASKS_%dKM_%s_%dIO_%dPPN%s'%(km,om,nio,n,cray)
147  if crayflag:
148  sumproc,procs = gridproc(crayflag,n,cpl1,cpl2,cpl3,wrfcompute,io1,io2)
149  else:
150  sumproc,procs = gridproc(crayflag,n,cpl1+cpl2+cpl3,wrfcompute,io1,io2)
151  print '<!ENTITY %s "%s">'%(pname,procs)
152  print '<!ENTITY %s "%d">'%(tname,int(round(sumproc)))
153