Skip to content

Commit 1b543c6

Browse files
authored
Merge pull request #15550 from mcgratta/master
FDS Verification: Convert fds_timing_stats.sh to python
2 parents 3b7dcd3 + 2f80179 commit 1b543c6

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
2+
# Produce a table of verification case CPU times in Manuals/FDS_Verification_Guide/SCRIPT_FIGURES/Scatterplots
3+
4+
import os
5+
import subprocess
6+
import csv
7+
8+
curdir = os.getcwd()
9+
verdir = '../../Verification/'
10+
resdir = '../../Manuals/FDS_Verification_Guide/SCRIPT_FIGURES/Scatterplots/'
11+
resfile = resdir + 'fds_timing_stats.csv'
12+
13+
with open(resfile, 'w') as f:
14+
f.write('FDS Case,Wall Clock Time (s),CPU Time (s),Number of Cells,Number of Time Steps,Performance Metric (1e-6)\n')
15+
16+
with open(verdir + 'FDS_Cases.sh', 'r') as casefile:
17+
for line in casefile:
18+
if line.strip().startswith('$QFDS'):
19+
parts = line.split()
20+
if '-d' in parts:
21+
d_index = parts.index('-d')
22+
if d_index + 2 < len(parts):
23+
subdir = parts[d_index + 1]
24+
fdsfile = parts[d_index + 2]
25+
26+
# Extract base filename without extension
27+
fdsbase = verdir + subdir + '/' + os.path.splitext(fdsfile)[0]
28+
outfile = f"{fdsbase}.out"
29+
cpufile = f"{fdsbase}_cpu.csv"
30+
31+
# Check if outfile exists, try alternate name if not
32+
if not os.path.exists(outfile):
33+
outfile = f"{fdsbase}_cat.out"
34+
if not os.path.exists(outfile):
35+
continue
36+
37+
# Check if cpufile exists, try alternate name if not
38+
if not os.path.exists(cpufile):
39+
cpufile = f"{fdsbase}_cat_cpu.csv"
40+
if not os.path.exists(cpufile):
41+
continue
42+
43+
# Grep for wall clock time
44+
WALL_CLOCK_TIME_VALUE = ""
45+
with open(outfile, 'r') as f:
46+
for line in f:
47+
if "Total Elapsed Wall Clock Time (s):" in line:
48+
WALL_CLOCK_TIME_VALUE = line.strip().split()[-1]
49+
50+
# Grep for CPU time and units
51+
TOTAL_CPU_TIME = 0.0
52+
CPU_TIME_VALUES = []
53+
54+
with open(cpufile, 'r') as f:
55+
lines = f.readlines()
56+
# Skip first line (header), process rest
57+
for line in lines[1:]:
58+
if line.strip():
59+
# Get last column (split by comma)
60+
parts = line.strip().split(',')
61+
if parts:
62+
CPU_TIME_VALUES.append(parts[-1])
63+
64+
# Process each CPU time value
65+
for j in CPU_TIME_VALUES:
66+
TOTAL_CPU_TIME += eval(j)
67+
68+
CPU_TIME = TOTAL_CPU_TIME
69+
70+
# Grep for number of cells in each dimension
71+
X_CELLS = []
72+
Y_CELLS = []
73+
Z_CELLS = []
74+
75+
with open(outfile, 'r') as f:
76+
for line in f:
77+
if "Cells in the X" in line:
78+
X_CELLS.append(line.strip().split()[-1])
79+
elif "Cells in the Y" in line:
80+
Y_CELLS.append(line.strip().split()[-1])
81+
elif "Cells in the Z" in line:
82+
Z_CELLS.append(line.strip().split()[-1])
83+
84+
numx = len(X_CELLS)
85+
86+
# Sum over the number of cells (for multi-mesh cases)
87+
NUM_TOTAL_CELLS = 0
88+
for i in range(numx):
89+
XI = int(X_CELLS[i])
90+
YI = int(Y_CELLS[i])
91+
ZI = int(Z_CELLS[i])
92+
sumxyz = XI * YI * ZI
93+
NUM_TOTAL_CELLS += sumxyz
94+
95+
# Grep for number of time steps
96+
NUM_TIME_STEPS = 0
97+
time_step_lines = []
98+
with open(outfile, 'r') as f:
99+
for line in f:
100+
if "Time Step " in line:
101+
time_step_lines.append(line)
102+
103+
if time_step_lines:
104+
# Get the last occurrence
105+
last_line = time_step_lines[-1]
106+
parts = last_line.strip().split()
107+
if len(parts) >= 5:
108+
# Get the 5th element from the end (NF-4 in awk)
109+
NUM_TIME_STEPS = int(parts[-5])
110+
111+
# Calculate nondimensional performance metric
112+
# Skip over cases with no time steps
113+
if NUM_TIME_STEPS == 0:
114+
NUM_TIME_STEPS = 0
115+
PERFORMANCE = 0
116+
else:
117+
# Calculate performance metric
118+
PERFORMANCE = int(1000000 * TOTAL_CPU_TIME / (NUM_TOTAL_CELLS * NUM_TIME_STEPS))
119+
120+
# Write results to fds_timing_stats.csv file
121+
with open(resfile, 'a', newline='') as f:
122+
csv_writer = csv.writer(f)
123+
csv_writer.writerow([fdsfile,WALL_CLOCK_TIME_VALUE,CPU_TIME,NUM_TOTAL_CELLS,NUM_TIME_STEPS,PERFORMANCE])
124+
125+
126+
# Sum up the wall clock times in the second column
127+
128+
TOTAL_CPU_TIME = 0.0
129+
with open(resfile, 'r') as f:
130+
lines = f.readlines()
131+
for line in lines[1:]:
132+
if line.strip():
133+
fields = line.split(',')
134+
if len(fields) >= 3:
135+
j = fields[1].strip()
136+
TOTAL_CPU_TIME = TOTAL_CPU_TIME + eval(j)
137+
138+
# Get git short commit hash and append to tmpout
139+
140+
git_hash = subprocess.check_output(['git', 'rev-parse', '--short', 'HEAD'], cwd=curdir, universal_newlines=True).strip()
141+
142+
# Append git hash and total CPU time to fds_timing_stats.csv
143+
144+
with open(resfile, 'a') as f:
145+
f.write(git_hash + '\n')
146+
f.write(str(TOTAL_CPU_TIME) + '\n')
147+

0 commit comments

Comments
 (0)