new stencil generator added

This commit is contained in:
Nicolas Kruse 2025-09-11 22:22:17 +02:00
parent deb02829b2
commit 086cdfea8d
6 changed files with 336 additions and 28 deletions

3
.gitignore vendored
View File

@ -8,4 +8,5 @@ __pycache__
.mypy_cache
.pytest_cache
tests/autogenerated_*.py
*test*.o
*test*.o
/src/copapy/obj/ops*.o

View File

@ -1,18 +0,0 @@
cff-version: 1.2.0
title: Gaspype
abstract: Gaspype is a performant library for thermodynamic calculations with ideal gases
authors:
- family-names: Kruse
given-names: Nicolas
orcid: "https://orcid.org/0000-0001-6758-2269"
affiliation: "German Aerospace Center (DLR)"
address: "Linder Höhe"
city: Köln
version: 1.0.1
date-released: "2025-05-09"
#identifiers:
# - description: This is the collection of archived snapshots of all versions of Gaspype
# type: doi
# value: ""
license: MIT License
repository-code: "https://github.com/DLR-Institute-of-Future-Fuels/gaspype"

View File

@ -1,5 +1,7 @@
#!/bin/bash
set -e
set -v
python src/copapy/generate_stancils.py
mkdir -p src/copapy/obj
gcc -c src/copapy/ops.c -o src/copapy/obj/ops_x86_64.o
gcc -c src/copapy/stancils.c -o src/copapy/obj/stancils_x86_64.o
ls -l src/copapy/obj/*.o

View File

@ -10,15 +10,17 @@ def get_var_name(var: Any, scope: dict[str, Any] = globals()) -> list[str]:
def _get_c_function_definitions(code: str) -> dict[str, str]:
ret = re.findall(r".*?void\s+([a-z_1-9]*)\s*\([^\)]*?\)[^\}]*?\{[^\}]*?result_([a-z_]*)\(.*?", code, flags=re.S)
ret = re.findall(r".*?void\s+([a-z_0-9]*)\s*\([^\)]*?\)[^\}]*?\{[^\}]*?result_([a-z_]*)\(.*?", code, flags=re.S)
return {r[0]: r[1] for r in ret}
_ccode = pkgutil.get_data(__name__, 'ops.c')
_ccode = pkgutil.get_data(__name__, 'stancils.c')
assert _ccode is not None
_function_definitions = _get_c_function_definitions(_ccode.decode('utf-8'))
print(_function_definitions)
class Node:
def __init__(self):
self.args: list[Net] = []
@ -105,7 +107,7 @@ def _add_op(op: str, args: list[Any], commutative: bool = False) -> Net:
if typed_op not in _function_definitions:
raise ValueError(f"Unsupported operand type(s) for {op}: {' and '.join([a.dtype for a in arg_nets])}")
result_type = _function_definitions[typed_op]
result_type = _function_definitions[typed_op].split('_')[0]
result_net = Net(result_type, Op(typed_op, arg_nets))
@ -224,7 +226,7 @@ def add_read_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], No
Returns:
Yields a tuples of a net and a operation. The net is the result net
from the returned operation"""
registers: list[None | Net] = [None] * 16
registers: list[None | Net] = [None] * 2
net_lookup = {net.source: net for node in node_list for net in node.args}
@ -234,7 +236,9 @@ def add_read_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], No
if net != registers[i]:
#if net in registers:
# print('x swap registers')
new_node = Op('read_reg' + str(i) + '_' + net.dtype, [])
type_list = ['int' if r is None else r.dtype for r in registers]
print(type_list)
new_node = Op('read_reg' + str(i) + '_' + '_'.join(type_list), [])
yield net, new_node
registers[i] = net
@ -273,7 +277,7 @@ def compile_to_instruction_list(end_nodes: Iterable[Node] | Node) -> binw.data_w
extended_output_ops = list(add_write_ops(output_ops, const_list))
obj_file: str = 'src/copapy/obj/test4_o0.o'
obj_file: str = 'src/copapy/obj/stancils_x86_64.o'
elf = pelfy.open_elf_file(obj_file)
dw = binw.data_writer(elf.byteorder)
@ -305,7 +309,8 @@ def compile_to_instruction_list(end_nodes: Iterable[Node] | Node) -> binw.data_w
print(list(prototype_functions.keys()))
for net, node in extended_output_ops:
if node.name in prototype_functions:
print(prototype_functions[node.name])
#print(prototype_functions[node.name])
pass
else: print(f"- Warning: {node.name} prototype not found")
print('-----')

View File

@ -0,0 +1,83 @@
from typing import Generator
op_signs = {'add': '+', 'sub': '-', 'mul': '*', 'div': '/'}
def get_op_code(op: str, type1: str, type2: str, type_out: str):
return f"""
void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{
asm volatile (".long 0xF17ECAFE");
result_{type_out}_{type2}(arg1 {op_signs[op]} arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}}
"""
def get_result_stubs(type1: str, type2: str):
return f"""
void result_{type1}_{type2}({type1} arg1, {type2} arg2);
"""
def get_read_reg0_code(type1: str, type2: str, type_out: str):
return f"""
void read_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{
asm volatile (".long 0xF17ECAFE");
result_{type_out}_{type2}(dummy_{type_out}, arg2);
asm volatile (".long 0xF27ECAFE");
}}
"""
def get_read_reg1_code(type1: str, type2: str, type_out: str):
return f"""
void read_reg1_{type1}_{type2}({type1} arg1, {type2} arg2) {{
asm volatile (".long 0xF17ECAFE");
result_{type1}_{type_out}(arg1, dummy_{type_out});
asm volatile (".long 0xF27ECAFE");
}}
"""
def get_write_code(type1: str, type2: str):
return f"""
void write_{type1}_{type2}({type1} arg1, {type2} arg2) {{
asm volatile (".long 0xF17ECAFE");
dummy_{type1} = arg1;
result_{type1}_{type2}(arg1, arg2);
asm volatile (".long 0xF27ECAFE");
}}
"""
def permutate(*lists: list[str]) -> Generator[list[str], None, None]:
if len(lists) == 0:
yield []
return
first, *rest = lists
for item in first:
for items in permutate(*rest):
yield [item, *items]
if __name__ == "__main__":
types = ['int', 'float']
ops = ['add', 'sub', 'mul', 'div']
code = """
// Auto-generated stancils for copapy
// Do not edit manually
volatile int dummy_int = 1337;
volatile float dummy_float = 1337;
"""
for t1, t2 in permutate(types, types):
code += get_result_stubs(t1, t2)
for op, t1, t2 in permutate(ops, types, types):
t_out = t1 if t1 == t2 else 'float'
code += get_op_code(op, t1, t2, t_out)
for t1, t2, t_out in permutate(types, types, types):
code += get_read_reg0_code(t1, t2, t_out)
code += get_read_reg1_code(t1, t2, t_out)
for t1, t2 in permutate(types, types):
code += get_write_code(t1, t2)
with open('src/copapy/stancils.c', 'w') as f:
f.write(code)

235
src/copapy/stancils.c Normal file
View File

@ -0,0 +1,235 @@
// Auto-generated stancils for copapy
// Do not edit manually
volatile int dummy_int = 1337;
volatile float dummy_float = 1337;
void result_int_int(int arg1, int arg2);
void result_int_float(int arg1, float arg2);
void result_float_int(float arg1, int arg2);
void result_float_float(float arg1, float arg2);
void add_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1 + arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void add_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 + arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void add_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1 + arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void add_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 + arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void sub_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1 - arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void sub_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 - arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void sub_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1 - arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void sub_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 - arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void mul_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1 * arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void mul_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 * arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void mul_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1 * arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void mul_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 * arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void div_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1 / arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void div_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 / arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void div_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1 / arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void div_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1 / arg2, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(dummy_int, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1, dummy_int);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(dummy_float, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_float(arg1, dummy_float);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_float(dummy_int, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(arg1, dummy_int);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(dummy_float, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_float(arg1, dummy_float);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_int(dummy_int, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1, dummy_int);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(dummy_float, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1, dummy_float);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_int_float(dummy_int, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_int(arg1, dummy_int);
asm volatile (".long 0xF27ECAFE");
}
void read_reg0_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(dummy_float, arg2);
asm volatile (".long 0xF27ECAFE");
}
void read_reg1_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
result_float_float(arg1, dummy_float);
asm volatile (".long 0xF27ECAFE");
}
void write_int_int(int arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
dummy_int = arg1;
result_int_int(arg1, arg2);
asm volatile (".long 0xF27ECAFE");
}
void write_int_float(int arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
dummy_int = arg1;
result_int_float(arg1, arg2);
asm volatile (".long 0xF27ECAFE");
}
void write_float_int(float arg1, int arg2) {
asm volatile (".long 0xF17ECAFE");
dummy_float = arg1;
result_float_int(arg1, arg2);
asm volatile (".long 0xF27ECAFE");
}
void write_float_float(float arg1, float arg2) {
asm volatile (".long 0xF17ECAFE");
dummy_float = arg1;
result_float_float(arg1, arg2);
asm volatile (".long 0xF27ECAFE");
}