forked from lijiext/lammps
first drafts of
benchmark,py - numerical comparison of log files regression.sh - script for cron git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10640 f3b2605a-c512-4ea7-a41b-209d697bcdaa
This commit is contained in:
parent
b22a8a7b61
commit
1144c1b3f9
|
@ -0,0 +1,235 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
function: numerical comparisions of logs and corresponding benchmarks
|
||||||
|
usage: benchmark.py <nprocs> <njobs> <dirs>
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
import re
|
||||||
|
from operator import itemgetter
|
||||||
|
from glob import glob
|
||||||
|
import time
|
||||||
|
import multiprocessing as mp
|
||||||
|
try:
|
||||||
|
import Queue as queue # 2.6
|
||||||
|
except ImportError:
|
||||||
|
import queue # 3.0
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### constants
|
||||||
|
#====================================================
|
||||||
|
thermo_pattern = re.compile("^Step "); # fragile
|
||||||
|
data_pattern = re.compile("\s*\d"); # fragile
|
||||||
|
fail_pattern = re.compile("FAIL");
|
||||||
|
tol = 1.e-6 # 1.e-10
|
||||||
|
arch = "openmpi"
|
||||||
|
src_path = "../src/" #relative to home
|
||||||
|
exe_path = "../"+src_path
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### date
|
||||||
|
#====================================================
|
||||||
|
def date():
|
||||||
|
return time.asctime()
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### timer
|
||||||
|
#====================================================
|
||||||
|
## NOTE these don't seem to work how I expect them to
|
||||||
|
def start():
|
||||||
|
global dt
|
||||||
|
dt = -(time.clock())
|
||||||
|
def stop():
|
||||||
|
global dt
|
||||||
|
dt += (time.clock())
|
||||||
|
return dt
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### run a benchmark
|
||||||
|
#====================================================
|
||||||
|
def run_test(test):
|
||||||
|
input = "in."+test;
|
||||||
|
log = "log."+test
|
||||||
|
stdout = "stdout."+test
|
||||||
|
ref = (glob(log+"*."+str(np)))[0];
|
||||||
|
msg = "==== comparing "+log+" with "+ref+" ====\n"
|
||||||
|
if (os.path.isfile(log)): os.remove(log)
|
||||||
|
if (os.path.isfile(stdout)): os.remove(stdout)
|
||||||
|
os.system(lmps+input+" >& "+stdout);
|
||||||
|
if (not os.path.isfile(log)) :
|
||||||
|
msg += "!!! no "+log+"\n";
|
||||||
|
msg += "!!! test "+test+" FAILED\n"
|
||||||
|
return msg
|
||||||
|
[cdict,cdata] = extract_data(log);
|
||||||
|
[bdict,bdata] = extract_data(ref);
|
||||||
|
cols = range(len(bdict))
|
||||||
|
if (len(cdata) != len(bdata)):
|
||||||
|
msg += "!!! data size "+str(len(cdata))+" does not match data "+str(len(bdata))+" in "+ref+"\n";
|
||||||
|
msg += "!!! test "+test+" FAILED\n"
|
||||||
|
return msg
|
||||||
|
fail = False
|
||||||
|
i = 0
|
||||||
|
for name in bdict:
|
||||||
|
[passing,cmsg] = compare(name,cdata[cols[i]],bdata[cols[i]]);
|
||||||
|
i += 1
|
||||||
|
msg += cmsg
|
||||||
|
if (not passing) : fail = True
|
||||||
|
if (fail) :
|
||||||
|
msg += "!!! test "+test+" FAILED\n"
|
||||||
|
else :
|
||||||
|
msg += "*** test "+test+" passed\n"
|
||||||
|
return msg
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### extract data from log file
|
||||||
|
#====================================================
|
||||||
|
def extract_data(file):
|
||||||
|
dictionary = [];
|
||||||
|
data = []
|
||||||
|
read = False
|
||||||
|
for line in open(file):
|
||||||
|
if (read and data_pattern.match(line)) :
|
||||||
|
cols = line.split();
|
||||||
|
data.append(cols)
|
||||||
|
else :
|
||||||
|
read = False
|
||||||
|
if (thermo_pattern.match(line)):
|
||||||
|
dictionary = line.split();
|
||||||
|
read = True
|
||||||
|
return [dictionary,data]
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### compare columns of current and benchmark
|
||||||
|
#====================================================
|
||||||
|
def compare(name,col1,col2):
|
||||||
|
err = 0.
|
||||||
|
norm1 = 0.
|
||||||
|
norm2 = 0.
|
||||||
|
n = len(col2)
|
||||||
|
for i in range(n):
|
||||||
|
v1 = float(col1[i])
|
||||||
|
v2 = float(col2[i])
|
||||||
|
norm1 += v1*v1
|
||||||
|
norm2 += v2*v2
|
||||||
|
dv = v1-v2
|
||||||
|
err += dv*dv
|
||||||
|
norm1 /= n
|
||||||
|
norm2 /= n
|
||||||
|
err /= n
|
||||||
|
if (norm2 > tol) :
|
||||||
|
msg = "{0:7s} relative error {1:4} wrt norm {2:7}\n".format(name,err,norm2)
|
||||||
|
else :
|
||||||
|
msg = "{0:7s} error {1:4}\n" .format(name,err)
|
||||||
|
return [(err < tol),msg];
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
class Worker(mp.Process):
|
||||||
|
def __init__(self, work_queue, result_queue):
|
||||||
|
mp.Process.__init__(self)
|
||||||
|
self.work_queue = work_queue
|
||||||
|
self.result_queue = result_queue
|
||||||
|
def run(self):
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
job = self.work_queue.get_nowait()
|
||||||
|
except queue.Empty:
|
||||||
|
break
|
||||||
|
#print(">>> starting " + str(job[1]) + " ...")
|
||||||
|
os.chdir(job[0])
|
||||||
|
start()
|
||||||
|
msg = run_test(job[1])
|
||||||
|
elapsed_time = stop()
|
||||||
|
msg += "elapsed time "+str(elapsed_time)+"\n"
|
||||||
|
os.chdir(home)
|
||||||
|
self.result_queue.put([job[1],msg])
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### parse
|
||||||
|
#====================================================
|
||||||
|
def init() :
|
||||||
|
global np, njobs, ntests, lmps, arch, home
|
||||||
|
home = os.getcwd()
|
||||||
|
if (len(sys.argv) < 4) :
|
||||||
|
print "usage: benchmark.py <nprocs> <njobs> <test_dirs>"
|
||||||
|
sys.exit(1)
|
||||||
|
np = int(sys.argv[1])
|
||||||
|
njobs = int(sys.argv[2])
|
||||||
|
lmps = "../"+src_path+"lmp_"+arch+" -in "
|
||||||
|
if (np > 1):
|
||||||
|
lmps = "mpirun -np "+str(np)+" "+lmps
|
||||||
|
else:
|
||||||
|
arch = "serial"
|
||||||
|
lmps = exe_path+"lmp_"+arch+" -in "
|
||||||
|
pool = mp.Pool(njobs)
|
||||||
|
dirs = sys.argv[3:]
|
||||||
|
tests = []
|
||||||
|
for dir in dirs:
|
||||||
|
os.chdir(dir);
|
||||||
|
for path in glob("./in.*"):
|
||||||
|
test = path[5:];
|
||||||
|
tests.append([dir,test])
|
||||||
|
os.chdir(home)
|
||||||
|
ntests = len(tests)
|
||||||
|
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||||
|
print "start: ",date()
|
||||||
|
print "arch:",arch,
|
||||||
|
print "nprocs:",np
|
||||||
|
print "ntests:",ntests,
|
||||||
|
print "njobs:",njobs
|
||||||
|
print "relative tolerance:",tol
|
||||||
|
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||||
|
print
|
||||||
|
return tests
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### build executable
|
||||||
|
#====================================================
|
||||||
|
def build(arch):
|
||||||
|
os.system("cd ..; svn update >& svn_update.log")
|
||||||
|
os.system("cd ../src; make no-atc >& /dev/null")
|
||||||
|
os.system("cd ../src; make clean-all >& /dev/null")
|
||||||
|
#os.system("cd ../src; make yes-all >& /dev/null")
|
||||||
|
os.system("cd ../src; make yes-dipole >& /dev/null")
|
||||||
|
sys.stdout.flush()
|
||||||
|
print "** building ",arch,"...",
|
||||||
|
os.system("cd "+src_path+"; make -j "+str(np)+" "+arch+" >& build_"+arch+".log")
|
||||||
|
if (not os.path.isfile(src_path+"lmp_"+arch)) :
|
||||||
|
print "!!! build ",arch," FAILED"
|
||||||
|
sys.exit()
|
||||||
|
else:
|
||||||
|
print "done"
|
||||||
|
print
|
||||||
|
|
||||||
|
#====================================================
|
||||||
|
### main
|
||||||
|
#====================================================
|
||||||
|
if __name__ == '__main__':
|
||||||
|
tests = init()
|
||||||
|
build(arch)
|
||||||
|
work_queue = mp.Queue()
|
||||||
|
for test in tests:
|
||||||
|
work_queue.put(test)
|
||||||
|
result_queue = mp.Queue()
|
||||||
|
nfails = 0
|
||||||
|
fail_list = []
|
||||||
|
for i in range(njobs):
|
||||||
|
w = Worker(work_queue, result_queue)
|
||||||
|
w.start()
|
||||||
|
for i in range(ntests):
|
||||||
|
[test,msg] = result_queue.get()
|
||||||
|
if (fail_pattern.search(msg)) :
|
||||||
|
nfails += 1
|
||||||
|
fail_list.append(test)
|
||||||
|
#print msg # can print only if failed
|
||||||
|
print msg # can print only if failed
|
||||||
|
#print test, " passed"
|
||||||
|
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
||||||
|
print "end:",date()
|
||||||
|
if (nfails == 0):
|
||||||
|
print "*** no failures ***"
|
||||||
|
else :
|
||||||
|
print "!!!",nfails,"of",ntests,"tests failed"
|
||||||
|
for test in fail_list:
|
||||||
|
print test
|
||||||
|
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
|
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/bash
|
||||||
|
cd /code/lammps-atc/regression
|
||||||
|
./benchmark.py 4 12 min dipole >& latest
|
||||||
|
fail=`grep -c FAIL latest`
|
||||||
|
addrs="rjones@sandia.gov jatempl@sandia.gov jzimmer@sandia.gov sjplimp@sandia.gov akohlmey@gmail.com"
|
||||||
|
if [ $fail == 0 ] ; then
|
||||||
|
mhmail $addrs -subject "LAMMPS regression passes" < latest
|
||||||
|
else
|
||||||
|
mhmail $addrs -subject "LAMMPS regression $fail tests failed" < latest
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue