mirror of
https://github.com/RRZE-HPC/OSACA.git
synced 2026-01-05 10:40:06 +01:00
Merge pull request #43 from RRZE-HPC/non_average_port_model
Non average port model
This commit is contained in:
1066
osaca/data/csx.yml
1066
osaca/data/csx.yml
File diff suppressed because it is too large
Load Diff
@@ -1,118 +1,29 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET
|
||||
from distutils.version import StrictVersion
|
||||
from itertools import groupby, product
|
||||
|
||||
from ruamel import yaml
|
||||
|
||||
from osaca.db_interface import add_entries_to_db
|
||||
from osaca.parser import ParserAArch64v81, ParserX86ATT
|
||||
from osaca.parser import get_parser
|
||||
from osaca.semantics import MachineModel
|
||||
|
||||
ARCH_DICT = {
|
||||
'vulcan': 'aarch64',
|
||||
'snb': 'x86',
|
||||
'ivb': 'x86',
|
||||
'hsw': 'x86',
|
||||
'bdw': 'x86',
|
||||
'skl': 'x86',
|
||||
'skx': 'x86',
|
||||
'csx': 'x86',
|
||||
}
|
||||
|
||||
def port_pressure_from_tag_attributes(attrib):
|
||||
# '1*p015+1*p1+1*p23+1*p4+3*p5' ->
|
||||
# [[1, '015'], [1, '1'], [1, '23'], [1, '4'], [3, '5']]
|
||||
port_occupation = []
|
||||
for p in attrib['ports'].split('+'):
|
||||
cycles, ports = p.split('*p')
|
||||
port_occupation.append([int(cycles), ports])
|
||||
|
||||
def port_pressure_from_tag_attributes(attrib, arch, ports):
|
||||
# apply cycles for D ports
|
||||
data_port = re.compile(r'[0-9]D$')
|
||||
data_ports = [x[:-1] for x in filter(data_port.match, ports)]
|
||||
|
||||
# format attributes
|
||||
cycles = attrib['ports'].split('+')
|
||||
cycles = [c.split('*') for c in cycles]
|
||||
for i, c in enumerate(cycles):
|
||||
cycles[i][0] = int(c[0])
|
||||
if str(c[1]).startswith('p'):
|
||||
cycles[i][1] = [p for p in c[1][1:]]
|
||||
if data_ports and data_ports == cycles[i][1]:
|
||||
# uops for data ports
|
||||
cycles.append([c[0], [x + 'D' for x in data_ports]])
|
||||
cycles[i][0] = [
|
||||
cycles[i][0] / num for num in range(1, len(cycles[i][1]) + 1) for _ in range(num)
|
||||
]
|
||||
cycles = [list(product(c[0], c[1])) for c in cycles]
|
||||
all_options = []
|
||||
|
||||
# iterate over all combinations of all uop options
|
||||
for cycles_combs in cycles:
|
||||
options = []
|
||||
tmp_opt = []
|
||||
total = cycles_combs[0][0]
|
||||
# iterate over all combinations of each uop option
|
||||
for comb in cycles_combs:
|
||||
# add options until they reach the total num of uops
|
||||
tmp_opt.append(comb)
|
||||
if sum([c[0] for c in tmp_opt]) == total:
|
||||
# copy this option as one of several to the cycle option list
|
||||
options.append(tmp_opt.copy())
|
||||
tmp_opt = []
|
||||
if len(tmp_opt) != 0:
|
||||
raise ValueError('Cannot compute port pressure')
|
||||
options = [x for x, _ in groupby(options)]
|
||||
all_options.append(options)
|
||||
all_options = list(product(*all_options))
|
||||
|
||||
# find best scheduling
|
||||
port_pressure = {}
|
||||
for p in ports:
|
||||
port_pressure[p] = 0.0
|
||||
first = calculate_port_pressure(all_options[0])
|
||||
for key in first:
|
||||
port_pressure[key] = first[key]
|
||||
for option in all_options[1:]:
|
||||
tmp = calculate_port_pressure(option)
|
||||
if (max(list(tmp.values())) <= max(list(port_pressure.values()))) and (
|
||||
len(tmp) > len([x for x in port_pressure.values() if x != 0.0])
|
||||
):
|
||||
for k in port_pressure:
|
||||
port_pressure[k] = tmp[k] if k in tmp else 0.0
|
||||
|
||||
# check if calculation equals given throughput
|
||||
if abs(max(list(port_pressure.values())) - float(attrib['TP_ports'])) > 0.01:
|
||||
print('Contradicting TP value compared to port_pressure. Ignore port pressure.')
|
||||
for p in port_pressure:
|
||||
port_pressure[p] = 0.0
|
||||
return port_pressure
|
||||
|
||||
# Also consider DIV pipeline
|
||||
# Also
|
||||
if 'div_cycles' in attrib:
|
||||
div_port = re.compile(r'[0-9]DV$')
|
||||
div_ports = [x for x in filter(div_port.match, ports)]
|
||||
for dp in div_ports:
|
||||
port_pressure[dp] += int(attrib['div_cycles']) / len(div_ports)
|
||||
return port_pressure
|
||||
port_occupation.append([int(attrib['div_cycles']), ['DIV']])
|
||||
|
||||
return port_occupation
|
||||
|
||||
|
||||
def calculate_port_pressure(pp_option):
|
||||
ports = {}
|
||||
for option in pp_option:
|
||||
for port in option:
|
||||
if port[1] in ports:
|
||||
ports[port[1]] += port[0]
|
||||
else:
|
||||
ports[port[1]] = port[0]
|
||||
return ports
|
||||
|
||||
|
||||
def extract_paramters(instruction_tag, arch):
|
||||
isa = ARCH_DICT[arch.lower()]
|
||||
parser = ParserX86ATT()
|
||||
if isa == 'aarch64':
|
||||
parser = ParserAArch64v81()
|
||||
elif isa == 'x86':
|
||||
parser = ParserX86ATT()
|
||||
def extract_paramters(instruction_tag, parser, isa):
|
||||
# Extract parameter components
|
||||
parameters = [] # used to store string representations
|
||||
parameter_tags = sorted(instruction_tag.findall("operand"), key=lambda p: int(p.attrib['idx']))
|
||||
@@ -175,9 +86,10 @@ def extract_paramters(instruction_tag, arch):
|
||||
|
||||
|
||||
def extract_model(tree, arch):
|
||||
mm = MachineModel(arch.lower())
|
||||
ports = mm._data['ports']
|
||||
model_data = []
|
||||
isa = MachineModel.get_isa_for_arch(arch)
|
||||
mm = MachineModel(isa=isa)
|
||||
parser = get_parser(isa)
|
||||
|
||||
for instruction_tag in tree.findall('.//instruction'):
|
||||
ignore = False
|
||||
|
||||
@@ -185,8 +97,8 @@ def extract_model(tree, arch):
|
||||
|
||||
# Extract parameter components
|
||||
try:
|
||||
parameters = extract_paramters(instruction_tag, arch)
|
||||
if ARCH_DICT[arch.lower()] == 'x86':
|
||||
parameters = extract_paramters(instruction_tag, parser, isa)
|
||||
if isa == 'x86':
|
||||
parameters.reverse()
|
||||
except ValueError as e:
|
||||
print(e, file=sys.stderr)
|
||||
@@ -208,9 +120,7 @@ def extract_model(tree, arch):
|
||||
int(measurement_tag.attrib['uops']) if 'uops' in measurement_tag.attrib else None
|
||||
)
|
||||
if 'ports' in measurement_tag.attrib:
|
||||
port_pressure.append(
|
||||
port_pressure_from_tag_attributes(measurement_tag.attrib, arch, ports)
|
||||
)
|
||||
port_pressure.append(port_pressure_from_tag_attributes(measurement_tag.attrib))
|
||||
latencies = [
|
||||
int(l_tag.attrib['cycles'])
|
||||
for l_tag in measurement_tag.iter('latency')
|
||||
@@ -233,9 +143,7 @@ def extract_model(tree, arch):
|
||||
arch_tag.iter('IACA'), key=lambda i: StrictVersion(i.attrib['version'])
|
||||
):
|
||||
if 'ports' in iaca_tag.attrib:
|
||||
port_pressure.append(
|
||||
port_pressure_from_tag_attributes(iaca_tag.attrib, arch, ports)
|
||||
)
|
||||
port_pressure.append(port_pressure_from_tag_attributes(iaca_tag.attrib))
|
||||
if ignore:
|
||||
continue
|
||||
|
||||
@@ -246,23 +154,20 @@ def extract_model(tree, arch):
|
||||
"Contradicting port occupancies, using latest IACA:", mnemonic, file=sys.stderr
|
||||
)
|
||||
port_pressure = port_pressure[-1]
|
||||
throughput = max(list(port_pressure.values()) + [0.0])
|
||||
|
||||
# Add missing ports:
|
||||
for ports in [pp[1] for pp in port_pressure]:
|
||||
for p in ports:
|
||||
mm.add_port(p)
|
||||
|
||||
throughput = max(mm.average_port_pressure(port_pressure))
|
||||
else:
|
||||
# print("No data available for this architecture:", mnemonic, file=sys.stderr)
|
||||
continue
|
||||
# ---------------------------------------------
|
||||
model_data.append(
|
||||
{
|
||||
'name': mnemonic,
|
||||
'operands': parameters,
|
||||
'uops': uops,
|
||||
'throughput': throughput,
|
||||
'latency': latency,
|
||||
'port_pressure': port_pressure,
|
||||
}
|
||||
)
|
||||
mm.set_instruction(mnemonic, parameters, latency, port_pressure, throughput, uops)
|
||||
|
||||
return model_data
|
||||
return mm
|
||||
|
||||
|
||||
def architectures(tree):
|
||||
@@ -281,13 +186,17 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
tree = ET.parse(args.xml)
|
||||
print('Available architectures:', ', '.join(architectures(tree)))
|
||||
if args.arch:
|
||||
model_data = extract_model(tree, args.arch)
|
||||
print(yaml.dump(model_data, allow_unicode=True))
|
||||
model = extract_model(tree, args.arch)
|
||||
print(model.dump())
|
||||
else:
|
||||
for arch in architectures(tree):
|
||||
model_data = extract_model(tree, arch)
|
||||
add_entries_to_db(arch, model_data)
|
||||
print(arch, end='')
|
||||
model = extract_model(tree, arch.lower())
|
||||
with open('{}.yml'.format(arch.lower()), 'w') as f:
|
||||
model.dump(f)
|
||||
print('.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
698
osaca/data/tx2.yml
Normal file
698
osaca/data/tx2.yml
Normal file
@@ -0,0 +1,698 @@
|
||||
osaca_version: 0.3.2
|
||||
micro_architecture: Thunder X2
|
||||
arch_code: tx2
|
||||
isa: AArch64
|
||||
ROB_size: 180
|
||||
retired_uOps_per_cycle: 4
|
||||
scheduler_size: 60
|
||||
hidden_loads: false
|
||||
load_latency: {w: 4.0, x: 4.0, b: 4.0, h: 4.0, s: 4.0, d: 4.0, q: 4.0, v: 4.0}
|
||||
load_throughput:
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [1, '34']}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [1, '34']}
|
||||
ports: ['0', 0DV, '1', 1DV, '2', '3', '4', '5']
|
||||
port_model_scheme: |
|
||||
┌-----------------------------------------------------------┐
|
||||
| 60 entry unified scheduler |
|
||||
└-----------------------------------------------------------┘
|
||||
0 | 1 | 2 | 3 | 4 | 5 |
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
┌------┐ ┌------┐ ┌------┐ ┌------┐ ┌------┐ ┌------┐
|
||||
| ALU | | ALU | | ALU/ | | LD | | LD | | ST |
|
||||
└------┘ └------┘ | BR | └------┘ └------┘ └------┘
|
||||
┌------┐ ┌------┐ └------┘ ┌------┐ ┌------┐
|
||||
| FP/ | | FP/ | | AGU | | AGU |
|
||||
| NEON | | NEON | └------┘ └------┘
|
||||
└------┘ └------┘
|
||||
┌------┐
|
||||
| INT |
|
||||
| MUL/ |
|
||||
| DIV |
|
||||
└------┘
|
||||
┌------┐
|
||||
|CRYPTO|
|
||||
└------┘
|
||||
instruction_forms:
|
||||
- name: add
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 1*p012
|
||||
port_pressure: [[1, '012']]
|
||||
- name: add
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: immediate
|
||||
imd: int
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 1*p012
|
||||
port_pressure: [[1, '012']]
|
||||
- name: adds
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: immediate
|
||||
imd: int
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 1*p012
|
||||
port_pressure: [[1, '012']]
|
||||
- name: b.ne
|
||||
operands:
|
||||
- class: identifier
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: b.gt
|
||||
operands:
|
||||
- class: identifier
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: bne
|
||||
operands:
|
||||
- class: identifier
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: cmp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: w
|
||||
- class: immediate
|
||||
imd: int
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 1*p012
|
||||
port_pressure: [[1, '012']]
|
||||
- name: cmp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 1*p012
|
||||
port_pressure: [[1, '012']]
|
||||
- name: fadd
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fadd
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fadd
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fdiv
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
throughput: 8.5
|
||||
latency: 16.0 # 1*p01+17*p0DV1DV
|
||||
port_pressure: [[1, '01'], [17.0, [0DV, 1DV]]]
|
||||
- name: fdiv
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
throughput: 12.0
|
||||
latency: 23.0 # 1*p01+24*p0DV1DV
|
||||
port_pressure: [[1, '01'], [24.0, [0DV, 1DV]]]
|
||||
- name: fmla
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fmla
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fmov
|
||||
operands:
|
||||
- {class: register, prefix: s}
|
||||
- {class: immediate, imd: double}
|
||||
latency: ~ # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
throughput: 0.5
|
||||
- name: fmul
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fmul
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fmul
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fsub
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: s
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: fsub
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: d
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: true
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 2*p34
|
||||
port_pressure: [[2.0, '34']]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0 # 1*p34
|
||||
port_pressure: [[1.0, '34']]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0 # 1*p34
|
||||
port_pressure: [[1.0, '34']]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: x
|
||||
scale: 8
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0 # 1*p34
|
||||
port_pressure: [[1.0, '34']]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
throughput: 0.0
|
||||
latency: 0.0
|
||||
port_pressure: []
|
||||
- name: mov
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: register
|
||||
prefix: x
|
||||
throughput: 0.5
|
||||
latency: 1.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: mov
|
||||
operands:
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: b
|
||||
- class: register
|
||||
prefix: v
|
||||
shape: b
|
||||
throughput: 0.5
|
||||
latency: 5.0 # 1*p01
|
||||
port_pressure: [[1, '01']]
|
||||
- name: prfm
|
||||
operands:
|
||||
- class: prfop
|
||||
type: pld
|
||||
target: l1
|
||||
policy: keep
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: ~
|
||||
latency: ~
|
||||
port_pressure: []
|
||||
- name: stp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 4*p34
|
||||
port_pressure: [[4.0, '34']]
|
||||
- name: stp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 4*p34
|
||||
port_pressure: [[4.0, '34']]
|
||||
- name: stp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 2.0
|
||||
latency: ~ # 2*p34+2*p5
|
||||
port_pressure: [[2.0, '34'], [2.0, '5']]
|
||||
- name: stp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 2*p34+2*p5
|
||||
port_pressure: [[2.0, '34'], [2.0, '5']]
|
||||
- name: stp
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 2*p34+2*p5
|
||||
port_pressure: [[2.0, '34'], [2.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: imd
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: d
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: x
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: q
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
- name: str
|
||||
operands:
|
||||
- class: register
|
||||
prefix: x
|
||||
- class: memory
|
||||
base: x
|
||||
offset: ~
|
||||
index: x
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 1*p34+1*p5
|
||||
port_pressure: [[1.0, '34'], [1.0, '5']]
|
||||
@@ -1,698 +0,0 @@
|
||||
osaca_version: 0.3.0
|
||||
micro_architecture: "Cavium Vulcan"
|
||||
arch_code: "Vulcan"
|
||||
isa: "AArch64"
|
||||
ROB_size: 180
|
||||
retired_uOps_per_cycle: 4
|
||||
scheduler_size: 60
|
||||
hidden_loads: false
|
||||
load_latency: {w: 4.0, x: 4.0, b: 4.0, h: 4.0, s: 4.0, d: 4.0, q: 4.0, v: 4.0}
|
||||
load_throughput:
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: ~, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: ~, offset: imd, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: ~, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 1, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: false, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: false, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: true, post-indexed: true, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
- {base: x, index: x, offset: imd, scale: 8, pre-indexed: true, post-indexed: false, port_pressure: [0,0,0,0,0,0.5,0.5,0]}
|
||||
ports: ["0", "0DV", "1", "1DV", "2", "3", "4", "5"]
|
||||
port_model_scheme: |
|
||||
┌-----------------------------------------------------------┐
|
||||
| 60 entry unified scheduler |
|
||||
└-----------------------------------------------------------┘
|
||||
0 | 1 | 2 | 3 | 4 | 5 |
|
||||
▼ ▼ ▼ ▼ ▼ ▼
|
||||
┌------┐ ┌------┐ ┌------┐ ┌------┐ ┌------┐ ┌------┐
|
||||
| ALU | | ALU | | ALU/ | | LD | | LD | | ST |
|
||||
└------┘ └------┘ | BR | └------┘ └------┘ └------┘
|
||||
┌------┐ ┌------┐ └------┘ ┌------┐ ┌------┐
|
||||
| FP/ | | FP/ | | AGU | | AGU |
|
||||
| NEON | | NEON | └------┘ └------┘
|
||||
└------┘ └------┘
|
||||
┌------┐
|
||||
| INT |
|
||||
| MUL/ |
|
||||
| DIV |
|
||||
└------┘
|
||||
┌------┐
|
||||
|CRYPTO|
|
||||
└------┘
|
||||
instruction_forms:
|
||||
- name: "add"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "add"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "immediate"
|
||||
imd: "int"
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "adds"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "immediate"
|
||||
imd: "int"
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "b.ne"
|
||||
operands:
|
||||
- class: 'identifier'
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
- name: "b.gt"
|
||||
operands:
|
||||
- class: 'identifier'
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
- name: "bne"
|
||||
operands:
|
||||
- class: 'identifier'
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
- name: "cmp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "w"
|
||||
- class: "immediate"
|
||||
imd: "int"
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "cmp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
throughput: 0.33333333
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.33333333, 0.0, 0.33333333, 0.0, 0.33333333, 0.0, 0.0, 0.0]
|
||||
- name: "fadd"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fadd"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fadd"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fdiv"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
throughput: 8.5
|
||||
latency: 16.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [1.0, 8.5, 1.0, 8.5, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fdiv"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
throughput: 12.0
|
||||
latency: 23.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [1.0, 12.5, 1.0, 12.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fmla"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- latency: ~
|
||||
name: "fmov"
|
||||
operands:
|
||||
- {class: "register", prefix: "s"}
|
||||
- {class: "immediate", imd: "double"}
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
throughput: 0.5
|
||||
- name: "fmul"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fmul"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fmul"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fsub"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "s"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "fsub"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "d"
|
||||
throughput: 0.5
|
||||
latency: 6.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: true
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "ldp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0]
|
||||
- name: ldr
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: "x"
|
||||
scale: 8
|
||||
post-indexed: false
|
||||
pre-indexed: false
|
||||
throughput: 0.5
|
||||
latency: 4.0
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0]
|
||||
- name: "ldr"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "ldr"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "ldr"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
throughput: 0.0
|
||||
latency: 0.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "mov"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
throughput: 0.5
|
||||
latency: 1.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "mov"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "b"
|
||||
- class: "register"
|
||||
prefix: "v"
|
||||
shape: "b"
|
||||
throughput: 0.5
|
||||
latency: 5.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.5, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0]
|
||||
- name: "prfm"
|
||||
operands:
|
||||
- class: "prfop"
|
||||
type: "pld"
|
||||
target: "l1"
|
||||
policy: "keep"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: ~
|
||||
latency: ~
|
||||
port_pressure: ~
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 0.0]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 2.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0]
|
||||
- name: "stp"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 2.0
|
||||
latency: ~ # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 2.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: "imd"
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "d"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: "x"
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "q"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: ~
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: true
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
- name: "str"
|
||||
operands:
|
||||
- class: "register"
|
||||
prefix: "x"
|
||||
- class: "memory"
|
||||
base: "x"
|
||||
offset: ~
|
||||
index: "x"
|
||||
scale: 1
|
||||
pre-indexed: false
|
||||
post-indexed: false
|
||||
throughput: 1.0
|
||||
latency: 4.0 # 0 0DV 1 1DV 2 3 4 5
|
||||
port_pressure: [0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 1.0]
|
||||
1102
osaca/data/zen1.yml
1102
osaca/data/zen1.yml
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,6 @@
|
||||
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import ruamel.yaml
|
||||
@@ -10,85 +9,6 @@ import ruamel.yaml
|
||||
from osaca.semantics import MachineModel
|
||||
|
||||
|
||||
def add_entry_to_db(arch: str, entry):
|
||||
"""Adds entry to the user database in ~/.osaca/data
|
||||
|
||||
Args:
|
||||
arch: string representation of the architecture as abbreviation.
|
||||
Database for this architecture must already exist.
|
||||
entry: DB entry which will be added. Should consist at best out of
|
||||
'name', 'operand(s)' ('register', 'memory', 'immediate', 'identifier', ...),
|
||||
'throughput', 'latency', 'port_pressure'.
|
||||
"""
|
||||
# load yaml
|
||||
arch = arch.lower()
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/' + arch + '.yml'))
|
||||
assert os.path.exists(filepath)
|
||||
yaml = _create_yaml_object()
|
||||
with open(filepath, 'r') as f:
|
||||
data = yaml.load(f)
|
||||
# check parameter of entry
|
||||
if 'name' not in entry:
|
||||
raise ValueError('No name for instruction specified. No import possible')
|
||||
if 'operands' not in entry:
|
||||
entry['operands'] = []
|
||||
if 'throughput' not in entry:
|
||||
entry['throughput'] = None
|
||||
if 'latency' not in entry:
|
||||
entry['latency'] = None
|
||||
if 'port_pressure' not in entry:
|
||||
entry['port_pressure'] = None
|
||||
if 'uops' not in entry:
|
||||
entry['uops'] = None
|
||||
data['instruction_forms'].append(entry)
|
||||
# __dump_data_to_yaml(filepath, data)
|
||||
with open(filepath, 'w') as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
|
||||
def add_entries_to_db(arch: str, entries: list) -> None:
|
||||
"""Adds entries to the user database in ~/.osaca/data
|
||||
|
||||
Args:
|
||||
arch: string representation of the architecture as abbreviation.
|
||||
Database for this architecture must already exist.
|
||||
entries: :class:`list` of DB entries which will be added. Should consist at best out of
|
||||
'name', 'operand(s)' ('register', 'memory', 'immediate', 'identifier', ...),
|
||||
'throughput', 'latency', 'port_pressure', 'uops'.
|
||||
"""
|
||||
# load yaml
|
||||
arch = arch.lower()
|
||||
filepath = os.path.join(os.path.expanduser('~/.osaca/data/' + arch + '.yml'))
|
||||
assert os.path.exists(filepath)
|
||||
yaml = _create_yaml_object()
|
||||
with open(filepath, 'r') as f:
|
||||
data = yaml.load(f)
|
||||
# check parameter of entry and append it to list
|
||||
for entry in entries:
|
||||
if 'name' not in entry:
|
||||
print(
|
||||
'No name for instruction \n\t{}\nspecified. No import possible'.format(entry),
|
||||
file=sys.stderr,
|
||||
)
|
||||
# remove entry from list
|
||||
entries.remove(entry)
|
||||
continue
|
||||
if 'operands' not in entry:
|
||||
entry['operands'] = []
|
||||
if 'throughput' not in entry:
|
||||
entry['throughput'] = None
|
||||
if 'latency' not in entry:
|
||||
entry['latency'] = None
|
||||
if 'port_pressure' not in entry:
|
||||
entry['port_pressure'] = None
|
||||
if 'uops' not in entry:
|
||||
entry['uops'] = None
|
||||
data['instruction_forms'].append(entry)
|
||||
# __dump_data_to_yaml(filepath, data)
|
||||
with open(filepath, 'w') as f:
|
||||
yaml.dump(data, f)
|
||||
|
||||
|
||||
def sanity_check(arch: str, verbose=False):
|
||||
# load arch machine model
|
||||
arch_mm = MachineModel(arch=arch)
|
||||
@@ -103,6 +23,7 @@ def sanity_check(arch: str, verbose=False):
|
||||
missing_throughput,
|
||||
missing_latency,
|
||||
missing_port_pressure,
|
||||
wrong_port,
|
||||
suspicious_instructions,
|
||||
duplicate_instr_arch,
|
||||
) = _check_sanity_arch_db(arch_mm, isa_mm)
|
||||
@@ -114,6 +35,7 @@ def sanity_check(arch: str, verbose=False):
|
||||
missing_throughput,
|
||||
missing_latency,
|
||||
missing_port_pressure,
|
||||
wrong_port,
|
||||
suspicious_instructions,
|
||||
duplicate_instr_arch,
|
||||
duplicate_instr_isa,
|
||||
@@ -135,8 +57,11 @@ def import_benchmark_output(arch, bench_type, filepath):
|
||||
elif bench_type == 'asmbench':
|
||||
raise NotImplementedError
|
||||
# write entries to DB
|
||||
add_entries_to_db(arch, list(db_entries.values()))
|
||||
|
||||
mm = MachineModel(arch)
|
||||
for entry in db_entries:
|
||||
mm.set_instruction_entry(entry)
|
||||
with open(filepath, 'w') as f:
|
||||
mm.dump(f)
|
||||
|
||||
##################
|
||||
# HELPERS IBENCH #
|
||||
@@ -179,6 +104,7 @@ def _get_ibench_output(input_data):
|
||||
+ ' and was not added. Please inspect your benchmark.'
|
||||
)
|
||||
db_entries[key] = entry
|
||||
return db_entries
|
||||
|
||||
|
||||
def _validate_measurement(self, measurement, is_tp):
|
||||
@@ -260,12 +186,12 @@ def _check_sanity_arch_db(arch_mm, isa_mm):
|
||||
suspicious_prefixes = suspicious_prefixes_arm
|
||||
if arch_mm.get_ISA().lower() == 'x86':
|
||||
suspicious_prefixes = suspicious_prefixes_x86
|
||||
port_num = len(arch_mm['ports'])
|
||||
|
||||
# returned lists
|
||||
missing_throughput = []
|
||||
missing_latency = []
|
||||
missing_port_pressure = []
|
||||
wrong_port = []
|
||||
suspicious_instructions = []
|
||||
duplicate_instr_arch = []
|
||||
|
||||
@@ -277,10 +203,9 @@ def _check_sanity_arch_db(arch_mm, isa_mm):
|
||||
missing_latency.append(instr_form)
|
||||
if instr_form['port_pressure'] is None:
|
||||
missing_port_pressure.append(instr_form)
|
||||
elif len(instr_form['port_pressure']) != port_num:
|
||||
warnings.warn(
|
||||
'Invalid number of ports:\n {}'.format(_get_full_instruction_name(instr_form))
|
||||
)
|
||||
else:
|
||||
if _check_for_wrong_port(arch_mm['ports'], instr_form):
|
||||
wrong_port.append(instr_form)
|
||||
# check entry against ISA DB
|
||||
for prefix in suspicious_prefixes:
|
||||
if instr_form['name'].startswith(prefix):
|
||||
@@ -302,11 +227,20 @@ def _check_sanity_arch_db(arch_mm, isa_mm):
|
||||
missing_throughput,
|
||||
missing_latency,
|
||||
missing_port_pressure,
|
||||
wrong_port,
|
||||
suspicious_instructions,
|
||||
duplicate_instr_arch,
|
||||
)
|
||||
|
||||
|
||||
def _check_for_wrong_port(port_list, instr_form):
|
||||
for cycles, ports in instr_form['port_pressure']:
|
||||
for p in ports:
|
||||
if p not in port_list:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _check_sanity_isa_db(arch_mm, isa_mm):
|
||||
# returned lists
|
||||
duplicate_instr_isa = []
|
||||
@@ -331,7 +265,7 @@ def _check_sanity_isa_db(arch_mm, isa_mm):
|
||||
|
||||
|
||||
def _print_sanity_report(
|
||||
total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa, verbose=False
|
||||
total, m_tp, m_l, m_pp, wrong_pp, suspic_instr, dup_arch, dup_isa, only_isa, verbose=False
|
||||
):
|
||||
# non-verbose summary
|
||||
print('SUMMARY\n----------------------')
|
||||
@@ -350,6 +284,11 @@ def _print_sanity_report(
|
||||
round(100 * len(m_pp) / total), len(m_pp), total
|
||||
)
|
||||
)
|
||||
print(
|
||||
'{}% ({}/{}) of instruction forms have an invalid port identifier.'.format(
|
||||
round(100 * len(wrong_pp) / total), len(wrong_pp), total
|
||||
)
|
||||
)
|
||||
print(
|
||||
'{}% ({}/{}) of instruction forms might miss an ISA DB entry.'.format(
|
||||
round(100 * len(suspic_instr) / total), len(suspic_instr), total
|
||||
@@ -365,12 +304,12 @@ def _print_sanity_report(
|
||||
# verbose version
|
||||
if verbose:
|
||||
_print_sanity_report_verbose(
|
||||
total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa
|
||||
total, m_tp, m_l, m_pp, wrong_pp, suspic_instr, dup_arch, dup_isa, only_isa
|
||||
)
|
||||
|
||||
|
||||
def _print_sanity_report_verbose(
|
||||
total, m_tp, m_l, m_pp, suspic_instr, dup_arch, dup_isa, only_isa
|
||||
total, m_tp, m_l, m_pp, wrong_pp, suspic_instr, dup_arch, dup_isa, only_isa
|
||||
):
|
||||
BRIGHT_CYAN = '\033[1;36;1m'
|
||||
BRIGHT_BLUE = '\033[1;34;1m'
|
||||
@@ -392,6 +331,14 @@ def _print_sanity_report_verbose(
|
||||
)
|
||||
for instr_form in m_pp:
|
||||
print('{}{}{}'.format(BRIGHT_MAGENTA, _get_full_instruction_name(instr_form), WHITE))
|
||||
print(
|
||||
'Instruction forms with invalid port identifiers in port pressure:\n'
|
||||
if len(wrong_pp) != 0
|
||||
else '',
|
||||
end='',
|
||||
)
|
||||
for instr_form in wrong_pp:
|
||||
print('{}{}{}'.format(BRIGHT_MAGENTA, _get_full_instruction_name(instr_form), WHITE))
|
||||
print(
|
||||
'Instruction forms which might miss an ISA DB entry:\n' if len(suspic_instr) != 0 else '',
|
||||
end='',
|
||||
|
||||
@@ -20,7 +20,7 @@ class Frontend(object):
|
||||
self._arch = arch
|
||||
if arch:
|
||||
self._arch = arch.lower()
|
||||
with open(utils.find_file(self._arch+'.yml'), 'r') as f:
|
||||
with open(utils.find_file(self._arch + '.yml'), 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
elif path_to_yaml:
|
||||
with open(path_to_yaml, 'r') as f:
|
||||
|
||||
@@ -7,6 +7,7 @@ import re
|
||||
import sys
|
||||
from filecmp import dircmp
|
||||
from subprocess import call
|
||||
import warnings
|
||||
|
||||
from osaca.db_interface import sanity_check, import_benchmark_output
|
||||
from osaca.frontend import Frontend
|
||||
@@ -58,7 +59,7 @@ def create_parser():
|
||||
parser.add_argument(
|
||||
'--arch',
|
||||
type=str,
|
||||
help='Define architecture (SNB, IVB, HSW, BDW, SKX, CSX, ZEN1, VULCAN).',
|
||||
help='Define architecture (SNB, IVB, HSW, BDW, SKX, CSX, ZEN1, TX2).',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--db-check',
|
||||
@@ -105,7 +106,7 @@ def create_parser():
|
||||
|
||||
def check_arguments(args, parser):
|
||||
"""Check arguments passed by user that are not checked by argparse itself."""
|
||||
supported_archs = ['SNB', 'IVB', 'HSW', 'BDW', 'SKX', 'CSX', 'ZEN1', 'VULCAN']
|
||||
supported_archs = ['SNB', 'IVB', 'HSW', 'BDW', 'SKX', 'CSX', 'ZEN1', 'TX2']
|
||||
supported_import_files = ['ibench', 'asmbench', 'uopsinfo']
|
||||
|
||||
if 'arch' in args and args.arch.upper() not in supported_archs:
|
||||
@@ -124,18 +125,8 @@ def check_user_dir():
|
||||
if not os.path.isdir(DATA_DIR):
|
||||
os.makedirs(DATA_DIR)
|
||||
for f in os.listdir(MODULE_DATA_DIR):
|
||||
if not os.path.exists(os.path.join(DATA_DIR, f)):
|
||||
if f.endswith('yml') and not os.path.exists(os.path.join(DATA_DIR, f)):
|
||||
call(['cp', '-r', os.path.join(MODULE_DATA_DIR, f), DATA_DIR])
|
||||
else:
|
||||
# Compare and warn if files in DATA_DIR are different
|
||||
dir_comp = dircmp(DATA_DIR, MODULE_DATA_DIR)
|
||||
if dir_comp.left_list != dir_comp.same_files:
|
||||
print(
|
||||
"WARNING: Files in {} differs from {}. Check or delete {}.".format(
|
||||
MODULE_DATA_DIR, DATA_DIR, DATA_DIR
|
||||
),
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
|
||||
def import_data(benchmark_type, arch, filepath):
|
||||
|
||||
@@ -8,4 +8,12 @@ from .base_parser import BaseParser
|
||||
from .parser_x86att import ParserX86ATT
|
||||
from .parser_AArch64v81 import ParserAArch64v81
|
||||
|
||||
__all__ = ['AttrDict', 'BaseParser', 'ParserX86ATT', 'ParserAArch64v81']
|
||||
__all__ = ['AttrDict', 'BaseParser', 'ParserX86ATT', 'ParserAArch64v81', 'get_parser']
|
||||
|
||||
def get_parser(isa):
|
||||
if isa.lower() == 'x86':
|
||||
return ParserX86ATT()
|
||||
elif isa.lower() == 'aarch64':
|
||||
return ParserAArch64v81()
|
||||
else:
|
||||
raise ValueError("Unknown ISA {!r}.".format(isa))
|
||||
|
||||
@@ -32,7 +32,7 @@ class ParserX86ATT(BaseParser):
|
||||
identifier.setResultsName('name') + pp.Literal(':') + pp.Optional(self.comment)
|
||||
).setResultsName(self.LABEL_ID)
|
||||
# Register: pp.Regex('^%[0-9a-zA-Z]+,?')
|
||||
register = pp.Group(
|
||||
self.register = pp.Group(
|
||||
pp.Literal('%')
|
||||
+ pp.Word(pp.alphanums).setResultsName('name')
|
||||
+ pp.Optional(
|
||||
@@ -55,9 +55,9 @@ class ParserX86ATT(BaseParser):
|
||||
memory = pp.Group(
|
||||
pp.Optional(offset.setResultsName('offset'))
|
||||
+ pp.Literal('(')
|
||||
+ pp.Optional(register.setResultsName('base'))
|
||||
+ pp.Optional(self.register.setResultsName('base'))
|
||||
+ pp.Optional(pp.Suppress(pp.Literal(',')))
|
||||
+ pp.Optional(register.setResultsName('index'))
|
||||
+ pp.Optional(self.register.setResultsName('index'))
|
||||
+ pp.Optional(pp.Suppress(pp.Literal(',')))
|
||||
+ pp.Optional(scale.setResultsName('scale'))
|
||||
+ pp.Literal(')')
|
||||
@@ -67,8 +67,8 @@ class ParserX86ATT(BaseParser):
|
||||
directive_option = pp.Combine(
|
||||
pp.Word('#@.', exact=1) + pp.Word(pp.printables, excludeChars=',')
|
||||
)
|
||||
directive_parameter = (
|
||||
pp.quotedString | directive_option | identifier | hex_number | decimal_number | register
|
||||
directive_parameter = (pp.quotedString | directive_option | identifier | hex_number |
|
||||
decimal_number | self.register
|
||||
)
|
||||
commaSeparatedList = pp.delimitedList(pp.Optional(directive_parameter), delim=',')
|
||||
self.directive = pp.Group(
|
||||
@@ -84,8 +84,8 @@ class ParserX86ATT(BaseParser):
|
||||
pp.alphanums
|
||||
).setResultsName('mnemonic')
|
||||
# Combine to instruction form
|
||||
operand_first = pp.Group(register ^ immediate ^ memory ^ identifier)
|
||||
operand_rest = pp.Group(register ^ immediate ^ memory)
|
||||
operand_first = pp.Group(self.register ^ immediate ^ memory ^ identifier)
|
||||
operand_rest = pp.Group(self.register ^ immediate ^ memory)
|
||||
self.instruction_parser = (
|
||||
mnemonic
|
||||
+ pp.Optional(operand_first.setResultsName('operand1'))
|
||||
@@ -99,19 +99,9 @@ class ParserX86ATT(BaseParser):
|
||||
)
|
||||
|
||||
def parse_register(self, register_string):
|
||||
register = pp.Group(
|
||||
pp.Literal('%')
|
||||
+ pp.Word(pp.alphanums).setResultsName('name')
|
||||
+ pp.Optional(
|
||||
pp.Literal('{')
|
||||
+ pp.Literal('%')
|
||||
+ pp.Word(pp.alphanums).setResultsName('mask')
|
||||
+ pp.Literal('}')
|
||||
)
|
||||
).setResultsName(self.REGISTER_ID)
|
||||
try:
|
||||
return self.process_operand(
|
||||
register.parseString(register_string, parseAll=True).asDict()
|
||||
self.register.parseString(register_string, parseAll=True).asDict()
|
||||
)
|
||||
except pp.ParseException:
|
||||
return None
|
||||
|
||||
@@ -1,29 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
from copy import deepcopy
|
||||
from itertools import product
|
||||
|
||||
from ruamel import yaml
|
||||
import ruamel.yaml
|
||||
from ruamel.yaml.compat import StringIO
|
||||
|
||||
from osaca import utils
|
||||
from osaca import __version__, utils
|
||||
from osaca.parser import ParserX86ATT
|
||||
|
||||
|
||||
class MachineModel(object):
|
||||
def __init__(self, arch=None, path_to_yaml=None):
|
||||
def __init__(self, arch=None, path_to_yaml=None, isa=None):
|
||||
if not arch and not path_to_yaml:
|
||||
raise ValueError('Either arch or path_to_yaml required.')
|
||||
if arch and path_to_yaml:
|
||||
raise ValueError('Only one of arch and path_to_yaml is allowed.')
|
||||
self._path = path_to_yaml
|
||||
self._arch = arch
|
||||
if arch:
|
||||
self._arch = arch.lower()
|
||||
with open(utils.find_file(self._arch+'.yml'), 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
elif path_to_yaml:
|
||||
with open(self._path, 'r') as f:
|
||||
self._data = yaml.load(f, Loader=yaml.Loader)
|
||||
if not isa:
|
||||
raise ValueError('One of arch, path_to_yaml and isa must be specified')
|
||||
self._data = {
|
||||
'osaca_version': str(__version__),
|
||||
'micro_architecture': None,
|
||||
'arch_code': None,
|
||||
'isa': isa,
|
||||
'ROB_size': None,
|
||||
'retired_uOps_per_cycle': None,
|
||||
'scheduler_size': None,
|
||||
'hidden_loads': None,
|
||||
'load_latency': {},
|
||||
'load_throughput': [
|
||||
{'base': b, 'index': i, 'offset': o, 'scale': s, 'port_pressure': []}
|
||||
for b, i, o, s in product(['gpr'], ['gpr', None], ['imd', None], [1, 8])
|
||||
],
|
||||
'ports': [],
|
||||
'port_model_scheme': None,
|
||||
'instruction_forms': [],
|
||||
}
|
||||
else:
|
||||
if arch and path_to_yaml:
|
||||
raise ValueError('Only one of arch and path_to_yaml is allowed.')
|
||||
self._path = path_to_yaml
|
||||
self._arch = arch
|
||||
yaml = self._create_yaml_object()
|
||||
if arch:
|
||||
self._arch = arch.lower()
|
||||
with open(utils.find_file(self._arch + '.yml'), 'r') as f:
|
||||
self._data = yaml.load(f)
|
||||
elif path_to_yaml:
|
||||
with open(self._path, 'r') as f:
|
||||
self._data = yaml.load(f)
|
||||
|
||||
def __getitem__(self, key):
|
||||
"""Return configuration entry."""
|
||||
@@ -36,26 +59,67 @@ class MachineModel(object):
|
||||
######################################################
|
||||
|
||||
def get_instruction(self, name, operands):
|
||||
"""Find and return instruction data from name and operands."""
|
||||
if name is None:
|
||||
return None
|
||||
try:
|
||||
return next(
|
||||
instruction_form
|
||||
for instruction_form in self._data['instruction_forms']
|
||||
if instruction_form['name'].lower() == name.lower()
|
||||
if instruction_form['name'].upper() == name.upper()
|
||||
and self._match_operands(instruction_form['operands'], operands)
|
||||
)
|
||||
except StopIteration:
|
||||
return None
|
||||
except TypeError:
|
||||
except TypeError as e:
|
||||
print('\nname: {}\noperands: {}'.format(name, operands))
|
||||
raise TypeError
|
||||
raise TypeError from e
|
||||
|
||||
def average_port_pressure(self, port_pressure):
|
||||
"""Construct average port pressure list from instruction data."""
|
||||
port_list = self._data['ports']
|
||||
average_pressure = [0.0] * len(port_list)
|
||||
for cycles, ports in port_pressure:
|
||||
for p in ports:
|
||||
average_pressure[port_list.index(p)] += cycles / len(ports)
|
||||
return average_pressure
|
||||
|
||||
def set_instruction(
|
||||
self, name, operands=None, latency=None, port_pressure=None, throughput=None, uops=None
|
||||
):
|
||||
"""Import instruction form information."""
|
||||
# If it already exists. Overwrite information.
|
||||
instr_data = self.get_instruction(name, operands)
|
||||
if instr_data is None:
|
||||
instr_data = {}
|
||||
self._data['instruction_forms'].append(instr_data)
|
||||
|
||||
instr_data['name'] = name
|
||||
instr_data['operands'] = operands
|
||||
instr_data['latency'] = latency
|
||||
instr_data['port_pressure'] = port_pressure
|
||||
instr_data['throughput'] = throughput
|
||||
instr_data['uops'] = uops
|
||||
|
||||
def set_instruction_entry(self, entry):
|
||||
self.set_instruction(
|
||||
entry['name'],
|
||||
entry['operands'] if 'operands' in entry else None,
|
||||
entry['latency'] if 'latency' in entry else None,
|
||||
entry['port_pressure'] if 'port_pressure' in entry else None,
|
||||
entry['throughput'] if 'throughput' in entry else None,
|
||||
entry['uops'] if 'uops' in entry else None,
|
||||
)
|
||||
|
||||
def add_port(self, port):
|
||||
if port not in self._data['ports']:
|
||||
self._data['ports'].append(port)
|
||||
|
||||
def get_ISA(self):
|
||||
return self._data['isa']
|
||||
return self._data['isa'].lower()
|
||||
|
||||
def get_arch(self):
|
||||
return self._data['arch_code']
|
||||
return self._data['arch_code'].lower()
|
||||
|
||||
def get_ports(self):
|
||||
return self._data['ports']
|
||||
@@ -85,10 +149,21 @@ class MachineModel(object):
|
||||
data_ports = [x for x in filter(data_port.match, self._data['ports'])]
|
||||
return data_ports
|
||||
|
||||
@staticmethod
|
||||
def get_full_instruction_name(instruction_form):
|
||||
operands = []
|
||||
for op in instruction_form['operands']:
|
||||
op_attrs = [
|
||||
y + ':' + str(op[y])
|
||||
for y in list(filter(lambda x: True if x != 'class' else False, op))
|
||||
]
|
||||
operands.append('{}({})'.format(op['class'], ','.join(op_attrs)))
|
||||
return '{} {}'.format(instruction_form['name'], ','.join(operands))
|
||||
|
||||
@staticmethod
|
||||
def get_isa_for_arch(arch):
|
||||
arch_dict = {
|
||||
'vulcan': 'aarch64',
|
||||
'tx2': 'aarch64',
|
||||
'zen1': 'x86',
|
||||
'snb': 'x86',
|
||||
'ivb': 'x86',
|
||||
@@ -97,11 +172,39 @@ class MachineModel(object):
|
||||
'skl': 'x86',
|
||||
'skx': 'x86',
|
||||
'csx': 'x86',
|
||||
'wsm': 'x86',
|
||||
'nhm': 'x86',
|
||||
'kbl': 'x86',
|
||||
'cnl': 'x86',
|
||||
'cfl': 'x86',
|
||||
'zen+': 'x86',
|
||||
}
|
||||
arch = arch.lower()
|
||||
if arch in arch_dict:
|
||||
return arch_dict[arch].lower()
|
||||
return None
|
||||
else:
|
||||
raise ValueError("Unknown architecture {!r}.".format(arch))
|
||||
|
||||
def dump(self, stream=None):
|
||||
# Replace instruction form's port_pressure with styled version for RoundtripDumper
|
||||
formatted_instruction_forms = deepcopy(self._data['instruction_forms'])
|
||||
for instruction_form in formatted_instruction_forms:
|
||||
cs = ruamel.yaml.comments.CommentedSeq(instruction_form['port_pressure'])
|
||||
cs.fa.set_flow_style()
|
||||
instruction_form['port_pressure'] = cs
|
||||
|
||||
# Create YAML object
|
||||
yaml = self._create_yaml_object()
|
||||
if not stream:
|
||||
# Create stream object to output string
|
||||
stream = StringIO()
|
||||
yaml.dump({k: v for k, v in self._data.items() if k != 'instruction_forms'}, stream)
|
||||
yaml.dump({'instruction_forms': formatted_instruction_forms}, stream)
|
||||
return stream.getvalue()
|
||||
else:
|
||||
# Write in given stream
|
||||
yaml.dump({k: v for k, v in self._data.items() if k != 'instruction_forms'}, stream)
|
||||
yaml.dump({'instruction_forms': formatted_instruction_forms}, stream)
|
||||
|
||||
######################################################
|
||||
|
||||
@@ -288,3 +391,14 @@ class MachineModel(object):
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _create_yaml_object(self):
|
||||
yaml_obj = ruamel.yaml.YAML()
|
||||
yaml_obj.representer.add_representer(type(None), self.__represent_none)
|
||||
yaml_obj.default_flow_style = None
|
||||
yaml_obj.width = 120
|
||||
yaml_obj.representer.ignore_aliases = lambda *args: True
|
||||
return yaml_obj
|
||||
|
||||
def __represent_none(self, yaml_obj, data):
|
||||
return yaml_obj.represent_scalar(u'tag:yaml.org,2002:null', u'~')
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import warnings
|
||||
from functools import reduce
|
||||
|
||||
@@ -27,7 +26,7 @@ class SemanticsAppender(object):
|
||||
def __init__(self, machine_model: MachineModel, path_to_yaml=None):
|
||||
self._machine_model = machine_model
|
||||
self._isa = machine_model.get_ISA().lower()
|
||||
path = utils.find_file('isa/'+self._isa+'.yml')
|
||||
path = utils.find_file('isa/' + self._isa + '.yml')
|
||||
self._isa_model = MachineModel(path_to_yaml=path)
|
||||
if self._isa == 'x86':
|
||||
self._parser = ParserX86ATT()
|
||||
@@ -98,7 +97,9 @@ class SemanticsAppender(object):
|
||||
if instruction_data:
|
||||
# instruction form in DB
|
||||
throughput = instruction_data['throughput']
|
||||
port_pressure = instruction_data['port_pressure']
|
||||
port_pressure = self._machine_model.average_port_pressure(
|
||||
instruction_data['port_pressure']
|
||||
)
|
||||
try:
|
||||
assert isinstance(port_pressure, list)
|
||||
assert len(port_pressure) == port_number
|
||||
@@ -143,12 +144,14 @@ class SemanticsAppender(object):
|
||||
for op in operands['operand_list']
|
||||
if 'register' in op
|
||||
]
|
||||
load_port_pressure = self._machine_model.get_load_throughput(
|
||||
[
|
||||
x['memory']
|
||||
for x in instruction_form['operands']['source']
|
||||
if 'memory' in x
|
||||
][0]
|
||||
load_port_pressure = self._machine_model.average_port_pressure(
|
||||
self._machine_model.get_load_throughput(
|
||||
[
|
||||
x['memory']
|
||||
for x in instruction_form['operands']['source']
|
||||
if 'memory' in x
|
||||
][0]
|
||||
)
|
||||
)
|
||||
if 'load_throughput_multiplier' in self._machine_model:
|
||||
multiplier = self._machine_model['load_throughput_multiplier'][
|
||||
@@ -165,7 +168,12 @@ class SemanticsAppender(object):
|
||||
latency_wo_load = instruction_data_reg['latency']
|
||||
instruction_form['port_pressure'] = [
|
||||
sum(x)
|
||||
for x in zip(load_port_pressure, instruction_data_reg['port_pressure'])
|
||||
for x in zip(
|
||||
load_port_pressure,
|
||||
self._machine_model.average_port_pressure(
|
||||
instruction_data_reg['port_pressure']
|
||||
),
|
||||
)
|
||||
]
|
||||
if assign_unknown:
|
||||
# --> mark as unknown and assume 0 cy for latency/throughput
|
||||
@@ -311,14 +319,14 @@ class SemanticsAppender(object):
|
||||
def _get_regular_source_x86ATT(self, instruction_form):
|
||||
# return all but last operand
|
||||
sources = [
|
||||
op for op in instruction_form['operands'][0:len(instruction_form['operands']) - 1]
|
||||
op for op in instruction_form['operands'][0 : len(instruction_form['operands']) - 1]
|
||||
]
|
||||
return sources
|
||||
|
||||
def _get_regular_source_AArch64(self, instruction_form):
|
||||
# return all but first operand
|
||||
sources = [
|
||||
op for op in instruction_form['operands'][1:len(instruction_form['operands'])]
|
||||
op for op in instruction_form['operands'][1 : len(instruction_form['operands'])]
|
||||
]
|
||||
return sources
|
||||
|
||||
|
||||
@@ -3,12 +3,9 @@
|
||||
Unit tests for DB interface
|
||||
"""
|
||||
|
||||
import copy
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from osaca.db_interface import add_entries_to_db, add_entry_to_db, sanity_check
|
||||
from osaca.db_interface import sanity_check
|
||||
from osaca.semantics import MachineModel
|
||||
|
||||
|
||||
@@ -26,90 +23,57 @@ class TestDBInterface(unittest.TestCase):
|
||||
'uops': 6,
|
||||
}
|
||||
self.entry_csx = sample_entry.copy()
|
||||
self.entry_vulcan = sample_entry.copy()
|
||||
self.entry_tx2 = sample_entry.copy()
|
||||
self.entry_zen1 = sample_entry.copy()
|
||||
|
||||
self.entry_csx['port_pressure'] = [1.25, 0, 1.25, 0.5, 0.5, 0.5, 0.5, 0, 1.25, 1.25, 0]
|
||||
self.entry_vulcan['port_pressure'] = [2.5, 2.5, 0, 0, 0.5, 0.5]
|
||||
del self.entry_vulcan['operands'][1]['name']
|
||||
self.entry_vulcan['operands'][1]['prefix'] = 'x'
|
||||
self.entry_zen1['port_pressure'] = [1, 1, 1, 1, 0, 1, 0, 0, 0, 0.5, 1, 0.5, 1]
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
if sys.exc_info() == (None, None, None):
|
||||
# Test successful, remove DB entries
|
||||
test_archs = {'csx': 54, 'vulcan': 57, 'zen1': 58}
|
||||
for arch in test_archs:
|
||||
lines = []
|
||||
with open(os.path.expanduser('~/.osaca/data/' + arch + '.yml'), 'r') as f:
|
||||
lines = f.readlines()
|
||||
with open(os.path.expanduser('~/.osaca/data/' + arch + '.yml'), 'w') as f:
|
||||
f.writelines([line for line in lines[:-1 * test_archs[arch]]])
|
||||
# self.entry_csx['port_pressure'] = [1.25, 0, 1.25, 0.5, 0.5, 0.5, 0.5, 0, 1.25, 1.25, 0]
|
||||
self.entry_csx['port_pressure'] = [[5, '0156'], [1, '23'], [1, ['2D', '3D']]]
|
||||
# self.entry_tx2['port_pressure'] = [2.5, 2.5, 0, 0, 0.5, 0.5]
|
||||
self.entry_tx2['port_pressure'] = [[5, '01'], [1, '45']]
|
||||
del self.entry_tx2['operands'][1]['name']
|
||||
self.entry_tx2['operands'][1]['prefix'] = 'x'
|
||||
# self.entry_zen1['port_pressure'] = [1, 1, 1, 1, 0, 1, 0, 0, 0, 0.5, 1, 0.5, 1]
|
||||
self.entry_zen1['port_pressure'] = [[4, '0123'], [1, '4'], [1, '89'], [2, ['8D', '9D']]]
|
||||
|
||||
###########
|
||||
# Tests
|
||||
###########
|
||||
|
||||
def test_add_single_entry(self):
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms'])
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms'])
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms'])
|
||||
mm_csx = MachineModel('csx')
|
||||
mm_tx2 = MachineModel('tx2')
|
||||
mm_zen1 = MachineModel('zen1')
|
||||
num_entries_csx = len(mm_csx['instruction_forms'])
|
||||
num_entries_tx2 = len(mm_tx2['instruction_forms'])
|
||||
num_entries_zen1 = len(mm_zen1['instruction_forms'])
|
||||
|
||||
add_entry_to_db('csx', self.entry_csx)
|
||||
add_entry_to_db('vulcan', self.entry_vulcan)
|
||||
add_entry_to_db('zen1', {'name': 'empty_operation'})
|
||||
mm_csx.set_instruction_entry(self.entry_csx)
|
||||
mm_tx2.set_instruction_entry(self.entry_tx2)
|
||||
mm_zen1.set_instruction_entry({'name': 'empty_operation'})
|
||||
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms']) - num_entries_csx
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms']) - num_entries_vulcan
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms']) - num_entries_zen1
|
||||
num_entries_csx = len(mm_csx['instruction_forms']) - num_entries_csx
|
||||
num_entries_tx2 = len(mm_tx2['instruction_forms']) - num_entries_tx2
|
||||
num_entries_zen1 = len(mm_zen1['instruction_forms']) - num_entries_zen1
|
||||
|
||||
self.assertEqual(num_entries_csx, 1)
|
||||
self.assertEqual(num_entries_vulcan, 1)
|
||||
self.assertEqual(num_entries_tx2, 1)
|
||||
self.assertEqual(num_entries_zen1, 1)
|
||||
|
||||
def test_invalid_add(self):
|
||||
entry = {}
|
||||
with self.assertRaises(ValueError):
|
||||
add_entry_to_db('csx', entry)
|
||||
add_entries_to_db('csx', [entry])
|
||||
|
||||
def test_add_multiple_entries(self):
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms'])
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms'])
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms'])
|
||||
|
||||
entries_csx, entries_vulcan, entries_zen1 = [], [], []
|
||||
for i in range(2):
|
||||
self.entry_csx['name'] += '-'
|
||||
self.entry_vulcan['name'] += '-'
|
||||
self.entry_zen1['name'] += '-'
|
||||
entries_csx.append(copy.deepcopy(self.entry_csx))
|
||||
entries_vulcan.append(copy.deepcopy(self.entry_vulcan))
|
||||
entries_zen1.append(copy.deepcopy(self.entry_zen1))
|
||||
|
||||
entries_csx[1] = {'name': entries_csx[1]['name']}
|
||||
|
||||
add_entries_to_db('csx', entries_csx)
|
||||
add_entries_to_db('vulcan', entries_vulcan)
|
||||
add_entries_to_db('zen1', entries_zen1)
|
||||
|
||||
num_entries_csx = len(MachineModel('csx')['instruction_forms']) - num_entries_csx
|
||||
num_entries_vulcan = len(MachineModel('vulcan')['instruction_forms']) - num_entries_vulcan
|
||||
num_entries_zen1 = len(MachineModel('zen1')['instruction_forms']) - num_entries_zen1
|
||||
|
||||
self.assertEqual(num_entries_csx, 2)
|
||||
self.assertEqual(num_entries_vulcan, 2)
|
||||
self.assertEqual(num_entries_zen1, 2)
|
||||
with self.assertRaises(KeyError):
|
||||
MachineModel('csx').set_instruction_entry(entry)
|
||||
with self.assertRaises(TypeError):
|
||||
MachineModel('csx').set_instruction()
|
||||
|
||||
def test_sanity_check(self):
|
||||
# non-verbose
|
||||
sanity_check('csx', verbose=False)
|
||||
sanity_check('vulcan', verbose=False)
|
||||
sanity_check('tx2', verbose=False)
|
||||
sanity_check('zen1', verbose=False)
|
||||
# verbose
|
||||
sanity_check('csx', verbose=True)
|
||||
sanity_check('vulcan', verbose=True)
|
||||
sanity_check('tx2', verbose=True)
|
||||
sanity_check('zen1', verbose=True)
|
||||
|
||||
##################
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,7 +35,7 @@ class TestFrontend(unittest.TestCase):
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'csx.yml')
|
||||
)
|
||||
self.machine_model_tx2 = MachineModel(
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'vulcan.yml')
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'tx2.yml')
|
||||
)
|
||||
self.semantics_csx = SemanticsAppender(
|
||||
self.machine_model_csx, path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'isa/x86.yml')
|
||||
@@ -74,7 +74,7 @@ class TestFrontend(unittest.TestCase):
|
||||
|
||||
def test_frontend_AArch64(self):
|
||||
dg = KernelDG(self.kernel_AArch64, self.parser_AArch64, self.machine_model_tx2)
|
||||
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'vulcan.yml'))
|
||||
fe = Frontend(path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'tx2.yml'))
|
||||
fe.print_full_analysis(self.kernel_AArch64, dg, verbose=True)
|
||||
|
||||
##################
|
||||
|
||||
@@ -52,7 +52,7 @@ class TestKerncraftAPI(unittest.TestCase):
|
||||
self.assertEqual(kapi.get_latency(), (1.0, 13.0))
|
||||
|
||||
def test_kerncraft_API_AArch64(self):
|
||||
kapi = KerncraftAPI('vulcan', self.code_AArch64)
|
||||
kapi = KerncraftAPI('tx2', self.code_AArch64)
|
||||
|
||||
kapi.create_output()
|
||||
self.assertEqual(kapi.get_unmatched_instruction_ratio(), 0.0)
|
||||
|
||||
@@ -41,7 +41,7 @@ class TestSemanticTools(unittest.TestCase):
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'csx.yml')
|
||||
)
|
||||
self.machine_model_tx2 = MachineModel(
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'vulcan.yml')
|
||||
path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'tx2.yml')
|
||||
)
|
||||
self.semantics_csx = SemanticsAppender(
|
||||
self.machine_model_csx, path_to_yaml=os.path.join(self.MODULE_DATA_DIR, 'isa/x86.yml')
|
||||
@@ -204,7 +204,8 @@ class TestSemanticTools(unittest.TestCase):
|
||||
)
|
||||
self.assertEqual(len(lc_deps[lcd_id2]['dependencies']), 1)
|
||||
self.assertEqual(
|
||||
lc_deps[lcd_id2]['dependencies'][0], dg.dg.nodes(data=True)[lcd_id2]['instruction_form']
|
||||
lc_deps[lcd_id2]['dependencies'][0],
|
||||
dg.dg.nodes(data=True)[lcd_id2]['instruction_form'],
|
||||
)
|
||||
|
||||
def test_is_read_is_written_x86(self):
|
||||
@@ -323,11 +324,11 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.assertIsNone(self.machine_model_csx.get_instruction('GETRESULT', sample_operands))
|
||||
self.assertIsNone(self.machine_model_tx2.get_instruction('GETRESULT', sample_operands))
|
||||
|
||||
self.assertEqual(self.machine_model_csx.get_arch(), 'CSX')
|
||||
self.assertEqual(self.machine_model_tx2.get_arch(), 'Vulcan')
|
||||
self.assertEqual(self.machine_model_csx.get_arch(), 'csx')
|
||||
self.assertEqual(self.machine_model_tx2.get_arch(), 'tx2')
|
||||
|
||||
self.assertEqual(self.machine_model_csx.get_ISA(), 'x86')
|
||||
self.assertEqual(self.machine_model_tx2.get_ISA(), 'AArch64')
|
||||
self.assertEqual(self.machine_model_tx2.get_ISA(), 'aarch64')
|
||||
|
||||
ports_csx = ['0', '0DV', '1', '2', '2D', '3', '3D', '4', '5', '6', '7']
|
||||
data_ports_csx = ['2D', '3D']
|
||||
@@ -337,8 +338,9 @@ class TestSemanticTools(unittest.TestCase):
|
||||
self.assertFalse(self.machine_model_tx2.has_hidden_loads())
|
||||
|
||||
self.assertEqual(MachineModel.get_isa_for_arch('CSX'), 'x86')
|
||||
self.assertEqual(MachineModel.get_isa_for_arch('VuLcAn'), 'aarch64')
|
||||
self.assertIsNone(MachineModel.get_isa_for_arch('THE_MACHINE'))
|
||||
self.assertEqual(MachineModel.get_isa_for_arch('tX2'), 'aarch64')
|
||||
with self.assertRaises(ValueError):
|
||||
self.assertIsNone(MachineModel.get_isa_for_arch('THE_MACHINE'))
|
||||
|
||||
##################
|
||||
# Helper functions
|
||||
|
||||
Reference in New Issue
Block a user