Merge pull request #43 from RRZE-HPC/non_average_port_model

Non average port model
This commit is contained in:
Jan
2019-10-16 10:39:02 +02:00
committed by GitHub
17 changed files with 2595 additions and 2739 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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
View 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']]

View File

@@ -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]

File diff suppressed because it is too large Load Diff

View File

@@ -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='',

View File

@@ -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:

View File

@@ -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):

View File

@@ -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))

View File

@@ -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

View File

@@ -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'~')

View File

@@ -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

View File

@@ -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

View File

@@ -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)
##################

View File

@@ -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)

View File

@@ -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