win stancils added

This commit is contained in:
Nicolas 2025-10-07 23:20:43 +02:00
parent a965ab607e
commit c7c3ad3553
13 changed files with 72 additions and 49 deletions

View File

@ -10,7 +10,7 @@ jobs:
build_stencils: build_stencils:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Install cross compilers - name: Install cross compilers
run: | run: |
@ -19,7 +19,8 @@ jobs:
gcc-12-aarch64-linux-gnu \ gcc-12-aarch64-linux-gnu \
gcc-12-arm-linux-gnueabihf \ gcc-12-arm-linux-gnueabihf \
gcc-12-mips-linux-gnu \ gcc-12-mips-linux-gnu \
gcc-12-riscv64-linux-gnu gcc-12-riscv64-linux-gnu \
gcc-12-mingw-w64-x86-64
- name: Build object files - name: Build object files
run: bash src/copapy/obj/crosscompile.sh run: bash src/copapy/obj/crosscompile.sh
@ -38,7 +39,7 @@ jobs:
os: [ubuntu-latest, windows-latest, macos-latest] os: [ubuntu-latest, windows-latest, macos-latest]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- uses: actions/download-artifact@v4 - uses: actions/download-artifact@v4
with: with:

View File

@ -7,7 +7,28 @@ on:
branches: [main] branches: [main]
jobs: jobs:
build_stencils:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install cross compilers
run: |
sudo apt-get update
sudo apt-get install -y \
gcc-12-mingw-w64-x86-64
- name: Build ops obj files
run: |
bash src/copapy/obj/nativecompile.sh
- uses: actions/upload-artifact@v4
with:
name: stencil-object-files
path: src/copapy/obj/*.o
build-ubuntu: build-ubuntu:
needs: [build_stencils]
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@ -18,6 +39,16 @@ jobs:
- name: Check out code - name: Check out code
uses: actions/checkout@v4 uses: actions/checkout@v4
- uses: actions/download-artifact@v4
with:
name: stencil-object-files
path: src/copapy/obj
- name: Install compiler
run: |
sudo apt-get update
sudo apt-get install -y gcc-12-mingw-w64-x86-64
- name: Set up Python ${{ matrix.python-version }} - name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5 uses: actions/setup-python@v5
with: with:
@ -26,25 +57,20 @@ jobs:
- name: Install Python dependencies - name: Install Python dependencies
run: python -m pip install -e .[dev] run: python -m pip install -e .[dev]
- name: Build ops obj files
run: |
bash src/copapy/obj/nativecompile.sh
- name: Compile coparun - name: Compile coparun
run: | run: |
mkdir -p bin mkdir -p bin
gcc -O3 -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -Werror -g src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o bin/coparun gcc -O3 -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -Werror -g src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o bin/coparun
- name: Run tests with pytest
run: pytest
- name: Type checking with mypy
run: mypy
#- name: Lint code with flake8 #- name: Lint code with flake8
# run: flake8 # run: flake8
- name: Upload obj files
uses: actions/upload-artifact@v4
if: strategy.job-index == 0
with:
name: stencil-object-files
path: src/copapy/obj/*.o
- name: Upload compiled runner - name: Upload compiled runner
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
if: strategy.job-index == 0 if: strategy.job-index == 0
@ -52,14 +78,8 @@ jobs:
name: runner-linux name: runner-linux
path: bin/* path: bin/*
- name: Run tests with pytest
run: pytest
- name: Type checking with mypy
run: mypy
build-windows: build-windows:
needs: [build-ubuntu] needs: [build_stencils]
runs-on: windows-latest runs-on: windows-latest
strategy: strategy:

View File

@ -14,14 +14,9 @@ def get_var_name(var: Any, scope: dict[str, Any] = globals()) -> list[str]:
return [name for name, value in scope.items() if value is var] return [name for name, value in scope.items() if value is var]
def get_local_arch() -> str:
arch_translation_table = {'AMD64': 'x86_64'}
return arch_translation_table.get(platform.machine(), platform.machine())
def stencil_db_from_package(arch: str = 'native', optimization: str = 'O3') -> stencil_database: def stencil_db_from_package(arch: str = 'native', optimization: str = 'O3') -> stencil_database:
if arch == 'native': if arch == 'native':
arch = get_local_arch() arch = platform.machine()
stencil_data = pkgutil.get_data(__name__, f"obj/stencils_{arch}_{optimization}.o") stencil_data = pkgutil.get_data(__name__, f"obj/stencils_{arch}_{optimization}.o")
assert stencil_data, f"stencils_{arch}_{optimization} not found" assert stencil_data, f"stencils_{arch}_{optimization} not found"
return stencil_database(stencil_data) return stencil_database(stencil_data)
@ -484,17 +479,16 @@ class Target():
raise ValueError(f"Unsupported int length: {lengths} bytes") raise ValueError(f"Unsupported int length: {lengths} bytes")
else: else:
raise ValueError(f"Unsupported variable type: {var_type}") raise ValueError(f"Unsupported variable type: {var_type}")
def read_variable_remote(self, net: Net) -> None: def read_variable_remote(self, net: Net) -> None:
dw = binw.data_writer(self.sdb.byteorder) dw = binw.data_writer(self.sdb.byteorder)
add_read_command(dw, self._variables, net) add_read_command(dw, self._variables, net)
assert coparun(dw.get_data()) > 0 assert coparun(dw.get_data()) > 0
def add_read_command(dw: binw.data_writer, variables: dict[Net, tuple[int, int, str]], net: Net) -> None: def add_read_command(dw: binw.data_writer, variables: dict[Net, tuple[int, int, str]], net: Net) -> None:
assert net in variables, f"Variable {net} not found in data writer variables" assert net in variables, f"Variable {net} not found in data writer variables"
addr, lengths, _ = variables[net] addr, lengths, _ = variables[net]
dw.write_com(binw.Command.READ_DATA) dw.write_com(binw.Command.READ_DATA)
dw.write_int(addr) dw.write_int(addr)
dw.write_int(lengths) dw.write_int(lengths)

View File

@ -55,12 +55,13 @@ class data_writer():
with open(path, 'wb') as f: with open(path, 'wb') as f:
f.write(self.get_data()) f.write(self.get_data())
class data_reader(): class data_reader():
def __init__(self, data: bytes | bytearray, byteorder: ByteOrder): def __init__(self, data: bytes | bytearray, byteorder: ByteOrder):
self._data = data self._data = data
self._index: int = 0 self._index: int = 0
self.byteorder: ByteOrder = byteorder self.byteorder: ByteOrder = byteorder
def read_int(self, num_bytes: int = 4, signed: bool = False) -> int: def read_int(self, num_bytes: int = 4, signed: bool = False) -> int:
ret = int.from_bytes(self._data[self._index:self._index + num_bytes], byteorder=self.byteorder, signed=signed) ret = int.from_bytes(self._data[self._index:self._index + num_bytes], byteorder=self.byteorder, signed=signed)
self._index += num_bytes self._index += num_bytes
@ -77,7 +78,7 @@ class data_reader():
self._index += 1 self._index += 1
return ret return ret
def read_bytes(self, num_bytes: int) -> bytes: def read_bytes(self, num_bytes: int) -> bytes | bytearray:
ret = self._data[self._index:self._index + num_bytes] ret = self._data[self._index:self._index + num_bytes]
self._index += num_bytes self._index += num_bytes
return ret return ret

View File

@ -7,7 +7,7 @@ op_signs = {'add': '+', 'sub': '-', 'mul': '*', 'div': '/',
def get_function_start() -> str: def get_function_start() -> str:
return """ return """
__attribute__((ms_abi)) int function_start(){ int function_start(){
result_int(0); // dummy call instruction before marker gets striped result_int(0); // dummy call instruction before marker gets striped
asm volatile (".long 0xE2401F0F"); asm volatile (".long 0xE2401F0F");
return 1; return 1;
@ -17,7 +17,7 @@ def get_function_start() -> str:
def get_function_end() -> str: def get_function_end() -> str:
return """ return """
__attribute__((ms_abi)) int function_end(){ int function_end(){
result_int(0); result_int(0);
asm volatile (".long 0xE1401F0F"); asm volatile (".long 0xE1401F0F");
return 1; return 1;

View File

@ -21,6 +21,9 @@ mkdir -p $DEST
# Native x86_64 # Native x86_64
gcc-12 -$OPT -c $SRC -o $DEST/stencils_x86_64_$OPT.o gcc-12 -$OPT -c $SRC -o $DEST/stencils_x86_64_$OPT.o
# Windows x86_64 (ARM64)
x86_64-w64-mingw32-gcc -$OPT -c $SRC -o $DEST/stencils_AMD64_$OPT.o
# ARM64 # ARM64
aarch64-linux-gnu-gcc-12 -$OPT -c $SRC -o $DEST/stencils_aarch64_$OPT.o aarch64-linux-gnu-gcc-12 -$OPT -c $SRC -o $DEST/stencils_aarch64_$OPT.o

View File

@ -11,4 +11,7 @@ mkdir -p $DEST
gcc-12 -c $SRC -O0 -o $DEST/stencils_x86_64_O0.o gcc-12 -c $SRC -O0 -o $DEST/stencils_x86_64_O0.o
gcc-12 -c $SRC -O1 -o $DEST/stencils_x86_64_O1.o gcc-12 -c $SRC -O1 -o $DEST/stencils_x86_64_O1.o
gcc-12 -c $SRC -O2 -o $DEST/stencils_x86_64_O2.o gcc-12 -c $SRC -O2 -o $DEST/stencils_x86_64_O2.o
gcc-12 -c $SRC -O3 -o $DEST/stencils_x86_64_O3.o gcc-12 -c $SRC -O3 -o $DEST/stencils_x86_64_O3.o
# Windows x86_64 (ARM64)
x86_64-w64-mingw32-gcc -O3 -c $SRC -o $DEST/stencils_AMD64_$OPT.o

View File

@ -5,11 +5,11 @@ from enum import Enum
ByteOrder = Literal['little', 'big'] ByteOrder = Literal['little', 'big']
START_MARKER = 0xE1401F0F # Nop on x86-64 START_MARKER = 0xE1401F0F # Nop on x86-64
END_MARKER = 0xE2401F0F # Nop on x86-64 END_MARKER = 0xE2401F0F # Nop on x86-64
MARKER_LENGTH = 4 MARKER_LENGTH = 4
# on x86_64: call or jmp instruction when tail call optimized # on x86_64: call or jmp instruction when tail call optimized
LENGTH_CALL_INSTRUCTION = 5 LENGTH_CALL_INSTRUCTION = 5
RelocationType = Enum('RelocationType', [('RELOC_RELATIVE_32', 0)]) RelocationType = Enum('RelocationType', [('RELOC_RELATIVE_32', 0)])

View File

@ -13,7 +13,7 @@ def test_ast_generation():
#r1 = i1 + i3 #r1 = i1 + i3
#r2 = i3 * i2 #r2 = i3 * i2
#c1 = const(4) #c1 = const(4)
#i1 = c1 * 2 #i1 = c1 * 2
#r1 = i1 + 7 #r1 = i1 + 7

View File

@ -1,6 +1,6 @@
from copapy import const, Target from copapy import const, Target
from pytest import approx from pytest import approx
import time
def function(c1, c2): def function(c1, c2):
i1 = c1 * 3.3 + 5 i1 = c1 * 3.3 + 5
@ -8,14 +8,14 @@ def function(c1, c2):
r1 = i1 + i2 * 55 / 4 r1 = i1 + i2 * 55 / 4
r2 = 4 * i2 + 5 r2 = 4 * i2 + 5
return i1, i2, r1, r2 return i1, i2, r1, r2
def test_compile(): def test_compile():
c1 = const(4) c1 = const(4)
c2 = const(2) c2 = const(2)
ret = function(c1, c2) ret = function(c1, c2)
tg = Target() tg = Target()

View File

@ -1,7 +1,6 @@
from copapy import Write, const from copapy import Write, const
import copapy import copapy
import subprocess import subprocess
import struct
from copapy import binwrite from copapy import binwrite
@ -19,14 +18,14 @@ def function(c1, c2):
r1 = i1 + i2 * 55 / 4 r1 = i1 + i2 * 55 / 4
r2 = 4 * i2 + 5 r2 = 4 * i2 + 5
return i1, i2, r1, r2 return i1, i2, r1, r2
def test_compile(): def test_compile():
c1 = const(4) c1 = const(4)
c2 = const(2) c2 = const(2)
ret = function(c1, c2) ret = function(c1, c2)
dw, variable_list = copapy.compile_to_instruction_list([Write(net) for net in ret], copapy.generic_sdb) dw, variable_list = copapy.compile_to_instruction_list([Write(net) for net in ret], copapy.generic_sdb)
@ -51,6 +50,7 @@ def test_compile():
print(result) print(result)
assert 'Return value: 1' in result assert 'Return value: 1' in result
if __name__ == "__main__": if __name__ == "__main__":
#test_example() #test_example()
test_compile() test_compile()

View File

@ -1,8 +1,9 @@
from copapy import stencil_database, stencil_db, get_local_arch from copapy import stencil_database, stencil_db
import platform
def test_list_symbols(): def test_list_symbols():
arch = get_local_arch() arch = platform.machine()
sdb = stencil_database(f'src/copapy/obj/stencils_{arch}_O3.o') sdb = stencil_database(f'src/copapy/obj/stencils_{arch}_O3.o')
print('----') print('----')
#print(sdb.function_definitions) #print(sdb.function_definitions)
@ -12,7 +13,7 @@ def test_list_symbols():
def test_start_end_function(): def test_start_end_function():
arch = get_local_arch() arch = platform.machine()
sdb = stencil_database(f'src/copapy/obj/stencils_{arch}_O3.o') sdb = stencil_database(f'src/copapy/obj/stencils_{arch}_O3.o')
for sym_name in sdb.function_definitions.keys(): for sym_name in sdb.function_definitions.keys():
data = sdb.elf.symbols[sym_name].data data = sdb.elf.symbols[sym_name].data

View File

@ -16,7 +16,7 @@ buffer_index: int = 0
end_flag: int = 0 end_flag: int = 0
program_data: bytearray = bytearray([]) program_data: bytearray = bytearray([])
while(end_flag == 0): while (end_flag == 0):
com = dr.read_com() com = dr.read_com()
if com == Command.ALLOCATE_DATA: if com == Command.ALLOCATE_DATA:
@ -67,4 +67,4 @@ while(end_flag == 0):
with open(output_file, mode='wb') as f: with open(output_file, mode='wb') as f:
f.write(program_data) f.write(program_data)
print('OK') print('OK')