11#!/usr/bin/env python3
22
33def cli ():
4- import os ,sys ,argparse
4+ import os ,shutil ,argparse
55 cli = argparse .ArgumentParser (description = 'CLARA scaling test' )
6- cli .add_argument ('-y' ,help = 'YAML file' ,required = True )
7- cli .add_argument ('-c' ,help = 'CLARA_HOME path' ,default = os .getenv ('CLARA_HOME' ,None ))
8- cli .add_argument ('-t' ,help = 'threads (default=4,8)' ,default = '4,8' )
9- cli .add_argument ('-e' ,help = 'events per thread' ,default = 100 ,type = int )
10- cli .add_argument ('-i' ,help = 'input data file' ,required = True )
6+ cli .add_argument ('-y' ,'--yaml' , metavar = 'YAML' ,help = 'path to YAML file' ,required = True )
7+ cli .add_argument ('-c' ,'--clara' , metavar = 'DIR' ,help = 'CLARA_HOME path (default=$CLARA_HOME)' ,default = os .getenv ('CLARA_HOME' ,None ))
8+ cli .add_argument ('-t' ,'--threads' ,metavar = '#' ,help = 'threads (default=4,8)' ,default = '4,8' )
9+ cli .add_argument ('-e' ,'--events' , metavar = '#' ,help = 'events per thread (default=555)' ,default = 555 ,type = int )
10+ cli .add_argument ('-N' ,'--numa' , metavar = '#' ,help = 'NUMA socket (default=None, choices=[0,1])' ,default = None ,type = int ,choices = [0 ,1 ])
11+ cli .add_argument ('datafile' , help = 'input EVIO/HIPO data file' )
1112 cfg = cli .parse_args ()
12- cfg .t = cfg .t .split (',' )
13- if cfg .c is None : sys .exit ('-c or $CLARA_HOME is required.' )
13+ cfg .threads = cfg .threads .split (',' )
14+ if not cfg .clara :
15+ cli .error ('cannot find CLARA installation via -c or $CLARA_HOME' )
16+ cfg .run_clara = find_run_clara (cfg .clara )
17+ if not cfg .run_clara :
18+ cli .error ('cannot find run-clara in $PATH or CLARA installation' )
19+ if cfg .numa is not None :
20+ if not shutil .which ('numactl' ):
21+ cli .error ('numactl is not in $PATH, --numa option not supported' )
22+ if len (list (get_numa_cpus (cfg .numa ))) == 0 :
23+ cli .error ('invalid --numa node: {cfg.numa}' )
24+ cfg .numa = ',' .join (list (get_numa_cpus (cfg .numa )))
1425 return cfg
1526
27+ def find_run_clara (clara_home ):
28+ import os ,shutil
29+ if shutil .which ('run-clara' ):
30+ return shutil .which ('run-clara' )
31+ elif os .path .exists (clara_home + '/plugins/clas12/bin/run-clara' ):
32+ return clara_home + '/plugins/clas12/bin/run-clara'
33+
34+ def get_numa_cpus (node ):
35+ for line in run (['numactl' ,'-H' ]):
36+ if line .startswith (f'node { node } cpus:' ):
37+ for col in line .strip ().split ()[3 :]:
38+ yield col
39+
1640def run (cmd ):
1741 import subprocess
1842 print ('run >>> ' + ' ' .join (cmd ))
@@ -26,21 +50,21 @@ def run(cmd):
2650 pass
2751
2852def benchmark (cfg , threads , log ):
29- import os ,sys ,shutil ,collections
30- run_clara = shutil .which ('run-clara' )
31- if not run_clara :
32- run_clara = cfg .c + '/plugins/clas12/bin/run-clara'
33- if not os .path .exists (run_clara ):
34- sys .exit ('run-clara is not in $PATH' )
35- exiting ,benchmarks = False ,collections .OrderedDict ()
36- cmd = [run_clara ,
37- '-c' ,cfg .c ,
38- '-n' ,str (cfg .e * int (threads )),
53+ import collections
54+ cmd = []
55+ # use taskset:
56+ if cfg .numa is not None :
57+ cmd .extend (['taskset' ,'-c' ,cfg .numa ])
58+ # add the run-clara command:
59+ cmd .extend ([cfg .run_clara ,
60+ '-c' ,cfg .clara ,
61+ '-n' ,str (cfg .events * int (threads )),
3962 '-t' ,str (threads ),
4063 '-l' ,
41- '-y' ,cfg .y ,
64+ '-y' ,cfg .yaml ,
4265 '-o' ,f'tmp-scaling-{ threads } ' ,
43- cfg .i ]
66+ cfg .datafile ])
67+ exiting ,benchmarks = False ,collections .OrderedDict ()
4468 for line in run (cmd ):
4569 cols = line .split ()
4670 print (line )
@@ -103,7 +127,7 @@ if __name__ == '__main__':
103127 cfg = cli ()
104128 import os
105129 benchmarks = []
106- for threads in cfg .t :
130+ for threads in cfg .threads :
107131 os .makedirs ('tmp-scaling-' + threads )
108132 with open (f'tmp-scaling-{ threads } /run-clara.log' ,'w' ) as log :
109133 benchmarks .append ([threads , benchmark (cfg , threads , log )])
0 commit comments