1 | import glob |
---|
2 | import sys |
---|
3 | import subprocess |
---|
4 | import os |
---|
5 | import json |
---|
6 | import itertools |
---|
7 | import copy |
---|
8 | |
---|
9 | param_list = ["ATMdomain", "UsingServer2", "NumberClients", "NumberServers", "RatioServer2", "NumberPoolsServer2", "Duration"] |
---|
10 | param_short_list = ["ATMdom", "Srv2", "NbClnt", "NbSrv", "RatioSrv2", "NbPlSrv2", "Duration"] |
---|
11 | |
---|
12 | mode=os.getenv("mode") |
---|
13 | arch=os.getenv("arch") |
---|
14 | machine=os.getenv("xios_machine_name") |
---|
15 | my_counter=1 |
---|
16 | portion=0 |
---|
17 | |
---|
18 | nb_proc_irene=20 # this must be >= NumberClients+NumberServers for all configs for all test folders |
---|
19 | nb_proc_jz=36 # this must be >= sum(NumberClients+NumberServers) for each test folder |
---|
20 | |
---|
21 | def OSinfo(runthis): |
---|
22 | red = lambda text: '\033[0;31m' + text + '\033[0m' |
---|
23 | osstdout = subprocess.Popen(runthis, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) |
---|
24 | theInfo = osstdout.communicate()[0].strip() |
---|
25 | if osstdout.returncode!=0: |
---|
26 | print(red(runthis+" FAILED")) |
---|
27 | print(theInfo) |
---|
28 | sys.exit() |
---|
29 | |
---|
30 | def product_dict(**kwargs): |
---|
31 | keys = kwargs.keys() |
---|
32 | vals = kwargs.values() |
---|
33 | for instance in itertools.product(*vals): |
---|
34 | yield dict(zip(keys, instance)) |
---|
35 | |
---|
36 | def get_default_param(): |
---|
37 | f=open("default_param.json", 'r') |
---|
38 | default_param = json.load(f) |
---|
39 | f.close() |
---|
40 | return default_param[0] |
---|
41 | |
---|
42 | def generate_job(fn, n): |
---|
43 | if machine=="irene": |
---|
44 | with open(fn, "w") as fh: |
---|
45 | fh.write("#!/bin/bash\n") |
---|
46 | fh.write("#MSUB -r XIOS\n") |
---|
47 | fh.write("#MSUB -eo\n") |
---|
48 | fh.write("#MSUB -o client_output.out\n") |
---|
49 | fh.write("#MSUB -e client_error.out\n") |
---|
50 | fh.write("#MSUB -c 1\n") |
---|
51 | fh.write("#MSUB -n "+str(n)+"\n") |
---|
52 | fh.write("#MSUB -X\n") |
---|
53 | fh.write("#MSUB -x\n") |
---|
54 | fh.write("#MSUB -T 1800\n") |
---|
55 | fh.write("#MSUB -q skylake\n") |
---|
56 | fh.write("#MSUB -A gen0826\n") |
---|
57 | fh.write("#MSUB -Q test\n") |
---|
58 | fh.write("#MSUB -m work,scratch\n") |
---|
59 | fh.write("source ../../../BUILD/build_"+arch+"_"+mode+"/arch.env\n") |
---|
60 | fh.write("ccc_mprun -n "+str(n)+" generic_testcase.exe\n") |
---|
61 | |
---|
62 | if machine=="jeanzay": |
---|
63 | with open(fn, "w") as fh: |
---|
64 | fh.write("#!/bin/bash\n") |
---|
65 | fh.write("#SBATCH --ntasks="+str(n)+"\n") |
---|
66 | fh.write("#SBATCH --hint=nomultithread\n") |
---|
67 | fh.write("#SBATCH -o output.out\n") |
---|
68 | fh.write("#SBATCH -e error.out\n") |
---|
69 | fh.write("#SBATCH -t 00:10:00\n") |
---|
70 | fh.write("#SBATCH --account=psl@cpu\n") |
---|
71 | fh.write("ulimit -c 0\n") |
---|
72 | fh.write("cd ${SLURM_SUBMIT_DIR}\n") |
---|
73 | fh.write("source ../../../BUILD/build_"+arch+"_"+mode+"/arch.env\n") |
---|
74 | fh.write("source $I_MPI_ROOT/intel64/bin/mpivars.sh release_mt") |
---|
75 | fh.write("srun generic_testcase.exe") |
---|
76 | |
---|
77 | |
---|
78 | def update_full_job(location, n): |
---|
79 | global my_counter |
---|
80 | if machine=="irene": |
---|
81 | with open("full_job_"+arch+"_"+mode+".sh", "a") as fh: |
---|
82 | fh.write("\ncd ${location}/"+location+"; ccc_mprun -E \'--exclusive\' -n "+str(n)+" generic_testcase.exe > output.out 2> error.out &\n") |
---|
83 | fh.write("PIDS+=($!)\n") |
---|
84 | fh.write("CONFIGS+=("+location+")\n") |
---|
85 | if machine=="jeanzay": |
---|
86 | with open("full_job_"+arch+"_"+mode+".sh", "a") as fh: |
---|
87 | fh.write("\ncd ${location}/"+location+"; srun --exclusive -n "+str(n)+" generic_testcase.exe > output.out 2> error.out &\n") |
---|
88 | #fh.write("echo \"test progress "+str(my_counter*portion)+"% \"\n") |
---|
89 | #my_counter = my_counter+1 |
---|
90 | |
---|
91 | def main(): |
---|
92 | global portion |
---|
93 | tmp_list=glob.glob("test_*/CONFIG_*") |
---|
94 | nb_configs = len(tmp_list) |
---|
95 | portion = 100.0/nb_configs |
---|
96 | |
---|
97 | if machine=="irene": |
---|
98 | with open("full_job_"+arch+"_"+mode+".sh", "w") as fh: |
---|
99 | fh.write("#!/bin/bash\n") |
---|
100 | fh.write("#MSUB -r XIOS\n") |
---|
101 | fh.write("#MSUB -eo\n") |
---|
102 | fh.write("#MSUB -o client_output.out\n") |
---|
103 | fh.write("#MSUB -e client_error.err\n") |
---|
104 | fh.write("#MSUB -c 1\n") |
---|
105 | fh.write("#MSUB -n "+str(nb_proc_irene)+"\n") |
---|
106 | fh.write("#MSUB -X\n") |
---|
107 | fh.write("#MSUB -x\n") |
---|
108 | fh.write("#MSUB -T 1800\n") |
---|
109 | fh.write("#MSUB -q skylake\n") |
---|
110 | fh.write("#MSUB -A gen0826\n") |
---|
111 | fh.write("#MSUB -Q test\n") |
---|
112 | fh.write("#MSUB -m work,scratch\n") |
---|
113 | fh.write("export location="+os.getcwd()+"\n") |
---|
114 | fh.write("export log_location="+os.getcwd()+"\n") |
---|
115 | fh.write("source ../BUILD/build_"+arch+"_"+mode+"/arch.env\n") |
---|
116 | fh.write("echo \"parallel launch arch="+arch+" mode="+mode+"\" >> ${log_location}/Log.txt\n") |
---|
117 | fh.write("date >> ${log_location}/Log.txt\n") |
---|
118 | |
---|
119 | if machine=="jeanzay": |
---|
120 | with open("full_job_"+arch+"_"+mode+".sh", "w") as fh: |
---|
121 | fh.write("#!/bin/bash\n") |
---|
122 | fh.write("#SBATCH --ntasks="+str(nb_proc_jz)+"\n") |
---|
123 | fh.write("#SBATCH --hint=nomultithread\n") |
---|
124 | fh.write("#SBATCH -t 00:10:00\n") |
---|
125 | fh.write("#SBATCH --account=psl@cpu\n") |
---|
126 | fh.write("ulimit -c 0\n") |
---|
127 | fh.write("cd ${SLURM_SUBMIT_DIR}\n") |
---|
128 | fh.write("source ../BUILD/build_"+arch+"_"+mode+"/arch.env\n") |
---|
129 | fh.write("source $I_MPI_ROOT/intel64/bin/mpivars.sh release_mt\n") |
---|
130 | fh.write("export location="+os.getcwd()+"\n") |
---|
131 | fh.write("export log_location="+os.getcwd()+"\n") |
---|
132 | fh.write("echo \"parallel launch arch="+arch+" mode="+mode+"\" >> ${log_location}/Log.txt\n") |
---|
133 | fh.write("date >> ${log_location}/Log.txt\n") |
---|
134 | |
---|
135 | |
---|
136 | |
---|
137 | test_folder_list = glob.glob('test_*') |
---|
138 | all_config=dict() |
---|
139 | |
---|
140 | default_param = get_default_param() |
---|
141 | # print(default_param) |
---|
142 | |
---|
143 | for test_folder in test_folder_list: |
---|
144 | config_list=[] |
---|
145 | config_name=[] |
---|
146 | with open(test_folder+"/user_param.json", "r") as f: |
---|
147 | config_dict = json.load(f) |
---|
148 | |
---|
149 | for i in range(len(config_dict)): |
---|
150 | config_list.extend(list(product_dict(**config_dict[i]))) |
---|
151 | #print(config_list) |
---|
152 | for i in range(len(config_list)): |
---|
153 | # print(config_list[i]) |
---|
154 | keylist = list(config_list[i].keys()) |
---|
155 | # print(keylist) |
---|
156 | full_config = copy.deepcopy(default_param) |
---|
157 | for j in range(len(keylist)): |
---|
158 | full_config[ keylist[j] ] = config_list[i][keylist[j]] |
---|
159 | |
---|
160 | #print(full_config) |
---|
161 | mystr = str(full_config) |
---|
162 | mystr = mystr.replace("{", "") |
---|
163 | mystr = mystr.replace("}", "") |
---|
164 | mystr = mystr.replace("[", "") |
---|
165 | mystr = mystr.replace("]", "") |
---|
166 | mystr = mystr.replace(",", "") |
---|
167 | mystr = mystr.replace(":", "") |
---|
168 | mystr = mystr.replace("'", "") |
---|
169 | mystr = mystr.replace("b'", "") |
---|
170 | mystr = mystr.replace(" ", "_") |
---|
171 | for j in range(len(param_list)): |
---|
172 | mystr = mystr.replace(param_list[j], param_short_list[j]) |
---|
173 | if not mystr in config_name: |
---|
174 | config_name.append(mystr) |
---|
175 | #print(mystr) |
---|
176 | OSinfo("mkdir -p "+test_folder+"/CONFIG_"+mystr) |
---|
177 | OSinfo("cp build_"+arch+"_"+mode+"/bin/generic_testcase.exe "+test_folder+"/CONFIG_"+mystr) |
---|
178 | OSinfo("cp iodef.xml "+test_folder+"/CONFIG_"+mystr+"/iodef.xml.tmp") |
---|
179 | |
---|
180 | with open(test_folder+"/CONFIG_"+mystr+"/iodef.xml.tmp", "r") as f: |
---|
181 | lines = f.readlines() |
---|
182 | for i in range(len(lines)): |
---|
183 | if "XIOS::" in lines[i]: |
---|
184 | config_keys = list(full_config.keys()) |
---|
185 | for idx in range(len(config_keys)): |
---|
186 | lines[i] = lines[i].replace("XIOS::"+config_keys[idx], str(full_config[config_keys[idx]])) |
---|
187 | with open(test_folder+"/CONFIG_"+mystr+"/iodef.xml", "w") as g: |
---|
188 | for line in lines: |
---|
189 | g.write(line) |
---|
190 | |
---|
191 | OSinfo("rm -f "+test_folder+"/CONFIG_"+mystr+"/iodef.xml.tmp") |
---|
192 | OSinfo("cp "+test_folder+"/context_atm.xml "+test_folder+"/CONFIG_"+mystr+"/") |
---|
193 | OSinfo("cp context_grid_dynamico.xml "+test_folder+"/CONFIG_"+mystr+"/") |
---|
194 | OSinfo("cp dynamico_grid.nc "+test_folder+"/CONFIG_"+mystr+"/") |
---|
195 | OSinfo("cp "+test_folder+"/checkfile.def "+test_folder+"/CONFIG_"+mystr+"/") |
---|
196 | with open(test_folder+"/CONFIG_"+mystr+"/param.def", "w") as fh: |
---|
197 | fh.write("¶ms_run\n") |
---|
198 | fh.write("duration=\'"+full_config["Duration"]+"\'\n") |
---|
199 | fh.write("nb_proc_atm="+str(full_config["NumberClients"])+"\n") |
---|
200 | fh.write("/\n") |
---|
201 | with open(test_folder+"/CONFIG_"+mystr+"/all_param.def", "w") as fh: |
---|
202 | fh.write("¶ms_run\n") |
---|
203 | for param in param_list: |
---|
204 | fh.write(param+"="+str(full_config[param])+"\n") |
---|
205 | fh.write("/\n") |
---|
206 | |
---|
207 | generate_job(test_folder+"/CONFIG_"+mystr+"/job.sh", full_config['NumberClients']+full_config['NumberServers']) |
---|
208 | update_full_job(test_folder+"/CONFIG_"+mystr, full_config['NumberClients']+full_config['NumberServers']) |
---|
209 | |
---|
210 | #print(config_name) |
---|
211 | with open("full_job_"+arch+"_"+mode+".sh", "a") as fh: |
---|
212 | fh.write("wait\nwait\n") |
---|
213 | fh.write("echo \"tests in "+test_folder+" finished\"\n") |
---|
214 | all_config[test_folder] = config_name |
---|
215 | |
---|
216 | |
---|
217 | if machine=="irene": |
---|
218 | with open("full_job_"+arch+"_"+mode+".sh", "a") as fh: |
---|
219 | fh.write("\nfor pid in ${PIDS[@]}; do\n") |
---|
220 | fh.write("wait ${pid}\n") |
---|
221 | fh.write("STATUS+=($?)\ndone\n") |
---|
222 | fh.write("\ni=0\n") |
---|
223 | fh.write("#for st in ${STATUS[@]}; do\n") |
---|
224 | fh.write("#if [[ ${st} -ne 0 ]]; then\n") |
---|
225 | fh.write("#echo \"${CONFIGS[${i}]} -1\" >> ${location}/plain_report.txt\n") |
---|
226 | fh.write("#else\n") |
---|
227 | fh.write("#echo \"${CONFIGS[${i}]} 1\" >> ${location}/plain_report.txt\n") |
---|
228 | fh.write("#fi\n") |
---|
229 | fh.write("#((i+=1))\n") |
---|
230 | fh.write("#done\n\n") |
---|
231 | fh.write("#wait\n") |
---|
232 | fh.write("date >> ${log_location}/Log.txt\n") |
---|
233 | if machine=="jeanzay": |
---|
234 | with open("full_job_"+arch+"_"+mode+".sh", "a") as fh: |
---|
235 | fh.write("date >> ${log_location}/Log.txt\n") |
---|
236 | |
---|
237 | |
---|
238 | #print(all_config) |
---|
239 | |
---|
240 | if __name__== "__main__": |
---|
241 | main() |
---|