Skip to content
Snippets Groups Projects
Commit 78465deb authored by Tim Jammer's avatar Tim Jammer
Browse files

added coverage for parcoach

parent 9d3aa970
No related branches found
No related tags found
No related merge requests found
...@@ -2,53 +2,60 @@ import re ...@@ -2,53 +2,60 @@ import re
import os import os
from MBButils import * from MBButils import *
class Tool(AbstractTool): class Tool(AbstractTool):
def identify(self): def identify(self):
return "PARCOACH wrapper" return "PARCOACH wrapper"
def ensure_image(self): def ensure_image(self):
AbstractTool.ensure_image(self, "-x parcoach") #AbstractTool.ensure_image(self, "-x parcoach")
pass
def build(self, rootdir, cached=True): def build(self, rootdir, cached=True):
if cached and os.path.exists(f"/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin/parcoachcc"): # nothing to do
print("No need to rebuild PARCOACH.") pass
os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin/"
os.environ['OMPI_CC'] = "clang-15"
return
here = os.getcwd() # Save where we were
os.chdir(rootdir)
subprocess.run(f"wget https://gitlab.inria.fr/api/v4/projects/12320/packages/generic/parcoach/2.4.0/parcoach-2.4.0-shared-Linux.tar.gz", shell=True, check=True)
subprocess.run(f"tar xfz parcoach-*.tar.gz", shell=True, check=True)
if not os.path.exists("/usr/lib/llvm-15/bin/clang"):
subprocess.run("ln -s $(which clang) /usr/lib/llvm-15/bin/clang", shell=True, check=True)
# Go to where we want to install it, and build it out-of-tree (we're in the docker)
subprocess.run(f"rm -rf /tmp/build-parcoach/parcoach-2.4.0-shared-Linux/ && mkdir -p /tmp/build-parcoach/", shell=True, check=True)
subprocess.run(f"mv parcoach-*/ /tmp/build-parcoach/ ", shell=True, check=True)
os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin/"
os.environ['OMPI_CC'] = "clang-15"
# Back to our previous directory
os.chdir(here)
def setup(self): def setup(self):
os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin" # os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin"
os.environ['OMPI_CC'] = "clang-15" os.environ['OMPI_CC'] = "clang-15"
result_parcoach = subprocess.run(
"which parcoach", shell=True, check=True, capture_output=True, text=True
)
self.parcoach_exe = result_parcoach.stdout.strip()
clang_19_bin = os.environ["LLVM_19_BIN"]
self.llvm_cov = clang_19_bin + "/llvm-cov"
self.llvm_profdata = clang_19_bin + "/llvm-profdata"
assert os.path.isfile(self.llvm_cov)
assert os.path.isfile(self.llvm_profdata)
self.llvm_profile_folder = os.environ["LLVM_PROFILE_FOLDER"]
assert os.path.isdir(self.llvm_profile_folder)
self.coverage_profile = "parcoach_profile.pro"
self.coverage_report_html = "parcoach_coverage_html"
self.coverage_source = os.path.dirname(self.parcoach_exe)+"/../src/"
def run(self, execcmd, filename, binary, id, number, timeout, batchinfo, loglevel=logging.INFO): def run(self, execcmd, filename, binary, id, number, timeout, batchinfo, loglevel=logging.INFO):
self.setup()
os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin" os.environ['PATH'] = os.environ['PATH'] + f":/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/bin"
os.environ['OMPI_CC'] = "clang-15" os.environ['OMPI_CC'] = "clang-15"
os.environ['OMPI_ALLOW_RUN_AS_ROOT'] = "1" os.environ['OMPI_ALLOW_RUN_AS_ROOT'] = "1"
os.environ['OMPI_ALLOW_RUN_AS_ROOT_CONFIRM'] = "1" os.environ['OMPI_ALLOW_RUN_AS_ROOT_CONFIRM'] = "1"
cachefile = f'{binary}_{id}' cachefile = f'{binary}_{id}'
current_env = os.environ.copy()
base_file = os.path.basename(filename)
current_env["LLVM_PROFILE_FILE"] = f"{self.llvm_profile_folder}/{base_file}-mbb{number}.profraw"
execcmd = re.sub('\${EXE}', f'./{binary}', execcmd) execcmd = re.sub('\${EXE}', f'./{binary}', execcmd)
if filename.find('lock') >= 0 or filename.find('fence') >= 0: if filename.find('lock') >= 0 or filename.find('fence') >= 0:
self.run_cmd( self.run_cmd(
# buildcmd=f"parcoachcc -check=rma --args mpicc {filename} -c -o {binary}.o", # buildcmd=f"parcoachcc -check=rma --args mpicc {filename} -c -o {binary}.o",
buildcmd=f"parcoachcc -check=rma --args mpicc {filename} -c -o {binary}.o \n mpicc {binary}.o -o {binary} -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/ -lParcoachRMADynamic_MPI_C", # buildcmd=f"parcoachcc -check=rma --args mpicc {filename} -c -o {binary}.o \n mpicc {binary}.o -o {binary} -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/ -lParcoachRMADynamic_MPI_C",
execcmd=f"mpicc {binary}.o -lParcoachRMADynamic_MPI_C -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/", # execcmd=f"mpicc {binary}.o -lParcoachRMADynamic_MPI_C -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/",
buildcmd=f"mpicc {filename} -S -emit-llvm -o {binary}.ir",
execcmd=f"{self.parcoach_exe} --check=rma {binary}.ir ",
# execcmd=execcmd, # execcmd=execcmd,
cachefile=cachefile, cachefile=cachefile,
filename=filename, filename=filename,
...@@ -56,12 +63,15 @@ class Tool(AbstractTool): ...@@ -56,12 +63,15 @@ class Tool(AbstractTool):
binary=binary, binary=binary,
timeout=timeout, timeout=timeout,
batchinfo=batchinfo, batchinfo=batchinfo,
loglevel=loglevel) loglevel=loglevel,
current_env=current_env, )
else: else:
self.run_cmd( self.run_cmd(
# buildcmd=f"parcoachcc -instrum-inter --args mpicc {filename} -c -o {binary}.o", # buildcmd=f"parcoachcc -instrum-inter --args mpicc {filename} -c -o {binary}.o",
buildcmd=f"parcoachcc -instrum-inter --args mpicc {filename} -c -o {binary}.o \n mpicc {binary}.o -o {binary} -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/ -lParcoachCollDynamic_MPI_C", # buildcmd=f"parcoachcc -instrum-inter --args mpicc {filename} -c -o {binary}.o \n mpicc {binary}.o -o {binary} -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/ -lParcoachCollDynamic_MPI_C",
execcmd=f"mpicc {binary}.o -lParcoachCollDynamic_MPI_C -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/", buildcmd=f"mpicc {filename} -S -emit-llvm -o {binary}.ir",
execcmd=f"{self.parcoach_exe} --check=mpi {binary}.ir ",
# execcmd=f"mpicc {binary}.o -lParcoachCollDynamic_MPI_C -L/tmp/build-parcoach/parcoach-2.4.0-shared-Linux/lib/",
# execcmd=execcmd, # execcmd=execcmd,
cachefile=cachefile, cachefile=cachefile,
filename=filename, filename=filename,
...@@ -69,18 +79,61 @@ class Tool(AbstractTool): ...@@ -69,18 +79,61 @@ class Tool(AbstractTool):
binary=binary, binary=binary,
timeout=timeout, timeout=timeout,
batchinfo=batchinfo, batchinfo=batchinfo,
loglevel=loglevel) loglevel=loglevel,
current_env=current_env, )
self.merge_coverage_single(filename=filename,
profile=f"{self.llvm_profile_folder}/{base_file}-mbb{number}.profraw", number=number)
subprocess.run("rm -f *.bc core", shell=True, check=True) subprocess.run("rm -f *.bc core", shell=True, check=True)
def merge_coverage_single(self, filename, profile, number):
here = os.getcwd()
os.chdir(self.llvm_profile_folder)
# print(f"We are here: {profile}")
try:
if os.path.isfile(profile):
command = f"-o {os.path.basename(filename)}-mbb{number}.pro"
subprocess.run(
f"{self.llvm_profdata} merge -sparse {profile} {command}",
shell=True,
check=True,
)
subprocess.run(
f"rm {profile}",
shell=True,
check=False,
)
except Exception:
pass
finally:
os.chdir(here)
def teardown(self):
self.setup()
here = os.getcwd()
os.chdir(self.llvm_profile_folder)
subprocess.run(
f"{self.llvm_profdata} merge -sparse *.pro -o {self.coverage_profile}",
shell=True,
check=True,
)
if os.path.exists(self.coverage_profile):
subprocess.run(
f"{self.llvm_cov} show -format=html {self.parcoach_exe} "
f"--instr-profile={self.coverage_profile} "
f"--show-directory-coverage --output-dir {self.coverage_report_html} "
f"--sources {self.coverage_source}",
shell=True,
check=True,
)
os.chdir(here)
def get_mbb_error_label(self, error_message): def get_mbb_error_label(self, error_message):
mbb_error_dict = { mbb_error_dict = {
'LocalConcurrency': "LocalConcurrency", 'LocalConcurrency': "LocalConcurrency",
'Call Ordering': "CallOrdering" 'Call Ordering': "CallOrdering"
} }
for k, v in mbb_error_dict.items(): for k, v in mbb_error_dict.items():
if error_message.startswith(k): if error_message.startswith(k):
return v return v
...@@ -88,18 +141,16 @@ class Tool(AbstractTool): ...@@ -88,18 +141,16 @@ class Tool(AbstractTool):
assert False and "ERROR MESSAGE NOT KNOWN PARSING DOES NOT WORK CORRECLTY" assert False and "ERROR MESSAGE NOT KNOWN PARSING DOES NOT WORK CORRECLTY"
return "UNKNOWN" return "UNKNOWN"
def parse(self, cachefile, logs_dir): def parse(self, cachefile, logs_dir):
if os.path.exists(f'{cachefile}.timeout') or os.path.exists(f'{logs_dir}/parcoach/{cachefile}.timeout'): if os.path.exists(f'{cachefile}.timeout') or os.path.exists(f'{logs_dir}/parcoach/{cachefile}.timeout'):
outcome = 'timeout' outcome = 'timeout'
if not (os.path.exists(f'{cachefile}.txt') or os.path.exists(f'{logs_dir}/parcoach/{cachefile}.txt')): if not (os.path.exists(f'{cachefile}.txt') or os.path.exists(f'{logs_dir}/parcoach/{cachefile}.txt')):
return 'failure' return 'failure'
with open(f'{cachefile}.txt' if os.path.exists(f'{cachefile}.txt') else f'{logs_dir}/parcoach/{cachefile}.txt', 'r') as infile: with open(f'{cachefile}.txt' if os.path.exists(f'{cachefile}.txt') else f'{logs_dir}/parcoach/{cachefile}.txt',
'r') as infile:
output = infile.read() output = infile.read()
if re.search('Compilation of .*? raised an error \(retcode: ', output): if re.search('Compilation of .*? raised an error \(retcode: ', output):
output = {} output = {}
output["status"] = "UNIMPLEMENTED" output["status"] = "UNIMPLEMENTED"
...@@ -125,7 +176,8 @@ class Tool(AbstractTool): ...@@ -125,7 +176,8 @@ class Tool(AbstractTool):
for line in lines: for line in lines:
# get the error/warning blocks: # get the error/warning blocks:
if re.match(COerror_line_prefix, line) or re.match(LC1error_line_prefix,line) or re.match(LC2error_line_prefix, line) or re.match(LCinfo_line_prefix,line): if re.match(COerror_line_prefix, line) or re.match(LC1error_line_prefix, line) or re.match(
LC2error_line_prefix, line) or re.match(LCinfo_line_prefix, line):
current_report.append(line) current_report.append(line)
reports.append(current_report) reports.append(current_report)
# print("--- current_report = ", current_report, "\n") # print("--- current_report = ", current_report, "\n")
...@@ -186,7 +238,6 @@ class Tool(AbstractTool): ...@@ -186,7 +238,6 @@ class Tool(AbstractTool):
parsed_report['ranks'] = list(set(parsed_report['ranks'])) parsed_report['ranks'] = list(set(parsed_report['ranks']))
parsed_reports.append(parsed_report) parsed_reports.append(parsed_report)
# parsed_reports = list(set(parsed_reports)) # parsed_reports = list(set(parsed_reports))
output["messages"] = parsed_reports output["messages"] = parsed_reports
# output["messages"] = list(set(output["messages"])) # output["messages"] = list(set(output["messages"]))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment