Source code for benchbuild.likwid
"""
Likwid helper functions.
Extract information from likwid's CSV output.
"""
[docs]def fetch_cols(fstream, split_char=','):
"""
Fetch columns from likwid's output stream.
Args:
fstream: The filestream with likwid's output.
split_car (str): The character we split on, default ','
Returns (list(str)):
A list containing the elements of fstream, after splitting at
split_char.
"""
return fstream.readline().strip().split(split_char)
[docs]def read_struct(fstream):
"""
Read a likwid struct from the text stream.
Args:
fstream: Likwid's filestream.
Returns (dict(str: str)):
A dict containing all likwid's struct info as key/value pairs.
"""
line = fstream.readline().strip()
fragments = line.split(",")
fragments = [x for x in fragments if x is not None]
partition = dict()
if not len(fragments) >= 3:
return None
partition["struct"] = fragments[0]
partition["info"] = fragments[1]
partition["num_lines"] = fragments[2]
struct = None
if partition is not None and partition["struct"] == "STRUCT":
num_lines = int(partition["num_lines"].strip())
struct = {}
for _ in range(num_lines):
cols = fetch_cols(fstream)
struct.update({cols[0]: cols[1:]})
return struct
[docs]def read_table(fstream):
"""
Read a likwid table info from the text stream.
Args:
fstream: Likwid's filestream.
Returns (dict(str: str)):
A dict containing likwid's table info as key/value pairs.
"""
pos = fstream.tell()
line = fstream.readline().strip()
fragments = line.split(",")
fragments = [x for x in fragments if x is not None]
partition = dict()
if not len(fragments) >= 4:
return None
partition["table"] = fragments[0]
partition["group"] = fragments[1]
partition["set"] = fragments[2]
partition["num_lines"] = fragments[3]
struct = None
if partition is not None and partition["table"] == "TABLE":
num_lines = int(partition["num_lines"].strip())
struct = {}
header = fetch_cols(fstream)
struct.update({header[0]: header[1:]})
for _ in range(num_lines):
cols = fetch_cols(fstream)
struct.update({cols[0]: cols[1:]})
else:
fstream.seek(pos)
return struct
[docs]def read_structs(fstream):
"""
Read all structs from likwid's file stream.
Args:
fstream: Likwid's output file stream.
Returns:
A generator that can be used to iterate over all structs in the
fstream.
"""
struct = read_struct(fstream)
while struct is not None:
yield struct
struct = read_struct(fstream)
[docs]def read_tables(fstream):
"""
Read all tables from likwid's file stream.
Args:
fstream: Likwid's output file stream.
Returns:
A generator that can be used to iterate over all tables in the fstream.
"""
table = read_table(fstream)
while table is not None:
yield table
table = read_table(fstream)
[docs]def get_measurements(region, core_info, data, extra_offset=0):
"""
Get the complete measurement info from likwid's region info.
Args:
region: The region we took a measurement in.
core_info: The core information.
data: The raw data.
extra_offset (int): default = 0
Returns (list((region, metric, core, value))):
A list of measurement tuples, a tuple contains the information about
the region, the metric, the core and the actual value.
"""
measurements = []
clean_core_info = [x for x in core_info if x]
cores = len(clean_core_info)
for k in data:
if k not in ["1", "Region Info", "Event", "Metric", "CPU clock"]:
slot = data[k]
for i in range(cores):
core = core_info[i]
idx = extra_offset + i
if core and slot[idx]:
measurements.append((region, k, core, slot[idx]))
return measurements
[docs]def perfcounters(infile):
"""
Get a complete list of all measurements.
Args:
infile: The filestream containing all likwid output.
Returns:
A list of all measurements extracted from likwid's file stream.
"""
measurements = []
with open(infile, 'r') as in_file:
read_struct(in_file)
for region_struct in read_structs(in_file):
region = region_struct["1"][1]
core_info = region_struct["Region Info"]
measurements += \
get_measurements(region, core_info, region_struct)
for table_struct in read_tables(in_file):
core_info = None
if "Event" in table_struct:
offset = 1
core_info = table_struct["Event"][offset:]
measurements += get_measurements(region, core_info,
table_struct, offset)
elif "Metric" in table_struct:
core_info = table_struct["Metric"]
measurements += get_measurements(region, core_info,
table_struct)
return measurements