#!/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