Joseph Huber 292e898c16 [OpenMP] Begin Adding OpenMP Tool to Gather OpenMP Information
Summary:
This patch begins to add support for a set of scripts that can be used to get information from OpenMP programs to better describe problems and eventually show the data to the user in formatted output. Right now the only support is forformatting the register and memory usage reports from ptxas and nvlink. This is simply done as a wrapper around clang and clang++.

Reviewers: jdoerfert

DIfferential Revision: https://reviews.llvm.org/D91085
2020-11-11 20:00:37 -05:00

55 lines
2.2 KiB
Python

#!/usr/bin/env python
import subprocess
import os.path
import yaml
import io
import re
def parseKernelUsages(usageStr, usageDict):
demangler = 'c++filt -p'
def getKernelMem(usages):
match = re.search(r"([0-9]+) bytes cmem\[0\]", usages)
return match.group(1) if match else None
def getSharedMem(usages):
match = re.search(r"([0-9]+) bytes smem", usages)
return match.group(1) if match else None
def getRegisters(usages):
match = re.search(r"[Uu]sed ([0-9]+) registers", usages)
return match.group(1) if match else None
def demangle(fn):
expr = re.compile("__omp_offloading_[a-zA-Z0-9]*_[a-zA-Z0-9]*_(_Z.*_)_l[0-9]*$")
match = expr.search(fn)
function = match.group(1) if match else fn
output = subprocess.run(demangler.split(' ') + [function], check=True, stdout=subprocess.PIPE)
return output.stdout.decode('utf-8').strip()
def getLine(fn):
expr = re.compile("__omp_offloading_[a-zA-Z0-9]*_[a-zA-Z0-9]*_.*_l([0-9]*)$")
match = expr.search(fn)
return match.group(1) if match else 0
expr = re.compile("Function properties for \'?([a-zA-Z0-9_]*)\'?\n(.*,.*)\n")
for (fn, usages) in expr.findall(usageStr):
info = usageDict[fn] if fn in usageDict else dict()
info["Name"] = demangle(fn)
info["DebugLoc"] = {"File" : "unknown", "Line": getLine(fn), "Column" : 0}
info["Usage"] = {"Registers" : getRegisters(usages), "Shared" : getSharedMem(usages), "Kernel" : getKernelMem(usages)}
usageDict[fn] = info
def getKernelUsage(stderr, fname='usage.yaml'):
remarks = [line for line in stderr.split('\n') if re.search(r"^remark:", line)]
ptxas = '\n'.join([line.split(':')[1].strip() for line in stderr.split('\n') if re.search(r"^ptxas info *:", line)])
nvlink = '\n'.join([line.split(':')[1].strip() for line in stderr.split('\n') if re.search(r"^nvlink info *:", line)])
if os.path.exists(fname):
with io.open(fname, 'r', encoding = 'utf-8') as f:
usage = yaml.load(f, Loader=yaml.Loader)
else:
usage = dict()
parseKernelUsages(ptxas, usage)
parseKernelUsages(nvlink, usage)
return usage