Skip to content

Commit 7071080

Browse files
author
cassiope
committed
Fast: move testcases and python code from Cassiopee/Apps/Apps/Fast
1 parent db53c5b commit 7071080

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+12365
-2
lines changed

Fast/Fast/Fast/Common.py

+244
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
# Class common to all types of FAST simulations
2+
import FastC.PyTree as FastC
3+
import Converter.PyTree as C
4+
import Converter.Internal as Internal
5+
from Apps.App import App
6+
import Converter.Filter as Filter
7+
import Converter.Mpi as Cmpi
8+
9+
try: range = xrange
10+
except: pass
11+
12+
#================================================================================
13+
# Redistribue les fichiers in place sans com pour l'instant
14+
# Change les noeuds procs seulement
15+
#=================================================================================
16+
def _distribute(t_in, tc_in, NP=Cmpi.size):
17+
if isinstance(t_in, str):
18+
if Cmpi.rank == 0: _distributeFile(t_in, tc_in, NP)
19+
else: _distributeMem(t_in, tc_in, NP)
20+
return None
21+
22+
def _distributeFile(t_in, tc_in, NP):
23+
import Distributor2.PyTree as D2
24+
t = Filter.convertFile2SkeletonTree(t_in, maxDepth=3, maxFloatSize=6)
25+
tc = Filter.convertFile2SkeletonTree(tc_in, maxDepth=3, maxFloatSize=6)
26+
stats = D2._distribute(tc, NP, algorithm='graph', useCom='ID')
27+
D2._copyDistribution(t, tc)
28+
nodes = Internal.getNodesFromName(t, 'proc')
29+
for n in nodes:
30+
p = Internal.getPath(t, n)
31+
Filter.writeNodesFromPaths(t_in, p, n)
32+
nodes = Internal.getNodesFromName(tc, 'proc')
33+
for n in nodes:
34+
p = Internal.getPath(tc, n)
35+
Filter.writeNodesFromPaths(tc_in, p, n)
36+
return None
37+
38+
def _distributeMem(t, tc, NP):
39+
import Distributor2.PyTree as D2
40+
tbbc = Cmpi.createBBoxTree(tc)
41+
stats = D2._distribute(tbbc, NP, algorithm='graph', useCom='ID')
42+
D2._copyDistribution(tc, tbbc)
43+
D2._copyDistribution(t, tbbc)
44+
return None
45+
46+
#==================================================
47+
# distribution + choix du nombre de coeurs optimum
48+
#==================================================
49+
def _distributeOpt(t_in, tc_in, corePerNode=28, nptMaxPerCore=4.e6):
50+
if isinstance(t_in, str):
51+
if Cmpi.rank == 0: _distributeOptFile(t_in, tc_in, corePerNode, nptMaxPerCore)
52+
else:
53+
#_distributeOptMem(t_in, tc_in, corePerNode, nptMaxPerCore)
54+
raise ValueError('Not implemented.')
55+
return None
56+
57+
def _distributeOptFile(t_in, tc_in, corePerNode=28, nptMaxPerCore=4.e6):
58+
import Distributor2.PyTree as D2
59+
t = Filter.convertFile2SkeletonTree(t_in, maxDepth=3, maxFloatSize=6)
60+
tc = Filter.convertFile2SkeletonTree(tc_in, maxDepth=3, maxFloatSize=6)
61+
62+
nbpts=0.; maxipts=0.
63+
for zone in Internal.getZones(t):
64+
ncells = C.getNCells(zone)
65+
nbpts += ncells
66+
maxipts = max(maxipts, ncells)
67+
68+
MaxNbProcs=int(nbpts/maxipts)+1
69+
70+
MinNbProcs=MaxNbProcs
71+
for nbproc in range(2,MaxNbProcs+1):
72+
if nbpts*1./nbproc < nptMaxPerCore: MinNbProcs=min(nbproc,MinNbProcs)
73+
74+
print('La distribution sera testee entre %d procs et %d procs.'%(MinNbProcs,MaxNbProcs))
75+
76+
#MinNbProcs = 140
77+
#MaxNbProcs = 140
78+
listequ = []
79+
varmax = 99.
80+
NP = MinNbProcs
81+
for nbproc in range(MinNbProcs,MaxNbProcs+1):
82+
if nbproc%corePerNode==0:
83+
print('Distribution sur %s procs.')
84+
stats = D2._distribute(tc, nbproc, algorithm='graph', useCom='ID')
85+
listequ.append([nbproc,stats['varMax']])
86+
if stats['varMax']<varmax: varmax = stats['varMax']; NP=nbproc
87+
88+
stats = D2._distribute(tc, NP, algorithm='graph', useCom='ID')
89+
print('Best distribution found on %d procs.'%NP)
90+
print(stats)
91+
#D2._printProcStats(t,stats,NP)
92+
93+
D2._copyDistribution(t, tc)
94+
nodes = Internal.getNodesFromName(t, 'proc')
95+
for n in nodes:
96+
p = Internal.getPath(t, n)
97+
Filter.writeNodesFromPaths(t_in, p, n)
98+
nodes = Internal.getNodesFromName(tc, 'proc')
99+
for n in nodes:
100+
p = Internal.getPath(tc, n)
101+
Filter.writeNodesFromPaths(tc_in, p, n)
102+
103+
return NP
104+
105+
#================================================================================
106+
# en gros, warmup
107+
#================================================================================
108+
def setup(t_in, tc_in, numb, numz, format='single'):
109+
if Cmpi.size > 1:
110+
import FastS.Mpi as FastS
111+
FastC.HOOK = None
112+
rank = Cmpi.rank; size = Cmpi.size
113+
else:
114+
import FastS.PyTree as FastS
115+
FastC.HOOK = None
116+
rank = 0; size = 1
117+
118+
t,tc,ts,graph = FastC.load(t_in, tc_in, split=format)
119+
120+
# Numerics
121+
FastC._setNum2Zones(t, numz); FastC._setNum2Base(t, numb)
122+
(t, tc, metrics) = FastS.warmup(t, tc, graph)
123+
return t, tc, ts, metrics, graph
124+
125+
#============================================================================
126+
# Ecrit le resultat
127+
# t: arbre
128+
# t_out: fichier de sortie
129+
# it0: iteration correspondant a la fin du cacul
130+
# time0: temps correspondant a la fin du calcul
131+
# format: "single" ou "multiple"
132+
# compress: si 1, compress le fichier pour le cartesien, 2, compressAll
133+
# ===========================================================================
134+
def finalize(t, t_out=None, it0=None, time0=None, format='single', compress=0):
135+
if it0 is not None:
136+
Internal.createUniqueChild(t, 'Iteration', 'DataArray_t', value=it0)
137+
if time0 is not None:
138+
Internal.createUniqueChild(t, 'Time', 'DataArray_t', value=time0)
139+
if t_out is not None and isinstance(t_out, str):
140+
FastC.save(t, t_out, split=format, compress=compress)
141+
142+
#=====================================================================================
143+
# IN: t_in : nom du fichier t input ou arbre input
144+
# IN: tc_in: nom du fichier tc input ou arbre tc
145+
# IN: t_out, tc_out: noms de fichiers ou arbres de sortie
146+
# IN: numb, numz: les data numeriques
147+
# IN: NIT: nbre d'iterations
148+
# format: single ou multiple
149+
# compress: si 1, compress le fichier de sortie pour le cartesien, 2 compressAll
150+
#======================================================================================
151+
def compute(t_in, tc_in,
152+
t_out, tc_out,
153+
numb, numz,
154+
NIT,
155+
format='single', compress=0):
156+
if Cmpi.size > 1:
157+
import FastS.Mpi as FastS
158+
rank = Cmpi.rank; size = Cmpi.size
159+
else:
160+
import FastS.PyTree as FastS
161+
rank = 0; size = 1
162+
163+
t,tc,ts,graph = FastC.load(t_in, tc_in, split=format)
164+
165+
# Numerics
166+
FastC._setNum2Zones(t, numz); FastC._setNum2Base(t, numb)
167+
168+
(t, tc, metrics) = FastS.warmup(t, tc, graph)
169+
170+
it0 = 0; time0 = 0.
171+
first = Internal.getNodeFromName1(t, 'Iteration')
172+
if first is not None: it0 = Internal.getValue(first)
173+
first = Internal.getNodeFromName1(t, 'Time')
174+
if first is not None: time0 = Internal.getValue(first)
175+
time_step = Internal.getNodeFromName(t, 'time_step')
176+
time_step = Internal.getValue(time_step)
177+
178+
if 'modulo_verif' in numb: moduloVerif = numb['modulo_verif']
179+
else: moduloVerif = 200
180+
181+
for it in range(NIT):
182+
FastS._compute(t, metrics, it, tc, graph)
183+
if it%moduloVerif == 0:
184+
if rank == 0: print('- %d / %d - %f'%(it+it0, NIT+it0, time0))
185+
FastS.display_temporal_criteria(t, metrics, it, format='double')
186+
#if it%50 == 0:
187+
# import CPlot.PyTree as CPlot
188+
# CPlot.display(t, dim=2, mode='Scalar', scalarField='Density')
189+
time0 += time_step
190+
191+
# time stamp
192+
Internal.createUniqueChild(t, 'Iteration', 'DataArray_t', value=it0+NIT)
193+
Internal.createUniqueChild(t, 'Time', 'DataArray_t', value=time0)
194+
if t_out is not None and isinstance(t_out,str):
195+
FastC.save(t, t_out, split=format, compress=compress)
196+
if tc_out is not None and isinstance(tc_out,str):
197+
FastC.save(tc, tc_out, split=format)
198+
if Cmpi.size > 1: Cmpi.barrier()
199+
return t, tc
200+
201+
#===============================================================================
202+
class Common(App):
203+
"""Preparation et caculs avec le module FastS."""
204+
def __init__(self, format=None, numb=None, numz=None):
205+
App.__init__(self)
206+
self.__version__ = "0.0"
207+
self.authors = ["[email protected]"]
208+
self.requires(['format', 'numb', 'numz'])
209+
self.compress = 0
210+
# default values
211+
if format is not None: self.set(format=format)
212+
else: self.set(format='single')
213+
if numb is not None: self.set(numb=numb)
214+
if numz is not None: self.set(numz=numz)
215+
216+
# Compute nit iterations
217+
# peut etre lance en sequentiel ou en parallele
218+
def compute(self, t_in, tc_in, t_out, nit, tc_out=None):
219+
numb = self.data['numb']
220+
numz = self.data['numz']
221+
compress = self.compress
222+
return compute(t_in, tc_in, t_out, tc_out,
223+
numb, numz,
224+
nit,
225+
format=self.data['format'],
226+
compress=compress)
227+
228+
# warm up et all
229+
def setup(self, t_in, tc_in):
230+
numb = self.data['numb']
231+
numz = self.data['numz']
232+
return setup(t_in, tc_in, numb, numz, self.data['format'])
233+
234+
# Ecrit le fichier de sortie
235+
def finalize(self, t_out=None, it0=None, time0=None):
236+
finalize(t_out, it0, time0, self.data['format'])
237+
238+
# distribue fichiers ou en memoire
239+
def _distribute(self, t_in, tc_in, NP=Cmpi.size):
240+
return _distribute(t_in, tc_in, NP)
241+
242+
# distribue fichiers ou en memoire, trouve le NP optimal
243+
def _distributeOpt(self, t_in, tc_in, corePerNode=28, nptMaxPerCore=4.e6):
244+
return _distributeOpt(t_in, tc_in, corePerNode, nptMaxPerCore)

0 commit comments

Comments
 (0)