mirror of https://github.com/Nonannet/copapy.git
Compare commits
No commits in common. "main" and "v0.0.4" have entirely different histories.
|
|
@ -22,11 +22,6 @@ jobs:
|
||||||
name: stencil-object-files
|
name: stencil-object-files
|
||||||
path: src/copapy/obj/*.o
|
path: src/copapy/obj/*.o
|
||||||
|
|
||||||
- uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: musl-object-files
|
|
||||||
path: /object_files/*
|
|
||||||
|
|
||||||
build_wheels:
|
build_wheels:
|
||||||
if: contains(github.ref, '-beta') == false
|
if: contains(github.ref, '-beta') == false
|
||||||
needs: [build_stencils]
|
needs: [build_stencils]
|
||||||
|
|
@ -38,9 +33,6 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: true
|
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -87,6 +89,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -140,6 +144,8 @@ jobs:
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: stencil-object-files
|
name: stencil-object-files
|
||||||
|
|
@ -169,6 +175,8 @@ jobs:
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: stencil-object-files
|
name: stencil-object-files
|
||||||
|
|
@ -198,6 +206,8 @@ jobs:
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: stencil-object-files
|
name: stencil-object-files
|
||||||
|
|
@ -232,6 +242,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-tags: true
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -278,8 +290,11 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 1
|
||||||
fetch-tags: true
|
fetch-tags: true
|
||||||
|
sparse-checkout: |
|
||||||
|
pyproject.toml
|
||||||
|
tools/get_tag.sh
|
||||||
|
|
||||||
- name: Download artifacts
|
- name: Download artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,3 @@ docs/source/api
|
||||||
core
|
core
|
||||||
*.log
|
*.log
|
||||||
docs/source/start.md
|
docs/source/start.md
|
||||||
/src/copapy/_version.py
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Copapy
|
# Copapy
|
||||||
|
|
||||||
Copapy is a Python framework for deterministic, low-latency realtime computation with automatic differentiation support, targeting hardware applications - for example in the fields of robotics, aerospace, SDR, embedded systems and control systems in general.
|
Copapy is a Python framework for deterministic, low-latency realtime computation with automatic differentiation support, targeting hardware applications - for example in the fields of robotics, aerospace, embedded systems and control systems in general.
|
||||||
|
|
||||||
GPU frameworks like PyTorch, JAX and TensorFlow jump-started the development in the field of AI. With the right balance of flexibility and performance, they allow for fast iteration of new ideas while still being performant enough to test or even use them in production.
|
GPU frameworks like PyTorch, JAX and TensorFlow jump-started the development in the field of AI. With the right balance of flexibility and performance, they allow for fast iteration of new ideas while still being performant enough to test or even use them in production.
|
||||||
|
|
||||||
|
|
@ -187,11 +187,11 @@ For more complex operations - where inlining is less useful - stencils call a no
|
||||||
e: R_X86_64_PLT32 result_float-0x4
|
e: R_X86_64_PLT32 result_float-0x4
|
||||||
```
|
```
|
||||||
|
|
||||||
Unlike stencils, non-stencil functions like `sinf` are not stripped and do not need to be tail-call-optimizable. These functions can be provided as C code and compiled together with the stencils or can be object files like in the case of `sinf` compiled from C and assembly code and merged into the stencil object files. Math functions like `sinf` are currently provided by the MUSL C library, with architecture-specific optimizations.
|
Unlike stencils, non-stencil functions are not stripped and do not need to be tail-call-optimizable.
|
||||||
|
|
||||||
Non-stencil functions and constants are stored together with the stencils in an ELF object file for each supported CPU architecture. The required non-stencil functions and constants are bundled during compilation. The compiler includes only the data and code required for a specific Copapy program.
|
Non-stencil functions and constants are stored together with the stencils in an ELF object file for each supported CPU architecture. The required non-stencil functions and constants are bundled during compilation. The compiler includes only the data and code required for the specific program.
|
||||||
|
|
||||||
The Copapy compilation process is independent of the actual instruction set. It relies purely on relocation entries and symbol metadata from the ELF file generated by the C compiler.
|
The whole compilation process is independent of the actual instruction set. It relies purely on relocation entries and symbol metadata from the ELF file generated by the C compiler.
|
||||||
|
|
||||||
## Developer Guide
|
## Developer Guide
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
# How it works
|
# Compiler
|
||||||
```{toctree}
|
```{toctree}
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
:hidden:
|
:hidden:
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
write_functions(f, ['*'], 'copapy', title='Vector functions', path_patterns=['*_vectors*'], api_dir=api_dir)
|
write_functions(f, ['*'], 'copapy', title='Vector functions', path_patterns=['*_vectors*'], api_dir=api_dir)
|
||||||
|
|
||||||
write_functions(f, ['*'], 'copapy', title='Tensor/Matrix functions', path_patterns=['*_tensors*'], api_dir=api_dir)
|
write_functions(f, ['*'], 'copapy', title='Matrix functions', path_patterns=['*_matrices*'], api_dir=api_dir)
|
||||||
|
|
||||||
#write_manual(f, ['NumLike'], title='Types')
|
#write_manual(f, ['NumLike'], title='Types')
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ copapy = ["obj/*.o", "py.typed"]
|
||||||
|
|
||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
version_scheme = "post-release"
|
version_scheme = "post-release"
|
||||||
local_scheme = "no-local-version"
|
local_scheme = "node-and-date"
|
||||||
tag_regex = "^v(?P<version>\\d+\\.\\d+\\.\\d+(?:-beta)?)$"
|
tag_regex = "^v(?P<version>\\d+\\.\\d+\\.\\d+(?:-beta)?)$"
|
||||||
fallback_version = "0.0.0"
|
fallback_version = "0.0.0"
|
||||||
write_to = "src/copapy/_version.py"
|
write_to = "src/copapy/_version.py"
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ from ._tensors import tensor, zeros, ones, arange, eye, identity, diagonal
|
||||||
from ._math import sqrt, abs, sign, sin, cos, tan, asin, acos, atan, atan2, log, exp, pow, get_42, clamp, min, max, relu
|
from ._math import sqrt, abs, sign, sin, cos, tan, asin, acos, atan, atan2, log, exp, pow, get_42, clamp, min, max, relu
|
||||||
from ._autograd import grad
|
from ._autograd import grad
|
||||||
from ._tensors import tensor as matrix
|
from ._tensors import tensor as matrix
|
||||||
from ._version import __version__ # Run "pip install -e ." to generate _version.py
|
from ._version import __version__
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
|
|
||||||
|
|
@ -89,11 +89,8 @@ def grad(x: Any, y: value[Any] | Sequence[value[Any]] | vector[Any] | tensor[Any
|
||||||
elif opn == 'sqrt':
|
elif opn == 'sqrt':
|
||||||
add_grad(a, g * (0.5 / cp.sqrt(a)))
|
add_grad(a, g * (0.5 / cp.sqrt(a)))
|
||||||
|
|
||||||
elif opn == 'abs':
|
#elif opn == 'abs':
|
||||||
add_grad(a, g * cp.sign(a))
|
# add_grad(x, g * cp.sign(x))
|
||||||
|
|
||||||
elif opn == 'neg':
|
|
||||||
add_grad(a, -b)
|
|
||||||
|
|
||||||
elif opn == 'sin':
|
elif opn == 'sin':
|
||||||
add_grad(a, g * cp.cos(a))
|
add_grad(a, g * cp.cos(a))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import pkgutil
|
import pkgutil
|
||||||
from typing import Any, Sequence, TypeVar, overload, TypeAlias, Generic, Callable
|
from typing import Any, Sequence, TypeVar, overload, TypeAlias, Generic, cast, Callable
|
||||||
from ._stencils import stencil_database, detect_process_arch
|
from ._stencils import stencil_database, detect_process_arch
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
from ._helper_types import TNum
|
from ._helper_types import TNum
|
||||||
|
|
@ -230,11 +230,13 @@ class value(Generic[TNum]):
|
||||||
def __rfloordiv__(self, other: NumLike) -> Any:
|
def __rfloordiv__(self, other: NumLike) -> Any:
|
||||||
return add_op('floordiv', [other, self])
|
return add_op('floordiv', [other, self])
|
||||||
|
|
||||||
def __abs__(self: 'value[TNum]') -> 'value[TNum]':
|
def __abs__(self: TCPNum) -> TCPNum:
|
||||||
return cp.abs(self)
|
return cp.abs(self) # type: ignore
|
||||||
|
|
||||||
def __neg__(self: 'value[TNum]') -> 'value[TNum]':
|
def __neg__(self: TCPNum) -> TCPNum:
|
||||||
return add_op('neg', [self])
|
if self.dtype == 'float':
|
||||||
|
return cast(TCPNum, add_op('sub', [value(0.0), self]))
|
||||||
|
return cast(TCPNum, add_op('sub', [value(0), self]))
|
||||||
|
|
||||||
def __gt__(self, other: TVarNumb) -> 'value[int]':
|
def __gt__(self, other: TVarNumb) -> 'value[int]':
|
||||||
return add_op('gt', [self, other], dtype='bool')
|
return add_op('gt', [self, other], dtype='bool')
|
||||||
|
|
@ -360,7 +362,7 @@ class CPConstant(Node):
|
||||||
return self.node_hash
|
return self.node_hash
|
||||||
|
|
||||||
|
|
||||||
class Store(Node):
|
class Write(Node):
|
||||||
def __init__(self, input: value[Any] | Net | int | float):
|
def __init__(self, input: value[Any] | Net | int | float):
|
||||||
if isinstance(input, value):
|
if isinstance(input, value):
|
||||||
net = input.net
|
net = input.net
|
||||||
|
|
@ -370,7 +372,7 @@ class Store(Node):
|
||||||
node = CPConstant(input)
|
node = CPConstant(input)
|
||||||
net = Net(node.dtype, node)
|
net = Net(node.dtype, node)
|
||||||
|
|
||||||
self.name = 'store_' + transl_type(net.dtype)
|
self.name = 'write_' + transl_type(net.dtype)
|
||||||
self.args = (net,)
|
self.args = (net,)
|
||||||
self.node_hash = hash(self.name) ^ hash(net.source.node_hash)
|
self.node_hash = hash(self.name) ^ hash(net.source.node_hash)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from typing import Generator, Iterable, Any
|
||||||
from . import _binwrite as binw
|
from . import _binwrite as binw
|
||||||
from ._stencils import stencil_database, patch_entry
|
from ._stencils import stencil_database, patch_entry
|
||||||
from collections import defaultdict, deque
|
from collections import defaultdict, deque
|
||||||
from ._basic_types import Net, Node, Store, CPConstant, Op, transl_type
|
from ._basic_types import Net, Node, Write, CPConstant, Op, transl_type
|
||||||
|
|
||||||
|
|
||||||
def stable_toposort(edges: Iterable[tuple[Node, Node]]) -> list[Node]:
|
def stable_toposort(edges: Iterable[tuple[Node, Node]]) -> list[Node]:
|
||||||
|
|
@ -132,7 +132,7 @@ def get_const_nets(nodes: list[Node]) -> list[Net]:
|
||||||
return [net_lookup[node] for node in nodes if isinstance(node, CPConstant)]
|
return [net_lookup[node] for node in nodes if isinstance(node, CPConstant)]
|
||||||
|
|
||||||
|
|
||||||
def add_load_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], None, None]:
|
def add_read_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], None, None]:
|
||||||
"""Add read node before each op where arguments are not already positioned
|
"""Add read node before each op where arguments are not already positioned
|
||||||
correctly in the registers
|
correctly in the registers
|
||||||
|
|
||||||
|
|
@ -156,7 +156,7 @@ def add_load_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], No
|
||||||
#if net in registers:
|
#if net in registers:
|
||||||
# print('x swap registers')
|
# print('x swap registers')
|
||||||
type_list = ['int' if r is None else transl_type(r.dtype) for r in registers]
|
type_list = ['int' if r is None else transl_type(r.dtype) for r in registers]
|
||||||
new_node = Op(f"load_{transl_type(net.dtype)}_reg{i}_" + '_'.join(type_list), [])
|
new_node = Op(f"read_{transl_type(net.dtype)}_reg{i}_" + '_'.join(type_list), [])
|
||||||
yield net, new_node
|
yield net, new_node
|
||||||
registers[i] = net
|
registers[i] = net
|
||||||
|
|
||||||
|
|
@ -170,7 +170,7 @@ def add_load_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], No
|
||||||
yield None, node
|
yield None, node
|
||||||
|
|
||||||
|
|
||||||
def add_store_ops(net_node_list: list[tuple[Net | None, Node]], const_nets: list[Net]) -> Generator[tuple[Net | None, Node], None, None]:
|
def add_write_ops(net_node_list: list[tuple[Net | None, Node]], const_nets: list[Net]) -> Generator[tuple[Net | None, Node], None, None]:
|
||||||
"""Add write operation for each new defined net if a read operation is later followed
|
"""Add write operation for each new defined net if a read operation is later followed
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
@ -181,19 +181,19 @@ def add_store_ops(net_node_list: list[tuple[Net | None, Node]], const_nets: list
|
||||||
# Initialize set of nets with constants
|
# Initialize set of nets with constants
|
||||||
stored_nets = set(const_nets)
|
stored_nets = set(const_nets)
|
||||||
|
|
||||||
#assert all(node.name.startswith('load_') for net, node in net_node_list if net)
|
#assert all(node.name.startswith('read_') for net, node in net_node_list if net)
|
||||||
read_back_nets = {
|
read_back_nets = {
|
||||||
net for net, node in net_node_list
|
net for net, node in net_node_list
|
||||||
if net and node.name.startswith('load_')}
|
if net and node.name.startswith('read_')}
|
||||||
|
|
||||||
registers: list[Net | None] = [None, None]
|
registers: list[Net | None] = [None, None]
|
||||||
|
|
||||||
for net, node in net_node_list:
|
for net, node in net_node_list:
|
||||||
if isinstance(node, Store):
|
if isinstance(node, Write):
|
||||||
assert len(registers) == 2
|
assert len(registers) == 2
|
||||||
type_list = [transl_type(r.dtype) if r else 'int' for r in registers]
|
type_list = [transl_type(r.dtype) if r else 'int' for r in registers]
|
||||||
yield node.args[0], Op(f"store_{type_list[0]}_reg0_" + '_'.join(type_list), node.args)
|
yield node.args[0], Op(f"write_{type_list[0]}_reg0_" + '_'.join(type_list), node.args)
|
||||||
elif node.name.startswith('load_'):
|
elif node.name.startswith('read_'):
|
||||||
yield net, node
|
yield net, node
|
||||||
else:
|
else:
|
||||||
yield None, node
|
yield None, node
|
||||||
|
|
@ -207,7 +207,7 @@ def add_store_ops(net_node_list: list[tuple[Net | None, Node]], const_nets: list
|
||||||
|
|
||||||
if net in read_back_nets and net not in stored_nets:
|
if net in read_back_nets and net not in stored_nets:
|
||||||
type_list = [transl_type(r.dtype) if r else 'int' for r in registers]
|
type_list = [transl_type(r.dtype) if r else 'int' for r in registers]
|
||||||
yield net, Op(f"store_{type_list[0]}_reg0_" + '_'.join(type_list), [])
|
yield net, Op(f"write_{type_list[0]}_reg0_" + '_'.join(type_list), [])
|
||||||
stored_nets.add(net)
|
stored_nets.add(net)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -344,8 +344,8 @@ def compile_to_dag(node_list: Iterable[Node], sdb: stencil_database) -> tuple[bi
|
||||||
|
|
||||||
ordered_ops = list(stable_toposort(get_all_dag_edges(node_list)))
|
ordered_ops = list(stable_toposort(get_all_dag_edges(node_list)))
|
||||||
const_net_list = get_const_nets(ordered_ops)
|
const_net_list = get_const_nets(ordered_ops)
|
||||||
output_ops = list(add_load_ops(ordered_ops))
|
output_ops = list(add_read_ops(ordered_ops))
|
||||||
extended_output_ops = list(add_store_ops(output_ops, const_net_list))
|
extended_output_ops = list(add_write_ops(output_ops, const_net_list))
|
||||||
|
|
||||||
dw = binw.data_writer(sdb.byteorder)
|
dw = binw.data_writer(sdb.byteorder)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
from . import vector
|
from . import vector
|
||||||
from . import tensor
|
|
||||||
from ._vectors import VecNumLike
|
from ._vectors import VecNumLike
|
||||||
from ._tensors import TensorNumLike
|
|
||||||
from . import value, NumLike
|
from . import value, NumLike
|
||||||
from typing import TypeVar, Any, overload, Callable
|
from typing import TypeVar, Any, overload, Callable
|
||||||
from ._basic_types import add_op, unifloat
|
from ._basic_types import add_op, unifloat
|
||||||
|
|
@ -17,8 +15,6 @@ def exp(x: float | int) -> float: ...
|
||||||
def exp(x: value[Any]) -> value[float]: ...
|
def exp(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def exp(x: vector[Any]) -> vector[float]: ...
|
def exp(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def exp(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def exp(x: Any) -> Any:
|
def exp(x: Any) -> Any:
|
||||||
"""Exponential function to basis e
|
"""Exponential function to basis e
|
||||||
|
|
||||||
|
|
@ -30,7 +26,7 @@ def exp(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('exp', [x])
|
return add_op('exp', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(exp)
|
return x.map(exp)
|
||||||
return float(math.exp(x))
|
return float(math.exp(x))
|
||||||
|
|
||||||
|
|
@ -41,8 +37,6 @@ def log(x: float | int) -> float: ...
|
||||||
def log(x: value[Any]) -> value[float]: ...
|
def log(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def log(x: vector[Any]) -> vector[float]: ...
|
def log(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def log(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def log(x: Any) -> Any:
|
def log(x: Any) -> Any:
|
||||||
"""Logarithm to basis e
|
"""Logarithm to basis e
|
||||||
|
|
||||||
|
|
@ -54,7 +48,7 @@ def log(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('log', [x])
|
return add_op('log', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(log)
|
return x.map(log)
|
||||||
return float(math.log(x))
|
return float(math.log(x))
|
||||||
|
|
||||||
|
|
@ -67,13 +61,7 @@ def pow(x: value[Any], y: NumLike) -> value[float]: ...
|
||||||
def pow(x: NumLike, y: value[Any]) -> value[float]: ...
|
def pow(x: NumLike, y: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def pow(x: vector[Any], y: Any) -> vector[float]: ...
|
def pow(x: vector[Any], y: Any) -> vector[float]: ...
|
||||||
@overload
|
def pow(x: VecNumLike, y: VecNumLike) -> Any:
|
||||||
def pow(x: Any, y: vector[Any]) -> vector[float]: ...
|
|
||||||
@overload
|
|
||||||
def pow(x: tensor[Any], y: Any) -> tensor[float]: ...
|
|
||||||
@overload
|
|
||||||
def pow(x: Any, y: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def pow(x: TensorNumLike, y: TensorNumLike) -> Any:
|
|
||||||
"""x to the power of y
|
"""x to the power of y
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
@ -82,10 +70,8 @@ def pow(x: TensorNumLike, y: TensorNumLike) -> Any:
|
||||||
Returns:
|
Returns:
|
||||||
result of x**y
|
result of x**y
|
||||||
"""
|
"""
|
||||||
if isinstance(x, tensor) or isinstance(y, tensor):
|
|
||||||
return _map2_tensor(x, y, pow)
|
|
||||||
if isinstance(x, vector) or isinstance(y, vector):
|
if isinstance(x, vector) or isinstance(y, vector):
|
||||||
return _map2_vector(x, y, pow)
|
return _map2(x, y, pow)
|
||||||
if isinstance(y, int) and 0 <= y < 8:
|
if isinstance(y, int) and 0 <= y < 8:
|
||||||
if y == 0:
|
if y == 0:
|
||||||
return 1
|
return 1
|
||||||
|
|
@ -107,8 +93,6 @@ def sqrt(x: float | int) -> float: ...
|
||||||
def sqrt(x: value[Any]) -> value[float]: ...
|
def sqrt(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def sqrt(x: vector[Any]) -> vector[float]: ...
|
def sqrt(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def sqrt(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def sqrt(x: Any) -> Any:
|
def sqrt(x: Any) -> Any:
|
||||||
"""Square root function
|
"""Square root function
|
||||||
|
|
||||||
|
|
@ -120,7 +104,7 @@ def sqrt(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('sqrt', [x])
|
return add_op('sqrt', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(sqrt)
|
return x.map(sqrt)
|
||||||
return float(math.sqrt(x))
|
return float(math.sqrt(x))
|
||||||
|
|
||||||
|
|
@ -131,8 +115,6 @@ def sin(x: float | int) -> float: ...
|
||||||
def sin(x: value[Any]) -> value[float]: ...
|
def sin(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def sin(x: vector[Any]) -> vector[float]: ...
|
def sin(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def sin(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def sin(x: Any) -> Any:
|
def sin(x: Any) -> Any:
|
||||||
"""Sine function
|
"""Sine function
|
||||||
|
|
||||||
|
|
@ -144,7 +126,7 @@ def sin(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('sin', [x])
|
return add_op('sin', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(sin)
|
return x.map(sin)
|
||||||
return math.sin(x)
|
return math.sin(x)
|
||||||
|
|
||||||
|
|
@ -155,8 +137,6 @@ def cos(x: float | int) -> float: ...
|
||||||
def cos(x: value[Any]) -> value[float]: ...
|
def cos(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def cos(x: vector[Any]) -> vector[float]: ...
|
def cos(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def cos(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def cos(x: Any) -> Any:
|
def cos(x: Any) -> Any:
|
||||||
"""Cosine function
|
"""Cosine function
|
||||||
|
|
||||||
|
|
@ -168,7 +148,7 @@ def cos(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('cos', [x])
|
return add_op('cos', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(cos)
|
return x.map(cos)
|
||||||
return math.cos(x)
|
return math.cos(x)
|
||||||
|
|
||||||
|
|
@ -179,8 +159,6 @@ def tan(x: float | int) -> float: ...
|
||||||
def tan(x: value[Any]) -> value[float]: ...
|
def tan(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def tan(x: vector[Any]) -> vector[float]: ...
|
def tan(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def tan(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def tan(x: Any) -> Any:
|
def tan(x: Any) -> Any:
|
||||||
"""Tangent function
|
"""Tangent function
|
||||||
|
|
||||||
|
|
@ -192,7 +170,8 @@ def tan(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('tan', [x])
|
return add_op('tan', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
|
#return x.map(tan)
|
||||||
return x.map(tan)
|
return x.map(tan)
|
||||||
return math.tan(x)
|
return math.tan(x)
|
||||||
|
|
||||||
|
|
@ -203,8 +182,6 @@ def atan(x: float | int) -> float: ...
|
||||||
def atan(x: value[Any]) -> value[float]: ...
|
def atan(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def atan(x: vector[Any]) -> vector[float]: ...
|
def atan(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def atan(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def atan(x: Any) -> Any:
|
def atan(x: Any) -> Any:
|
||||||
"""Inverse tangent function
|
"""Inverse tangent function
|
||||||
|
|
||||||
|
|
@ -216,7 +193,7 @@ def atan(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('atan', [x])
|
return add_op('atan', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(atan)
|
return x.map(atan)
|
||||||
return math.atan(x)
|
return math.atan(x)
|
||||||
|
|
||||||
|
|
@ -231,11 +208,7 @@ def atan2(x: NumLike, y: value[Any]) -> value[float]: ...
|
||||||
def atan2(x: vector[float], y: VecNumLike) -> vector[float]: ...
|
def atan2(x: vector[float], y: VecNumLike) -> vector[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def atan2(x: VecNumLike, y: vector[float]) -> vector[float]: ...
|
def atan2(x: VecNumLike, y: vector[float]) -> vector[float]: ...
|
||||||
@overload
|
def atan2(x: VecNumLike, y: VecNumLike) -> Any:
|
||||||
def atan2(x: tensor[float], y: TensorNumLike) -> tensor[float]: ...
|
|
||||||
@overload
|
|
||||||
def atan2(x: TensorNumLike, y: tensor[float]) -> tensor[float]: ...
|
|
||||||
def atan2(x: TensorNumLike, y: TensorNumLike) -> Any:
|
|
||||||
"""2-argument arctangent
|
"""2-argument arctangent
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
@ -245,10 +218,8 @@ def atan2(x: TensorNumLike, y: TensorNumLike) -> Any:
|
||||||
Returns:
|
Returns:
|
||||||
Result in radian
|
Result in radian
|
||||||
"""
|
"""
|
||||||
if isinstance(x, tensor) or isinstance(y, tensor):
|
|
||||||
return _map2_tensor(x, y, atan2)
|
|
||||||
if isinstance(x, vector) or isinstance(y, vector):
|
if isinstance(x, vector) or isinstance(y, vector):
|
||||||
return _map2_vector(x, y, atan2)
|
return _map2(x, y, atan2)
|
||||||
if isinstance(x, value) or isinstance(y, value):
|
if isinstance(x, value) or isinstance(y, value):
|
||||||
return add_op('atan2', [x, y])
|
return add_op('atan2', [x, y])
|
||||||
return math.atan2(x, y)
|
return math.atan2(x, y)
|
||||||
|
|
@ -260,8 +231,6 @@ def asin(x: float | int) -> float: ...
|
||||||
def asin(x: value[Any]) -> value[float]: ...
|
def asin(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def asin(x: vector[Any]) -> vector[float]: ...
|
def asin(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def asin(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def asin(x: Any) -> Any:
|
def asin(x: Any) -> Any:
|
||||||
"""Inverse sine function
|
"""Inverse sine function
|
||||||
|
|
||||||
|
|
@ -273,7 +242,7 @@ def asin(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('asin', [x])
|
return add_op('asin', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(asin)
|
return x.map(asin)
|
||||||
return math.asin(x)
|
return math.asin(x)
|
||||||
|
|
||||||
|
|
@ -284,8 +253,6 @@ def acos(x: float | int) -> float: ...
|
||||||
def acos(x: value[Any]) -> value[float]: ...
|
def acos(x: value[Any]) -> value[float]: ...
|
||||||
@overload
|
@overload
|
||||||
def acos(x: vector[Any]) -> vector[float]: ...
|
def acos(x: vector[Any]) -> vector[float]: ...
|
||||||
@overload
|
|
||||||
def acos(x: tensor[Any]) -> tensor[float]: ...
|
|
||||||
def acos(x: Any) -> Any:
|
def acos(x: Any) -> Any:
|
||||||
"""Inverse cosine function
|
"""Inverse cosine function
|
||||||
|
|
||||||
|
|
@ -297,12 +264,11 @@ def acos(x: Any) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('acos', [x])
|
return add_op('acos', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(acos)
|
return x.map(acos)
|
||||||
return math.asin(x)
|
return math.asin(x)
|
||||||
|
|
||||||
|
|
||||||
# Debug test function
|
|
||||||
@overload
|
@overload
|
||||||
def get_42(x: float | int) -> float: ...
|
def get_42(x: float | int) -> float: ...
|
||||||
@overload
|
@overload
|
||||||
|
|
@ -320,9 +286,7 @@ def abs(x: U) -> U: ...
|
||||||
def abs(x: value[U]) -> value[U]: ...
|
def abs(x: value[U]) -> value[U]: ...
|
||||||
@overload
|
@overload
|
||||||
def abs(x: vector[U]) -> vector[U]: ...
|
def abs(x: vector[U]) -> vector[U]: ...
|
||||||
@overload
|
def abs(x: U | value[U] | vector[U]) -> Any:
|
||||||
def abs(x: tensor[U]) -> tensor[U]: ...
|
|
||||||
def abs(x: U | value[U] | vector[U] | tensor[U]) -> Any:
|
|
||||||
"""Absolute value function
|
"""Absolute value function
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
@ -333,20 +297,18 @@ def abs(x: U | value[U] | vector[U] | tensor[U]) -> Any:
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
if isinstance(x, value):
|
||||||
return add_op('abs', [x])
|
return add_op('abs', [x])
|
||||||
if isinstance(x, vector | tensor):
|
if isinstance(x, vector):
|
||||||
return x.map(abs)
|
return x.map(abs)
|
||||||
return (x < 0) * -x + (x >= 0) * x
|
return (x < 0) * -x + (x >= 0) * x
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def sign(x: U) -> int: ...
|
def sign(x: U) -> U: ...
|
||||||
@overload
|
@overload
|
||||||
def sign(x: value[U]) -> value[int]: ...
|
def sign(x: value[U]) -> value[U]: ...
|
||||||
@overload
|
@overload
|
||||||
def sign(x: vector[U]) -> vector[int]: ...
|
def sign(x: vector[U]) -> vector[U]: ...
|
||||||
@overload
|
def sign(x: U | value[U] | vector[U]) -> Any:
|
||||||
def sign(x: tensor[U]) -> tensor[int]: ...
|
|
||||||
def sign(x: U | value[U] | vector[U] | tensor[U]) -> Any:
|
|
||||||
"""Return 1 for positive numbers and -1 for negative numbers.
|
"""Return 1 for positive numbers and -1 for negative numbers.
|
||||||
For an input of 0 the return value is 0.
|
For an input of 0 the return value is 0.
|
||||||
|
|
||||||
|
|
@ -356,11 +318,8 @@ def sign(x: U | value[U] | vector[U] | tensor[U]) -> Any:
|
||||||
Returns:
|
Returns:
|
||||||
-1, 0 or 1
|
-1, 0 or 1
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
ret = (x > 0) - (x < 0)
|
||||||
return add_op('sign', [x])
|
return ret
|
||||||
if isinstance(x, vector | tensor):
|
|
||||||
return x.map(sign)
|
|
||||||
return (x > 0) - (x < 0)
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
|
@ -408,13 +367,7 @@ def min(x: U | value[U], y: U | value[U]) -> Any:
|
||||||
Returns:
|
Returns:
|
||||||
Minimum of x and y
|
Minimum of x and y
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
return (x < y) * x + (x >= y) * y
|
||||||
return add_op('min', [x, y])
|
|
||||||
if isinstance(x, tensor):
|
|
||||||
return _map2_tensor(x, y, min)
|
|
||||||
if isinstance(x, vector):
|
|
||||||
return _map2_vector(x, y, min)
|
|
||||||
return x if x < y else y
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
|
@ -433,13 +386,7 @@ def max(x: U | value[U], y: U | value[U]) -> Any:
|
||||||
Returns:
|
Returns:
|
||||||
Maximum of x and y
|
Maximum of x and y
|
||||||
"""
|
"""
|
||||||
if isinstance(x, value):
|
return (x > y) * x + (x <= y) * y
|
||||||
return add_op('max', [x, y])
|
|
||||||
if isinstance(x, tensor):
|
|
||||||
return _map2_tensor(x, y, max)
|
|
||||||
if isinstance(x, vector):
|
|
||||||
return _map2_vector(x, y, max)
|
|
||||||
return x if x > y else y
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
|
@ -453,16 +400,7 @@ def lerp(v1: U, v2: U, t: float) -> U: ...
|
||||||
@overload
|
@overload
|
||||||
def lerp(v1: vector[U], v2: vector[U], t: unifloat) -> vector[U]: ...
|
def lerp(v1: vector[U], v2: vector[U], t: unifloat) -> vector[U]: ...
|
||||||
def lerp(v1: U | value[U] | vector[U], v2: U | value[U] | vector[U], t: unifloat) -> Any:
|
def lerp(v1: U | value[U] | vector[U], v2: U | value[U] | vector[U], t: unifloat) -> Any:
|
||||||
"""Linearly interpolate between two values or vectors v1 and v2 by a factor t.
|
"""Linearly interpolate between two values or vectors v1 and v2 by a factor t."""
|
||||||
|
|
||||||
Arguments:
|
|
||||||
v1: First value or vector
|
|
||||||
v2: Second value or vector
|
|
||||||
t: Interpolation factor (0.0 to 1.0)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Interpolated value or vector
|
|
||||||
"""
|
|
||||||
if isinstance(v1, vector) or isinstance(v2, vector):
|
if isinstance(v1, vector) or isinstance(v2, vector):
|
||||||
assert isinstance(v1, vector) and isinstance(v2, vector), "None or both v1 and v2 must be vectors."
|
assert isinstance(v1, vector) and isinstance(v2, vector), "None or both v1 and v2 must be vectors."
|
||||||
assert len(v1.values) == len(v2.values), "Vectors must be of the same length."
|
assert len(v1.values) == len(v2.values), "Vectors must be of the same length."
|
||||||
|
|
@ -476,15 +414,13 @@ def relu(x: U) -> U: ...
|
||||||
def relu(x: value[U]) -> value[U]: ...
|
def relu(x: value[U]) -> value[U]: ...
|
||||||
@overload
|
@overload
|
||||||
def relu(x: vector[U]) -> vector[U]: ...
|
def relu(x: vector[U]) -> vector[U]: ...
|
||||||
@overload
|
def relu(x: U | value[U] | vector[U]) -> Any:
|
||||||
def relu(x: tensor[U]) -> tensor[U]: ...
|
|
||||||
def relu(x: U | value[U] | vector[U] | tensor[U]) -> Any:
|
|
||||||
"""Returns x for x > 0 and otherwise 0."""
|
"""Returns x for x > 0 and otherwise 0."""
|
||||||
ret = x * (x > 0)
|
ret = (x > 0) * x
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def _map2_vector(self: VecNumLike, other: VecNumLike, func: Callable[[Any, Any], value[U] | U]) -> vector[U]:
|
def _map2(self: VecNumLike, other: VecNumLike, func: Callable[[Any, Any], value[U] | U]) -> vector[U]:
|
||||||
"""Applies a function to each element of the vector and a second vector or scalar."""
|
"""Applies a function to each element of the vector and a second vector or scalar."""
|
||||||
if isinstance(self, vector) and isinstance(other, vector):
|
if isinstance(self, vector) and isinstance(other, vector):
|
||||||
return vector(func(x, y) for x, y in zip(self.values, other.values))
|
return vector(func(x, y) for x, y in zip(self.values, other.values))
|
||||||
|
|
@ -494,20 +430,3 @@ def _map2_vector(self: VecNumLike, other: VecNumLike, func: Callable[[Any, Any],
|
||||||
return vector(func(self, x) for x in other.values)
|
return vector(func(self, x) for x in other.values)
|
||||||
else:
|
else:
|
||||||
return vector([func(self, other)])
|
return vector([func(self, other)])
|
||||||
|
|
||||||
|
|
||||||
def _map2_tensor(self: TensorNumLike, other: TensorNumLike, func: Callable[[Any, Any], value[U] | U]) -> tensor[U]:
|
|
||||||
"""Applies a function to each element of the vector and a second vector or scalar."""
|
|
||||||
if isinstance(self, vector):
|
|
||||||
self = tensor(self.values, (len(self.values),))
|
|
||||||
if isinstance(other, vector):
|
|
||||||
other = tensor(other.values, (len(other.values),))
|
|
||||||
if isinstance(self, tensor) and isinstance(other, tensor):
|
|
||||||
assert self.shape == other.shape, "Tensors must have the same shape"
|
|
||||||
return tensor([func(x, y) for x, y in zip(self.values, other.values)], self.shape)
|
|
||||||
elif isinstance(self, tensor):
|
|
||||||
return tensor([func(x, other) for x in self.values], self.shape)
|
|
||||||
elif isinstance(other, tensor):
|
|
||||||
return tensor([func(self, x) for x in other.values], other.shape)
|
|
||||||
else:
|
|
||||||
return tensor(func(self, other))
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ from typing import Iterable, overload, TypeVar, Any, Callable, TypeAlias
|
||||||
from . import _binwrite as binw
|
from . import _binwrite as binw
|
||||||
from coparun_module import coparun, read_data_mem, create_target, clear_target
|
from coparun_module import coparun, read_data_mem, create_target, clear_target
|
||||||
import struct
|
import struct
|
||||||
from ._basic_types import value, Net, Node, Store, NumLike, ArrayType, stencil_db_from_package
|
from ._basic_types import value, Net, Node, Write, NumLike, ArrayType, stencil_db_from_package
|
||||||
from ._compiler import compile_to_dag
|
from ._compiler import compile_to_dag
|
||||||
|
|
||||||
T = TypeVar("T", int, float)
|
T = TypeVar("T", int, float)
|
||||||
|
|
@ -76,13 +76,13 @@ class Target():
|
||||||
if isinstance(input, ArrayType):
|
if isinstance(input, ArrayType):
|
||||||
for v in input.values:
|
for v in input.values:
|
||||||
if isinstance(v, value):
|
if isinstance(v, value):
|
||||||
nodes.append(Store(v))
|
nodes.append(Write(v))
|
||||||
elif isinstance(input, Iterable):
|
elif isinstance(input, Iterable):
|
||||||
for v in input:
|
for v in input:
|
||||||
if isinstance(v, value):
|
if isinstance(v, value):
|
||||||
nodes.append(Store(v))
|
nodes.append(Write(v))
|
||||||
elif isinstance(input, value):
|
elif isinstance(input, value):
|
||||||
nodes.append(Store(input))
|
nodes.append(Write(input))
|
||||||
|
|
||||||
dw, self._values = compile_to_dag(nodes, self.sdb)
|
dw, self._values = compile_to_dag(nodes, self.sdb)
|
||||||
dw.write_com(binw.Command.END_COM)
|
dw.write_com(binw.Command.END_COM)
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
from copapy._basic_types import NumLike, ArrayType
|
from copapy._basic_types import NumLike, ArrayType
|
||||||
from . import value
|
from . import value
|
||||||
from ._vectors import vector, VecFloatLike, VecIntLike, VecNumLike
|
from ._vectors import vector
|
||||||
from ._mixed import mixed_sum
|
from ._mixed import mixed_sum
|
||||||
from typing import TypeVar, Any, overload, TypeAlias, Callable, Iterator, Sequence
|
from typing import TypeVar, Any, overload, TypeAlias, Callable, Iterator, Sequence
|
||||||
from ._helper_types import TNum
|
from ._helper_types import TNum
|
||||||
|
|
||||||
TensorNumLike: TypeAlias = 'tensor[Any] | vector[Any] | value[Any] | int | float | bool'
|
TensorNumLike: TypeAlias = 'tensor[Any] | vector[Any] | value[Any] | int | float | bool'
|
||||||
TensorIntLike: TypeAlias = 'tensor[int] | vector[int] | value[int] | int | bool'
|
TensorIntLike: TypeAlias = 'tensor[int] | value[int] | int'
|
||||||
TensorFloatLike: TypeAlias = 'tensor[float] | vector[float] | value[float] | float'
|
TensorFloatLike: TypeAlias = 'tensor[float] | value[float] | float'
|
||||||
TensorSequence: TypeAlias = 'Sequence[TNum | value[TNum]] | Sequence[Sequence[TNum | value[TNum]]] | Sequence[Sequence[Sequence[TNum | value[TNum]]]]'
|
TensorSequence: TypeAlias = 'Sequence[TNum | value[TNum]] | Sequence[Sequence[TNum | value[TNum]]] | Sequence[Sequence[Sequence[TNum | value[TNum]]]]'
|
||||||
U = TypeVar("U", int, float)
|
U = TypeVar("U", int, float)
|
||||||
|
|
||||||
|
|
@ -26,7 +26,6 @@ class tensor(ArrayType[TNum]):
|
||||||
values: Nested iterables of constant values or copapy values.
|
values: Nested iterables of constant values or copapy values.
|
||||||
Can be a scalar, 1D iterable (vector),
|
Can be a scalar, 1D iterable (vector),
|
||||||
or n-dimensional nested structure.
|
or n-dimensional nested structure.
|
||||||
shape: Optional shape of the tensor. If not provided, inferred from values.
|
|
||||||
"""
|
"""
|
||||||
if shape:
|
if shape:
|
||||||
self.shape: tuple[int, ...] = tuple(shape)
|
self.shape: tuple[int, ...] = tuple(shape)
|
||||||
|
|
@ -265,19 +264,15 @@ class tensor(ArrayType[TNum]):
|
||||||
@overload
|
@overload
|
||||||
def __add__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
def __add__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __add__(self, other: TensorNumLike) -> 'tensor[Any]': ...
|
def __add__(self, other: TensorNumLike) -> 'tensor[int] | tensor[float]': ...
|
||||||
def __add__(self, other: TensorNumLike) -> Any:
|
def __add__(self, other: TensorNumLike) -> Any:
|
||||||
"""Element-wise addition."""
|
"""Element-wise addition."""
|
||||||
return self._binary_op(other, lambda a, b: a + b)
|
return self._binary_op(other, lambda a, b: a + b)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __radd__(self: 'tensor[int]', other: VecFloatLike) -> 'tensor[float]': ...
|
def __radd__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __radd__(self: 'tensor[int]', other: VecIntLike) -> 'tensor[int]': ...
|
def __radd__(self: 'tensor[int]', other: value[int] | int) -> 'tensor[int]': ...
|
||||||
@overload
|
|
||||||
def __radd__(self: 'tensor[float]', other: VecNumLike) -> 'tensor[float]': ...
|
|
||||||
@overload
|
|
||||||
def __radd__(self, other: VecNumLike) -> 'tensor[Any]': ...
|
|
||||||
def __radd__(self, other: Any) -> Any:
|
def __radd__(self, other: Any) -> Any:
|
||||||
return self + other
|
return self + other
|
||||||
|
|
||||||
|
|
@ -288,19 +283,15 @@ class tensor(ArrayType[TNum]):
|
||||||
@overload
|
@overload
|
||||||
def __sub__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
def __sub__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __sub__(self, other: TensorNumLike) -> 'tensor[Any]': ...
|
def __sub__(self, other: TensorNumLike) -> 'tensor[int] | tensor[float]': ...
|
||||||
def __sub__(self, other: TensorNumLike) -> Any:
|
def __sub__(self, other: TensorNumLike) -> Any:
|
||||||
"""Element-wise subtraction."""
|
"""Element-wise subtraction."""
|
||||||
return self._binary_op(other, lambda a, b: a - b, commutative=False)
|
return self._binary_op(other, lambda a, b: a - b, commutative=False)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rsub__(self: 'tensor[int]', other: VecFloatLike) -> 'tensor[float]': ...
|
def __rsub__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __rsub__(self: 'tensor[int]', other: VecIntLike) -> 'tensor[int]': ...
|
def __rsub__(self: 'tensor[int]', other: value[int] | int) -> 'tensor[int]': ...
|
||||||
@overload
|
|
||||||
def __rsub__(self: 'tensor[float]', other: VecNumLike) -> 'tensor[float]': ...
|
|
||||||
@overload
|
|
||||||
def __rsub__(self, other: VecNumLike) -> 'tensor[Any]': ...
|
|
||||||
def __rsub__(self, other: TensorNumLike) -> Any:
|
def __rsub__(self, other: TensorNumLike) -> Any:
|
||||||
return self._binary_op(other, lambda a, b: b - a, commutative=False, reversed=True)
|
return self._binary_op(other, lambda a, b: b - a, commutative=False, reversed=True)
|
||||||
|
|
||||||
|
|
@ -311,19 +302,15 @@ class tensor(ArrayType[TNum]):
|
||||||
@overload
|
@overload
|
||||||
def __mul__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
def __mul__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __mul__(self, other: TensorNumLike) -> 'tensor[Any]': ...
|
def __mul__(self, other: TensorNumLike) -> 'tensor[int] | tensor[float]': ...
|
||||||
def __mul__(self, other: TensorNumLike) -> Any:
|
def __mul__(self, other: TensorNumLike) -> Any:
|
||||||
"""Element-wise multiplication."""
|
"""Element-wise multiplication."""
|
||||||
return self._binary_op(other, lambda a, b: a * b)
|
return self._binary_op(other, lambda a, b: a * b)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rmul__(self: 'tensor[int]', other: VecFloatLike) -> 'tensor[float]': ...
|
def __rmul__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __rmul__(self: 'tensor[int]', other: VecIntLike) -> 'tensor[int]': ...
|
def __rmul__(self: 'tensor[int]', other: value[int] | int) -> 'tensor[int]': ...
|
||||||
@overload
|
|
||||||
def __rmul__(self: 'tensor[float]', other: VecNumLike) -> 'tensor[float]': ...
|
|
||||||
@overload
|
|
||||||
def __rmul__(self, other: VecNumLike) -> 'tensor[Any]': ...
|
|
||||||
def __rmul__(self, other: TensorNumLike) -> Any:
|
def __rmul__(self, other: TensorNumLike) -> Any:
|
||||||
return self * other
|
return self * other
|
||||||
|
|
||||||
|
|
@ -342,19 +329,15 @@ class tensor(ArrayType[TNum]):
|
||||||
@overload
|
@overload
|
||||||
def __pow__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
def __pow__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __pow__(self, other: TensorNumLike) -> 'tensor[Any]': ...
|
def __pow__(self, other: TensorNumLike) -> 'tensor[int] | tensor[float]': ...
|
||||||
def __pow__(self, other: TensorNumLike) -> Any:
|
def __pow__(self, other: TensorNumLike) -> Any:
|
||||||
"""Element-wise power."""
|
"""Element-wise power."""
|
||||||
return self._binary_op(other, lambda a, b: a ** b, commutative=False)
|
return self._binary_op(other, lambda a, b: a ** b, commutative=False)
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rpow__(self: 'tensor[int]', other: VecFloatLike) -> 'tensor[float]': ...
|
def __rpow__(self: 'tensor[float]', other: TensorNumLike) -> 'tensor[float]': ...
|
||||||
@overload
|
@overload
|
||||||
def __rpow__(self: 'tensor[int]', other: VecIntLike) -> 'tensor[int]': ...
|
def __rpow__(self: 'tensor[int]', other: value[int] | int) -> 'tensor[int]': ...
|
||||||
@overload
|
|
||||||
def __rpow__(self: 'tensor[float]', other: VecNumLike) -> 'tensor[float]': ...
|
|
||||||
@overload
|
|
||||||
def __rpow__(self, other: VecNumLike) -> 'tensor[Any]': ...
|
|
||||||
def __rpow__(self, other: TensorNumLike) -> Any:
|
def __rpow__(self, other: TensorNumLike) -> Any:
|
||||||
return self._binary_op(other, lambda a, b: b ** a, commutative=False, reversed=True)
|
return self._binary_op(other, lambda a, b: b ** a, commutative=False, reversed=True)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
# generated by setuptools_scm - do not edit
|
||||||
|
__version__ = "0.0.0"
|
||||||
|
|
@ -4,10 +4,10 @@ and give access to compiler internals and debugging tools.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ._target import add_read_command
|
from ._target import add_read_command
|
||||||
from ._basic_types import Net, Op, Node, CPConstant, Store, stencil_db_from_package
|
from ._basic_types import Net, Op, Node, CPConstant, Write, stencil_db_from_package
|
||||||
from ._compiler import compile_to_dag, \
|
from ._compiler import compile_to_dag, \
|
||||||
stable_toposort, get_const_nets, get_all_dag_edges, add_load_ops, get_all_dag_edges_between, \
|
stable_toposort, get_const_nets, get_all_dag_edges, add_read_ops, get_all_dag_edges_between, \
|
||||||
add_store_ops, get_dag_stats
|
add_write_ops, get_dag_stats
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"add_read_command",
|
"add_read_command",
|
||||||
|
|
@ -15,14 +15,14 @@ __all__ = [
|
||||||
"Op",
|
"Op",
|
||||||
"Node",
|
"Node",
|
||||||
"CPConstant",
|
"CPConstant",
|
||||||
"Store",
|
"Write",
|
||||||
"compile_to_dag",
|
"compile_to_dag",
|
||||||
"stable_toposort",
|
"stable_toposort",
|
||||||
"get_const_nets",
|
"get_const_nets",
|
||||||
"get_all_dag_edges",
|
"get_all_dag_edges",
|
||||||
"get_all_dag_edges_between",
|
"get_all_dag_edges_between",
|
||||||
"add_load_ops",
|
"add_read_ops",
|
||||||
"add_store_ops",
|
"add_write_ops",
|
||||||
"stencil_db_from_package",
|
"stencil_db_from_package",
|
||||||
"get_dag_stats"
|
"get_dag_stats"
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -166,42 +166,8 @@ def get_floordiv(op: str, type1: str, type2: str) -> str:
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
return f"""
|
return f"""
|
||||||
STENCIL void {op}_{type1}_{type2}({type1} a, {type2} b) {{
|
STENCIL void {op}_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
||||||
result_float_{type2}(floorf((float)a / (float)b), b);
|
result_float_{type2}(floorf((float)arg1 / (float)arg2), arg2);
|
||||||
}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@norm_indent
|
|
||||||
def get_min(type1: str, type2: str) -> str:
|
|
||||||
if type1 == 'int' and type2 == 'int':
|
|
||||||
return f"""
|
|
||||||
STENCIL void min_{type1}_{type2}({type1} a, {type2} b) {{
|
|
||||||
result_int_{type2}(a < b ? a : b, b);
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
return f"""
|
|
||||||
STENCIL void min_{type1}_{type2}({type1} a, {type2} b) {{
|
|
||||||
float _a = (float)a; float _b = (float)b;
|
|
||||||
result_float_{type2}(_a < _b ? _a : _b, b);
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@norm_indent
|
|
||||||
def get_max(type1: str, type2: str) -> str:
|
|
||||||
if type1 == 'int' and type2 == 'int':
|
|
||||||
return f"""
|
|
||||||
STENCIL void max_{type1}_{type2}({type1} a, {type2} b) {{
|
|
||||||
result_int_{type2}(a > b ? a : b, b);
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
else:
|
|
||||||
return f"""
|
|
||||||
STENCIL void max_{type1}_{type2}({type1} a, {type2} b) {{
|
|
||||||
float _a = (float)a; float _b = (float)b;
|
|
||||||
result_float_{type2}(_a > _b ? _a : _b, b);
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -221,27 +187,27 @@ def get_result_stubs2(type1: str, type2: str) -> str:
|
||||||
|
|
||||||
|
|
||||||
@norm_indent
|
@norm_indent
|
||||||
def get_load_reg0_code(type1: str, type2: str, type_out: str) -> str:
|
def get_read_reg0_code(type1: str, type2: str, type_out: str) -> str:
|
||||||
return f"""
|
return f"""
|
||||||
STENCIL void load_{type_out}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
STENCIL void read_{type_out}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
||||||
result_{type_out}_{type2}(dummy_{type_out}, arg2);
|
result_{type_out}_{type2}(dummy_{type_out}, arg2);
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@norm_indent
|
@norm_indent
|
||||||
def get_load_reg1_code(type1: str, type2: str, type_out: str) -> str:
|
def get_read_reg1_code(type1: str, type2: str, type_out: str) -> str:
|
||||||
return f"""
|
return f"""
|
||||||
STENCIL void load_{type_out}_reg1_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
STENCIL void read_{type_out}_reg1_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
||||||
result_{type1}_{type_out}(arg1, dummy_{type_out});
|
result_{type1}_{type_out}(arg1, dummy_{type_out});
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@norm_indent
|
@norm_indent
|
||||||
def get_store_code(type1: str, type2: str) -> str:
|
def get_write_code(type1: str, type2: str) -> str:
|
||||||
return f"""
|
return f"""
|
||||||
STENCIL void store_{type1}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
STENCIL void write_{type1}_reg0_{type1}_{type2}({type1} arg1, {type2} arg2) {{
|
||||||
dummy_{type1} = arg1;
|
dummy_{type1} = arg1;
|
||||||
result_{type1}_{type2}(arg1, arg2);
|
result_{type1}_{type2}(arg1, arg2);
|
||||||
}}
|
}}
|
||||||
|
|
@ -302,17 +268,10 @@ if __name__ == "__main__":
|
||||||
code += get_math_func1('fabsf', 'float', 'abs')
|
code += get_math_func1('fabsf', 'float', 'abs')
|
||||||
code += get_custom_stencil('abs_int(int arg1)', 'result_int(__builtin_abs(arg1));')
|
code += get_custom_stencil('abs_int(int arg1)', 'result_int(__builtin_abs(arg1));')
|
||||||
|
|
||||||
for t in types:
|
|
||||||
code += get_custom_stencil(f"sign_{t}({t} arg1)", f"result_int((arg1 > 0) - (arg1 < 0));")
|
|
||||||
|
|
||||||
fnames = ['atan2', 'pow']
|
fnames = ['atan2', 'pow']
|
||||||
for fn, t1, t2 in permutate(fnames, types, types):
|
for fn, t1, t2 in permutate(fnames, types, types):
|
||||||
code += get_math_func2(fn, t1, t2)
|
code += get_math_func2(fn, t1, t2)
|
||||||
|
|
||||||
for t1, t2 in permutate(types, types):
|
|
||||||
code += get_min(t1, t2)
|
|
||||||
code += get_max(t1, t2)
|
|
||||||
|
|
||||||
for op, t1, t2 in permutate(ops, types, types):
|
for op, t1, t2 in permutate(ops, types, types):
|
||||||
t_out = t1 if t1 == t2 else 'float'
|
t_out = t1 if t1 == t2 else 'float'
|
||||||
if op == 'floordiv':
|
if op == 'floordiv':
|
||||||
|
|
@ -330,11 +289,11 @@ if __name__ == "__main__":
|
||||||
code += get_op_code('mod', 'int', 'int', 'int')
|
code += get_op_code('mod', 'int', 'int', 'int')
|
||||||
|
|
||||||
for t1, t2, t_out in permutate(types, types, types):
|
for t1, t2, t_out in permutate(types, types, types):
|
||||||
code += get_load_reg0_code(t1, t2, t_out)
|
code += get_read_reg0_code(t1, t2, t_out)
|
||||||
code += get_load_reg1_code(t1, t2, t_out)
|
code += get_read_reg1_code(t1, t2, t_out)
|
||||||
|
|
||||||
for t1, t2 in permutate(types, types):
|
for t1, t2 in permutate(types, types):
|
||||||
code += get_store_code(t1, t2)
|
code += get_write_code(t1, t2)
|
||||||
|
|
||||||
print(f"Write file {args.path}...")
|
print(f"Write file {args.path}...")
|
||||||
with open(args.path, 'w') as f:
|
with open(args.path, 'w') as f:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import value
|
from copapy import value
|
||||||
from copapy.backend import Store
|
from copapy.backend import Write
|
||||||
import copapy.backend as cpb
|
import copapy.backend as cpb
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,16 +19,16 @@ def test_ast_generation():
|
||||||
#i1 = c1 * 2
|
#i1 = c1 * 2
|
||||||
#r1 = i1 + 7
|
#r1 = i1 + 7
|
||||||
#r2 = i1 + 9
|
#r2 = i1 + 9
|
||||||
#out = [Store(r1), Store(r2)]
|
#out = [Write(r1), Write(r2)]
|
||||||
|
|
||||||
c1 = value(4)
|
c1 = value(4)
|
||||||
c2 = value(2)
|
c2 = value(2)
|
||||||
#i1 = c1 * 2
|
#i1 = c1 * 2
|
||||||
#r1 = i1 + 7 + (c2 + 7 * 9)
|
#r1 = i1 + 7 + (c2 + 7 * 9)
|
||||||
#r2 = i1 + 9
|
#r2 = i1 + 9
|
||||||
#out = [Store(r1), Store(r2)]
|
#out = [Write(r1), Write(r2)]
|
||||||
r1 = c1 * 5 + 8 + c2 * 3
|
r1 = c1 * 5 + 8 + c2 * 3
|
||||||
out = [Store(r1)]
|
out = [Write(r1)]
|
||||||
|
|
||||||
print(out)
|
print(out)
|
||||||
print('-- get_edges:')
|
print('-- get_edges:')
|
||||||
|
|
@ -48,12 +48,12 @@ def test_ast_generation():
|
||||||
print('#', p)
|
print('#', p)
|
||||||
|
|
||||||
print('-- add_read_ops:')
|
print('-- add_read_ops:')
|
||||||
output_ops = list(cpb.add_load_ops(ordered_ops))
|
output_ops = list(cpb.add_read_ops(ordered_ops))
|
||||||
for p in output_ops:
|
for p in output_ops:
|
||||||
print('#', p)
|
print('#', p)
|
||||||
|
|
||||||
print('-- add_write_ops:')
|
print('-- add_write_ops:')
|
||||||
extended_output_ops = list(cpb.add_store_ops(output_ops, const_list))
|
extended_output_ops = list(cpb.add_write_ops(output_ops, const_list))
|
||||||
for p in extended_output_ops:
|
for p in extended_output_ops:
|
||||||
print('#', p)
|
print('#', p)
|
||||||
print('--')
|
print('--')
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ def test_autograd():
|
||||||
c += c + 1
|
c += c + 1
|
||||||
c += 1 + c + (-a)
|
c += 1 + c + (-a)
|
||||||
d += d * 2 + cp.relu(b + a)
|
d += d * 2 + cp.relu(b + a)
|
||||||
d += 3 * d + cp.relu(-a + b)
|
d += 3 * d + cp.relu(b - a)
|
||||||
e = c - d
|
e = c - d
|
||||||
f = e**2
|
f = e**2
|
||||||
g = f / 2.0
|
g = f / 2.0
|
||||||
|
|
@ -34,26 +34,5 @@ def test_autograd():
|
||||||
assert pytest.approx(dg[1], abs=1e-4) == 645.57725 # pyright: ignore[reportUnknownMemberType]
|
assert pytest.approx(dg[1], abs=1e-4) == 645.57725 # pyright: ignore[reportUnknownMemberType]
|
||||||
|
|
||||||
|
|
||||||
def test_autograd_extended():
|
|
||||||
a = value(-4.0)
|
|
||||||
b = value(2.0)
|
|
||||||
c = a + b
|
|
||||||
d = a * b + b**3
|
|
||||||
c += c + 1
|
|
||||||
c += 1 + c + (-a)
|
|
||||||
d += d * 2 + cp.relu(b + a)
|
|
||||||
d += 3 * d + cp.relu(b - a)
|
|
||||||
e = c - cp.sin(-d)
|
|
||||||
f = cp.abs(e**2)
|
|
||||||
g = f / 2.0
|
|
||||||
g += 10.0 / f
|
|
||||||
|
|
||||||
dg = grad(g, (a, b))
|
|
||||||
|
|
||||||
tg = cp.Target()
|
|
||||||
tg.compile(g, dg)
|
|
||||||
tg.run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_autograd()
|
test_autograd()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import value
|
from copapy import value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
|
|
@ -22,7 +22,7 @@ def test_compile():
|
||||||
# Function with no passing-on-jump as last instruction:
|
# Function with no passing-on-jump as last instruction:
|
||||||
ret_test = [r for v in test_vals for r in (cp.tan(value(v)),)]
|
ret_test = [r for v in test_vals for r in (cp.tan(value(v)),)]
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import time
|
import time
|
||||||
from copapy import backend
|
from copapy import backend
|
||||||
from copapy.backend import Store, stencil_db_from_package
|
from copapy.backend import Write, stencil_db_from_package
|
||||||
import copapy.backend as cpb
|
import copapy.backend as cpb
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
import copapy._binwrite as binw
|
import copapy._binwrite as binw
|
||||||
|
|
@ -13,7 +13,7 @@ def test_timing_compiler():
|
||||||
#t2 = t1.sum()
|
#t2 = t1.sum()
|
||||||
t3 = cp.vector(cp.value(1 / (v + 1)) for v in range(256))
|
t3 = cp.vector(cp.value(1 / (v + 1)) for v in range(256))
|
||||||
t5 = ((t3 * t1) * 2).magnitude()
|
t5 = ((t3 * t1) * 2).magnitude()
|
||||||
out = [Store(t5)]
|
out = [Write(t5)]
|
||||||
|
|
||||||
print(out)
|
print(out)
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ def test_timing_compiler():
|
||||||
|
|
||||||
print('-- add_read_ops:')
|
print('-- add_read_ops:')
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
output_ops = list(cpb.add_load_ops(ordered_ops))
|
output_ops = list(cpb.add_read_ops(ordered_ops))
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
#for p in output_ops:
|
#for p in output_ops:
|
||||||
# print('#', p)
|
# print('#', p)
|
||||||
|
|
@ -53,7 +53,7 @@ def test_timing_compiler():
|
||||||
|
|
||||||
print('-- add_write_ops:')
|
print('-- add_write_ops:')
|
||||||
t0 = time.time()
|
t0 = time.time()
|
||||||
extended_output_ops = list(cpb.add_store_ops(output_ops, const_net_list))
|
extended_output_ops = list(cpb.add_write_ops(output_ops, const_net_list))
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
#for p in extended_output_ops:
|
#for p in extended_output_ops:
|
||||||
# print('#', p)
|
# print('#', p)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike
|
from copapy import NumLike
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
import subprocess
|
import subprocess
|
||||||
import struct
|
import struct
|
||||||
|
|
@ -58,7 +58,7 @@ def test_compile():
|
||||||
|
|
||||||
ret = (t2, t4, t5)
|
ret = (t2, t4, t5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike
|
from copapy import NumLike
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -52,7 +52,7 @@ def test_compile():
|
||||||
|
|
||||||
ret = (t2, t4, t5)
|
ret = (t2, t4, t5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('arm64')
|
sdb = backend.stencil_db_from_package('arm64')
|
||||||
il, variables = compile_to_dag(out, sdb)
|
il, variables = compile_to_dag(out, sdb)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike
|
from copapy import NumLike
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -52,7 +52,7 @@ def test_compile():
|
||||||
|
|
||||||
ret = (t2, t4, t5)
|
ret = (t2, t4, t5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('armv7')
|
sdb = backend.stencil_db_from_package('armv7')
|
||||||
il, variables = compile_to_dag(out, sdb)
|
il, variables = compile_to_dag(out, sdb)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import value, NumLike
|
from copapy import value, NumLike
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command, Net
|
||||||
import copapy
|
import copapy
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
|
|
@ -26,7 +26,7 @@ def test_compile():
|
||||||
|
|
||||||
ret = function(c1)
|
ret = function(c1)
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
il, vars = compile_to_dag(out, copapy.generic_sdb)
|
il, vars = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import value
|
from copapy import value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
|
|
@ -21,7 +21,7 @@ def test_compile_sqrt():
|
||||||
ret = [r for v in test_vals for r in (cp.sqrt(value(v)),)]
|
ret = [r for v in test_vals for r in (cp.sqrt(value(v)),)]
|
||||||
|
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
@ -55,7 +55,7 @@ def test_compile_log():
|
||||||
ret = [r for v in test_vals for r in (cp.log(value(v)),)]
|
ret = [r for v in test_vals for r in (cp.log(value(v)),)]
|
||||||
|
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ def test_compile_sin():
|
||||||
ret = [r for v in test_vals for r in (cp.sin(value(v)),)]
|
ret = [r for v in test_vals for r in (cp.sin(value(v)),)]
|
||||||
|
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
il, variables = compile_to_dag(out, copapy.generic_sdb)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import copapy as cp
|
import copapy as cp
|
||||||
from copapy import value
|
from copapy import value
|
||||||
from copapy.backend import get_dag_stats, Store
|
from copapy.backend import get_dag_stats, Write
|
||||||
import copapy.backend as cpb
|
import copapy.backend as cpb
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
def show_dag(val: value[Any]):
|
def show_dag(val: value[Any]):
|
||||||
out = [Store(val.net)]
|
out = [Write(val.net)]
|
||||||
|
|
||||||
print(out)
|
print(out)
|
||||||
print('-- get_edges:')
|
print('-- get_edges:')
|
||||||
|
|
@ -26,12 +26,12 @@ def show_dag(val: value[Any]):
|
||||||
print('#', p)
|
print('#', p)
|
||||||
|
|
||||||
print('-- add_read_ops:')
|
print('-- add_read_ops:')
|
||||||
output_ops = list(cpb.add_load_ops(ordered_ops))
|
output_ops = list(cpb.add_read_ops(ordered_ops))
|
||||||
for p in output_ops:
|
for p in output_ops:
|
||||||
print('#', p)
|
print('#', p)
|
||||||
|
|
||||||
print('-- add_write_ops:')
|
print('-- add_write_ops:')
|
||||||
extended_output_ops = list(cpb.add_store_ops(output_ops, const_list))
|
extended_output_ops = list(cpb.add_write_ops(output_ops, const_list))
|
||||||
for p in extended_output_ops:
|
for p in extended_output_ops:
|
||||||
print('#', p)
|
print('#', p)
|
||||||
print('--')
|
print('--')
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,7 @@ def test_fine():
|
||||||
cp.cos(c_f),
|
cp.cos(c_f),
|
||||||
cp.tan(c_f),
|
cp.tan(c_f),
|
||||||
cp.abs(-c_i),
|
cp.abs(-c_i),
|
||||||
cp.abs(-c_f),
|
cp.abs(-c_f))
|
||||||
cp.sign(c_i),
|
|
||||||
cp.sign(-c_f),
|
|
||||||
cp.min(c_i, 5),
|
|
||||||
cp.max(c_f, 5))
|
|
||||||
|
|
||||||
re2_test = (a_f ** 2,
|
re2_test = (a_f ** 2,
|
||||||
a_i ** -1,
|
a_i ** -1,
|
||||||
|
|
@ -36,11 +32,7 @@ def test_fine():
|
||||||
cp.cos(a_f),
|
cp.cos(a_f),
|
||||||
cp.tan(a_f),
|
cp.tan(a_f),
|
||||||
cp.abs(-a_i),
|
cp.abs(-a_i),
|
||||||
cp.abs(-a_f),
|
cp.abs(-a_f))
|
||||||
cp.sign(a_i),
|
|
||||||
cp.sign(-a_f),
|
|
||||||
cp.min(a_i, 5),
|
|
||||||
cp.max(a_f, 5))
|
|
||||||
|
|
||||||
ret_refe = (a_f ** 2,
|
ret_refe = (a_f ** 2,
|
||||||
a_i ** -1,
|
a_i ** -1,
|
||||||
|
|
@ -51,12 +43,8 @@ def test_fine():
|
||||||
ma.sin(a_f),
|
ma.sin(a_f),
|
||||||
ma.cos(a_f),
|
ma.cos(a_f),
|
||||||
ma.tan(a_f),
|
ma.tan(a_f),
|
||||||
abs(-a_i),
|
cp.abs(-a_i),
|
||||||
abs(-a_f),
|
cp.abs(-a_f))
|
||||||
(a_i > 0) - (a_i < 0),
|
|
||||||
(-a_f > 0) - (-a_f < 0),
|
|
||||||
min(a_i, 5),
|
|
||||||
max(a_f, 5))
|
|
||||||
|
|
||||||
tg = Target()
|
tg = Target()
|
||||||
print('* compile and copy ...')
|
print('* compile and copy ...')
|
||||||
|
|
@ -65,10 +53,10 @@ def test_fine():
|
||||||
tg.run()
|
tg.run()
|
||||||
print('* finished')
|
print('* finished')
|
||||||
|
|
||||||
for test, val2, ref, name in zip(ret_test, re2_test, ret_refe, ['^2', '**-1', 'sqrt_int', 'sqrt_float', 'sin', 'cos', 'tan'] + ['other']*10):
|
for test, val2, ref, name in zip(ret_test, re2_test, ret_refe, ('^2', '**-1', 'sqrt_int', 'sqrt_float', 'sin', 'cos', 'tan')):
|
||||||
assert isinstance(test, cp.value)
|
assert isinstance(test, cp.value)
|
||||||
val = tg.read_value(test)
|
val = tg.read_value(test)
|
||||||
print('+', name, val, ref, type(val), test.dtype)
|
print('+', val, ref, type(val), test.dtype)
|
||||||
#for t in (int, float, bool):
|
#for t in (int, float, bool):
|
||||||
# assert isinstance(val, t) == isinstance(ref, t), f"Result type does not match for {val} and {ref}"
|
# assert isinstance(val, t) == isinstance(ref, t), f"Result type does not match for {val} and {ref}"
|
||||||
assert val == pytest.approx(ref, abs=1e-3), f"Result for {name} does not match: {val} and reference: {ref}" # pyright: ignore[reportUnknownMemberType]
|
assert val == pytest.approx(ref, abs=1e-3), f"Result for {name} does not match: {val} and reference: {ref}" # pyright: ignore[reportUnknownMemberType]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike, iif, value
|
from copapy import NumLike, iif, value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -91,7 +91,7 @@ def test_compile():
|
||||||
ret_test = function1(c_i) + function1(c_f) + function2(c_i) + function2(c_f) + function3(c_i) + function4(c_i) + function5(c_b) + [value(9) % 2] + iiftests(c_i) + iiftests(c_f) + [cp.asin(c_i/10)]
|
ret_test = function1(c_i) + function1(c_f) + function2(c_i) + function2(c_f) + function3(c_i) + function4(c_i) + function5(c_b) + [value(9) % 2] + iiftests(c_i) + iiftests(c_f) + [cp.asin(c_i/10)]
|
||||||
ret_ref = function1(9) + function1(1.111) + function2(9) + function2(1.111) + function3(9) + function4(9) + function5(True) + [9 % 2] + iiftests(9) + iiftests(1.111) + [cp.asin(9/10)]
|
ret_ref = function1(9) + function1(1.111) + function2(9) + function2(1.111) + function3(9) + function4(9) + function5(True) + [9 % 2] + iiftests(9) + iiftests(1.111) + [cp.asin(9/10)]
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
#ret_test += [c_i, v2]
|
#ret_test += [c_i, v2]
|
||||||
#ret_ref += [9, 4.44, -4.44]
|
#ret_ref += [9, 4.44, -4.44]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike, iif, value
|
from copapy import NumLike, iif, value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -96,7 +96,7 @@ def test_compile():
|
||||||
#ret_test = (c_i * 100 // 5, c_f * 10 // 5)
|
#ret_test = (c_i * 100 // 5, c_f * 10 // 5)
|
||||||
#ret_ref = (9 * 100 // 5, 1.111 * 10 // 5)
|
#ret_ref = (9 * 100 // 5, 1.111 * 10 // 5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('armv6')
|
sdb = backend.stencil_db_from_package('armv6')
|
||||||
dw, variables = compile_to_dag(out, sdb)
|
dw, variables = compile_to_dag(out, sdb)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike, iif, value
|
from copapy import NumLike, iif, value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -96,7 +96,7 @@ def test_compile():
|
||||||
#ret_test = (c_i * 100 // 5, c_f * 10 // 5)
|
#ret_test = (c_i * 100 // 5, c_f * 10 // 5)
|
||||||
#ret_ref = (9 * 100 // 5, 1.111 * 10 // 5)
|
#ret_ref = (9 * 100 // 5, 1.111 * 10 // 5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('armv7')
|
sdb = backend.stencil_db_from_package('armv7')
|
||||||
dw, variables = compile_to_dag(out, sdb)
|
dw, variables = compile_to_dag(out, sdb)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import NumLike, iif, value
|
from copapy import NumLike, iif, value
|
||||||
from copapy.backend import Store, compile_to_dag, add_read_command
|
from copapy.backend import Write, compile_to_dag, add_read_command
|
||||||
import subprocess
|
import subprocess
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
import copapy.backend as backend
|
import copapy.backend as backend
|
||||||
|
|
@ -104,7 +104,7 @@ def test_compile():
|
||||||
#ret_test = [cp.get_42(c_i)]
|
#ret_test = [cp.get_42(c_i)]
|
||||||
#ret_ref = [cp.get_42(9)]
|
#ret_ref = [cp.get_42(9)]
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
#ret_test += [c_i, v2]
|
#ret_test += [c_i, v2]
|
||||||
#ret_ref += [9, 4.44, -4.44]
|
#ret_ref += [9, 4.44, -4.44]
|
||||||
|
|
@ -185,7 +185,7 @@ def test_vector_compile():
|
||||||
|
|
||||||
ret = (t2, t4, t5)
|
ret = (t2, t4, t5)
|
||||||
|
|
||||||
out = [Store(r) for r in ret]
|
out = [Write(r) for r in ret]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('x86')
|
sdb = backend.stencil_db_from_package('x86')
|
||||||
il, variables = compile_to_dag(out, sdb)
|
il, variables = compile_to_dag(out, sdb)
|
||||||
|
|
@ -243,7 +243,7 @@ def test_sinus():
|
||||||
ret_test = [si, e]
|
ret_test = [si, e]
|
||||||
ret_ref = [cp.sin(a_val), (a_val + 0.87 * 2.0) ** 2 + cp.sin(a_val) + cp.sqrt(0.87)]
|
ret_ref = [cp.sin(a_val), (a_val + 0.87 * 2.0) ** 2 + cp.sin(a_val) + cp.sqrt(0.87)]
|
||||||
|
|
||||||
out = [Store(r) for r in ret_test]
|
out = [Write(r) for r in ret_test]
|
||||||
|
|
||||||
sdb = backend.stencil_db_from_package('x86')
|
sdb = backend.stencil_db_from_package('x86')
|
||||||
dw, variables = compile_to_dag(out, sdb)
|
dw, variables = compile_to_dag(out, sdb)
|
||||||
|
|
|
||||||
144
tools/build.bat
144
tools/build.bat
|
|
@ -1,156 +1,68 @@
|
||||||
@echo off
|
|
||||||
setlocal ENABLEDELAYEDEXPANSION
|
|
||||||
|
|
||||||
set ARCH=%1
|
|
||||||
if "%ARCH%"=="" set ARCH=x86_64
|
|
||||||
|
|
||||||
if not "%ARCH%"=="x86_64" ^
|
|
||||||
if not "%ARCH%"=="x86" ^
|
|
||||||
if not "%ARCH%"=="arm64" ^
|
|
||||||
if not "%ARCH%"=="arm-v6" ^
|
|
||||||
if not "%ARCH%"=="arm-v7" ^
|
|
||||||
if not "%ARCH%"=="all" (
|
|
||||||
echo Usage: %0 [x86_64^|x86^|arm64^|arm-v6^|arm-v7^|all]
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
mkdir build\stencils
|
mkdir build\stencils
|
||||||
mkdir build\runner
|
mkdir build\runner
|
||||||
|
python stencils/generate_stencils.py build/stencils/stencils.c
|
||||||
|
|
||||||
python stencils/generate_stencils.py build\stencils\stencils.c
|
|
||||||
|
|
||||||
REM ============================================================
|
|
||||||
REM x86_64
|
|
||||||
REM ============================================================
|
|
||||||
if "%ARCH%"=="x86_64" goto BUILD_X86_64
|
|
||||||
if "%ARCH%"=="all" goto BUILD_X86_64
|
|
||||||
goto SKIP_X86_64
|
|
||||||
|
|
||||||
:BUILD_X86_64
|
|
||||||
echo -------------x86_64 - 64 bit-----------------
|
echo -------------x86_64 - 64 bit-----------------
|
||||||
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
|
call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||||
|
|
||||||
echo - Compile stencil test...
|
echo - Compile stencil test...
|
||||||
cl /Zi /Od stencils\test.c /Fe:build\stencils\test.exe
|
cl /Zi /Od stencils\test.c /Fe:build\stencils\test.exe
|
||||||
|
|
||||||
echo - Build runner for Windows 64 bit...
|
echo - Build runner for Windows 64 bit...
|
||||||
cl /Zi /Od /DENABLE_BASIC_LOGGING ^
|
cl /Zi /Od /DENABLE_BASIC_LOGGING src\coparun\runmem.c src\coparun\coparun.c src\coparun\mem_man.c /Fe:build\runner\coparun.exe
|
||||||
src\coparun\runmem.c ^
|
|
||||||
src\coparun\coparun.c ^
|
|
||||||
src\coparun\mem_man.c ^
|
|
||||||
/Fe:build\runner\coparun.exe
|
|
||||||
|
|
||||||
echo - Build stencils for x86_64...
|
REM Optimized:
|
||||||
|
REM cl /O2 src\coparun\runmem.c src\coparun\coparun.c src\coparun\mem_man.c /Fe:build\runner\coparun.exe
|
||||||
|
|
||||||
|
echo - Build stencils for 64 bit...
|
||||||
|
REM ../copapy/tools/cross_compiler_unix/packobjs.sh gcc ld ../copapy/build/musl/musl_objects_x86_64.o
|
||||||
wsl gcc -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
wsl gcc -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
||||||
wsl ld -r build/stencils/stencils.o build/musl/musl_objects_x86_64.o -o src/copapy/obj/stencils_x86_64_O3.o
|
wsl ld -r build/stencils/stencils.o build/musl/musl_objects_x86_64.o -o src/copapy/obj/stencils_x86_64_O3.o
|
||||||
wsl objdump -d -x src/copapy/obj/stencils_x86_64_O3.o > build/stencils/stencils_x86_64_O3.asm
|
wsl objdump -d -x src/copapy/obj/stencils_x86_64_O3.o > build/stencils/stencils_x86_64_O3.asm
|
||||||
|
|
||||||
:SKIP_X86_64
|
echo ---------------x86 - 32 bit---------------
|
||||||
|
|
||||||
REM ============================================================
|
|
||||||
REM x86 32-bit
|
|
||||||
REM ============================================================
|
|
||||||
if "%ARCH%"=="x86" goto BUILD_X86
|
|
||||||
if "%ARCH%"=="all" goto BUILD_X86
|
|
||||||
goto SKIP_X86
|
|
||||||
|
|
||||||
:BUILD_X86
|
|
||||||
echo ---------------x86 - 32 bit----------------
|
|
||||||
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x86
|
call "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x86
|
||||||
|
|
||||||
echo - Build runner for Windows 32 bit...
|
echo - Build runner for Windows 32 bit...
|
||||||
cl /Zi /Od /DENABLE_LOGGING ^
|
cl /Zi /Od /DENABLE_LOGGING src\coparun\runmem.c src\coparun\coparun.c src\coparun\mem_man.c /Fe:build\runner\coparun-x86.exe
|
||||||
src\coparun\runmem.c ^
|
|
||||||
src\coparun\coparun.c ^
|
|
||||||
src\coparun\mem_man.c ^
|
|
||||||
/Fe:build\runner\coparun-x86.exe
|
|
||||||
|
|
||||||
echo - Build runner for Linux x86 32 bit...
|
echo - Build runner for linux x86 32 bit...
|
||||||
wsl i686-linux-gnu-gcc-12 -static -O3 -DENABLE_LOGGING ^
|
wsl i686-linux-gnu-gcc-12 -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-x86
|
||||||
src/coparun/runmem.c ^
|
|
||||||
src/coparun/coparun.c ^
|
|
||||||
src/coparun/mem_man.c ^
|
|
||||||
-o build/runner/coparun-x86
|
|
||||||
|
|
||||||
echo - Build stencils x86 32 bit...
|
echo - Build stencils x86 32 bit...
|
||||||
|
REM sh ../copapy/tools/cross_compiler_unix/packobjs.sh i686-linux-gnu-gcc-12 i686-linux-gnu-ld ../copapy/build/musl/musl_objects_x86.o -fno-pic
|
||||||
wsl i686-linux-gnu-gcc-12 -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
wsl i686-linux-gnu-gcc-12 -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
||||||
wsl i686-linux-gnu-ld -r build/stencils/stencils.o build/musl/musl_objects_x86.o -o src/copapy/obj/stencils_x86_O3.o
|
wsl i686-linux-gnu-ld -r build/stencils/stencils.o build/musl/musl_objects_x86.o -o src/copapy/obj/stencils_x86_O3.o
|
||||||
wsl i686-linux-gnu-objdump -d -x src/copapy/obj/stencils_x86_O3.o > build/stencils/stencils_x86_O3.asm
|
wsl i686-linux-gnu-objdump -d -x src/copapy/obj/stencils_x86_O3.o > build/stencils/stencils_x86_O3.asm
|
||||||
|
|
||||||
:SKIP_X86
|
|
||||||
|
|
||||||
REM ============================================================
|
|
||||||
REM ARM64
|
|
||||||
REM ============================================================
|
|
||||||
if "%ARCH%"=="arm64" goto BUILD_ARM64
|
|
||||||
if "%ARCH%"=="all" goto BUILD_ARM64
|
|
||||||
goto SKIP_ARM64
|
|
||||||
|
|
||||||
:BUILD_ARM64
|
|
||||||
echo --------------arm64 64 bit----------------
|
echo --------------arm64 64 bit----------------
|
||||||
|
|
||||||
wsl aarch64-linux-gnu-gcc-12 -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
wsl aarch64-linux-gnu-gcc-12 -fno-pic -ffunction-sections -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
||||||
wsl aarch64-linux-gnu-ld -r build/stencils/stencils.o build/musl/musl_objects_arm64.o -o src/copapy/obj/stencils_arm64_O3.o
|
wsl aarch64-linux-gnu-ld -r build/stencils/stencils.o build/musl/musl_objects_arm64.o -o src/copapy/obj/stencils_arm64_O3.o
|
||||||
wsl aarch64-linux-gnu-objdump -d -x src/copapy/obj/stencils_arm64_O3.o > build/stencils/stencils_arm64_O3.asm
|
wsl aarch64-linux-gnu-objdump -d -x src/copapy/obj/stencils_arm64_O3.o > build/stencils/stencils_arm64_O3.asm
|
||||||
|
echo ------------------------------
|
||||||
|
echo - Build runner for Aarch64...
|
||||||
|
wsl aarch64-linux-gnu-gcc-12 -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-aarch64
|
||||||
|
|
||||||
echo - Build runner for AArch64...
|
|
||||||
wsl aarch64-linux-gnu-gcc-12 -static -O3 -DENABLE_LOGGING ^
|
|
||||||
src/coparun/runmem.c ^
|
|
||||||
src/coparun/coparun.c ^
|
|
||||||
src/coparun/mem_man.c ^
|
|
||||||
-o build/runner/coparun-aarch64
|
|
||||||
|
|
||||||
:SKIP_ARM64
|
|
||||||
|
|
||||||
REM ============================================================
|
|
||||||
REM ARM v6
|
|
||||||
REM ============================================================
|
|
||||||
if "%ARCH%"=="arm-v6" goto BUILD_ARMV6
|
|
||||||
if "%ARCH%"=="all" goto BUILD_ARMV6
|
|
||||||
goto SKIP_ARMV6
|
|
||||||
|
|
||||||
:BUILD_ARMV6
|
|
||||||
echo --------------arm-v6 32 bit----------------
|
echo --------------arm-v6 32 bit----------------
|
||||||
|
REM sh ../copapy/tools/cross_compiler_unix/packobjs.sh arm-none-eabi-gcc arm-none-eabi-ld ../copapy/build/musl/musl_objects_armv6.o "-march=armv6 -mfpu=vfp -marm"
|
||||||
wsl arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv6 -mfpu=vfp -mfloat-abi=hard -marm ^
|
wsl arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv6 -mfpu=vfp -mfloat-abi=hard -marm -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
||||||
-c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
wsl arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv6.o $(arm-none-eabi-gcc -print-libgcc-file-name) -o src/copapy/obj/stencils_armv6_O3.o
|
||||||
|
|
||||||
wsl arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv6.o ^
|
|
||||||
$(arm-none-eabi-gcc -print-libgcc-file-name) ^
|
|
||||||
-o src/copapy/obj/stencils_armv6_O3.o
|
|
||||||
|
|
||||||
wsl arm-none-eabi-objdump -d -x src/copapy/obj/stencils_armv6_O3.o > build/stencils/stencils_armv6_O3.asm
|
wsl arm-none-eabi-objdump -d -x src/copapy/obj/stencils_armv6_O3.o > build/stencils/stencils_armv6_O3.asm
|
||||||
|
echo ------------------------------
|
||||||
|
REM echo - Build runner
|
||||||
|
REM wsl arm-linux-gnueabihf-gcc -march=armv6 -mfpu=vfp -marm -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-armv6
|
||||||
|
|
||||||
:SKIP_ARMV6
|
|
||||||
|
|
||||||
REM ============================================================
|
|
||||||
REM ARM v7
|
|
||||||
REM ============================================================
|
|
||||||
if "%ARCH%"=="arm-v7" goto BUILD_ARMV7
|
|
||||||
if "%ARCH%"=="all" goto BUILD_ARMV7
|
|
||||||
goto END
|
|
||||||
|
|
||||||
:BUILD_ARMV7
|
|
||||||
echo --------------arm-v7 32 bit----------------
|
echo --------------arm-v7 32 bit----------------
|
||||||
|
REM sh ../copapy/tools/cross_compiler_unix/packobjs.sh arm-none-eabi-gcc arm-none-eabi-ld ../copapy/build/musl/musl_objects_armv7.o "-march=armv7-a -mfpu=neon-vfpv3 -marm"
|
||||||
wsl arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm ^
|
wsl arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm -c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
||||||
-c build/stencils/stencils.c -O3 -o build/stencils/stencils.o
|
wsl arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv7.o $(arm-none-eabi-gcc -print-libgcc-file-name) -o src/copapy/obj/stencils_armv7_O3.o
|
||||||
|
|
||||||
wsl arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv7.o ^
|
|
||||||
$(arm-none-eabi-gcc -print-libgcc-file-name) ^
|
|
||||||
-o src/copapy/obj/stencils_armv7_O3.o
|
|
||||||
|
|
||||||
wsl arm-none-eabi-objdump -d -x src/copapy/obj/stencils_armv7_O3.o > build/stencils/stencils_armv7_O3.asm
|
wsl arm-none-eabi-objdump -d -x src/copapy/obj/stencils_armv7_O3.o > build/stencils/stencils_armv7_O3.asm
|
||||||
|
|
||||||
echo - Build runner for ARM v7...
|
|
||||||
wsl arm-linux-gnueabihf-gcc -static -O3 -DENABLE_LOGGING ^
|
|
||||||
src/coparun/runmem.c ^
|
|
||||||
src/coparun/coparun.c ^
|
|
||||||
src/coparun/mem_man.c ^
|
|
||||||
-o build/runner/coparun-armv7
|
|
||||||
|
|
||||||
:END
|
echo ------------------------------
|
||||||
echo Build completed for %ARCH%
|
echo - Build runner
|
||||||
endlocal
|
wsl arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=neon-vfpv3 -marm -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-armv7
|
||||||
|
|
||||||
|
|
|
||||||
104
tools/build.sh
104
tools/build.sh
|
|
@ -1,16 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eux
|
set -e
|
||||||
|
set -v
|
||||||
ARCH=${1:-x86_64}
|
|
||||||
|
|
||||||
case "$ARCH" in
|
|
||||||
(x86_64|arm-v6|arm-v7|all)
|
|
||||||
;;
|
|
||||||
(*)
|
|
||||||
echo "Usage: $0 [x86_64|arm-v6|arm-v7|all]"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
mkdir -p build/stencils
|
mkdir -p build/stencils
|
||||||
mkdir -p build/runner
|
mkdir -p build/runner
|
||||||
|
|
@ -20,90 +10,34 @@ DEST=src/copapy/obj
|
||||||
python3 stencils/generate_stencils.py $SRC
|
python3 stencils/generate_stencils.py $SRC
|
||||||
mkdir -p $DEST
|
mkdir -p $DEST
|
||||||
|
|
||||||
#######################################
|
|
||||||
# x86_64
|
|
||||||
#######################################
|
|
||||||
if [[ "$ARCH" == "x86_64" || "$ARCH" == "all" ]]; then
|
|
||||||
echo "--------------x86_64----------------"
|
|
||||||
|
|
||||||
gcc -fno-pic -ffunction-sections -c $SRC -O3 -o build/stencils/stencils.o
|
gcc -fno-pic -ffunction-sections -c $SRC -O3 -o build/stencils/stencils.o
|
||||||
ld -r build/stencils/stencils.o build/musl/musl_objects_x86_64.o \
|
ld -r build/stencils/stencils.o build/musl/musl_objects_x86_64.o -o $DEST/stencils_x86_64_O3.o
|
||||||
-o $DEST/stencils_x86_64_O3.o
|
objdump -d -x $DEST/stencils_x86_64_O3.o > build/stencils/stencils_x86_64_O3.asm
|
||||||
objdump -d -x $DEST/stencils_x86_64_O3.o \
|
|
||||||
> build/stencils/stencils_x86_64_O3.asm
|
|
||||||
|
|
||||||
mkdir -p bin
|
mkdir bin -p
|
||||||
gcc -Wall -Wextra -Wconversion -Wsign-conversion \
|
gcc -Wall -Wextra -Wconversion -Wsign-conversion \
|
||||||
-Wshadow -Wstrict-overflow -Werror -g -O3 \
|
-Wshadow -Wstrict-overflow -Werror -g -O3 \
|
||||||
-DENABLE_LOGGING \
|
-DENABLE_LOGGING \
|
||||||
src/coparun/runmem.c \
|
src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun
|
||||||
src/coparun/coparun.c \
|
|
||||||
src/coparun/mem_man.c \
|
|
||||||
-o build/runner/coparun
|
|
||||||
fi
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# ARM v6
|
|
||||||
#######################################
|
|
||||||
if [[ "$ARCH" == "arm-v6" || "$ARCH" == "all" ]]; then
|
|
||||||
echo "--------------arm-v6 32 bit----------------"
|
echo "--------------arm-v6 32 bit----------------"
|
||||||
|
|
||||||
LIBGCC=$(arm-none-eabi-gcc -print-libgcc-file-name)
|
LIBGCC=$(arm-none-eabi-gcc -print-libgcc-file-name)
|
||||||
|
#LIBM=$(arm-none-eabi-gcc -print-file-name=libm.a)
|
||||||
|
#LIBC=$(arm-none-eabi-gcc -print-file-name=libc.a)
|
||||||
|
|
||||||
arm-none-eabi-gcc -fno-pic -ffunction-sections \
|
arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv6 -mfpu=vfp -mfloat-abi=hard -marm -c $SRC -O3 -o build/stencils/stencils.o
|
||||||
-march=armv6 -mfpu=vfp -mfloat-abi=hard -marm \
|
arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv6.o $LIBGCC -o $DEST/stencils_armv6_O3.o
|
||||||
-c $SRC -O3 -o build/stencils/stencils.o
|
arm-none-eabi-objdump -d -x $DEST/stencils_armv6_O3.o > build/stencils/stencils_armv6_O3.asm
|
||||||
|
arm-linux-gnueabihf-gcc -march=armv6 -mfpu=vfp -mfloat-abi=hard -marm -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-armv6
|
||||||
|
|
||||||
arm-none-eabi-ld -r \
|
|
||||||
build/stencils/stencils.o \
|
|
||||||
build/musl/musl_objects_armv6.o \
|
|
||||||
$LIBGCC \
|
|
||||||
-o $DEST/stencils_armv6_O3.o
|
|
||||||
|
|
||||||
arm-none-eabi-objdump -d -x \
|
|
||||||
$DEST/stencils_armv6_O3.o \
|
|
||||||
> build/stencils/stencils_armv6_O3.asm
|
|
||||||
|
|
||||||
arm-linux-gnueabihf-gcc \
|
|
||||||
-march=armv6 -mfpu=vfp -mfloat-abi=hard -marm -static \
|
|
||||||
-Wall -Wextra -Wconversion -Wsign-conversion \
|
|
||||||
-Wshadow -Wstrict-overflow -O3 \
|
|
||||||
-DENABLE_LOGGING \
|
|
||||||
src/coparun/runmem.c \
|
|
||||||
src/coparun/coparun.c \
|
|
||||||
src/coparun/mem_man.c \
|
|
||||||
-o build/runner/coparun-armv6
|
|
||||||
fi
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# ARM v7
|
|
||||||
#######################################
|
|
||||||
if [[ "$ARCH" == "arm-v7" || "$ARCH" == "all" ]]; then
|
|
||||||
echo "--------------arm-v7 32 bit----------------"
|
echo "--------------arm-v7 32 bit----------------"
|
||||||
|
|
||||||
LIBGCC=$(arm-none-eabi-gcc -print-libgcc-file-name)
|
LIBGCC=$(arm-none-eabi-gcc -print-libgcc-file-name)
|
||||||
|
#LIBM=$(arm-none-eabi-gcc -print-file-name=libm.a)
|
||||||
|
#LIBC=$(arm-none-eabi-gcc -print-file-name=libc.a)
|
||||||
|
|
||||||
arm-none-eabi-gcc -fno-pic -ffunction-sections \
|
arm-none-eabi-gcc -fno-pic -ffunction-sections -march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm -c $SRC -O3 -o build/stencils/stencils.o
|
||||||
-march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm \
|
arm-none-eabi-ld -r build/stencils/stencils.o build/musl/musl_objects_armv7.o $LIBGCC -o $DEST/stencils_armv7_O3.o
|
||||||
-c $SRC -O3 -o build/stencils/stencils.o
|
arm-none-eabi-objdump -d -x $DEST/stencils_armv7_O3.o > build/stencils/stencils_armv7_O3.asm
|
||||||
|
arm-linux-gnueabihf-gcc -march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm -static -Wall -Wextra -Wconversion -Wsign-conversion -Wshadow -Wstrict-overflow -O3 -DENABLE_LOGGING src/coparun/runmem.c src/coparun/coparun.c src/coparun/mem_man.c -o build/runner/coparun-armv7
|
||||||
arm-none-eabi-ld -r \
|
|
||||||
build/stencils/stencils.o \
|
|
||||||
build/musl/musl_objects_armv7.o \
|
|
||||||
$LIBGCC \
|
|
||||||
-o $DEST/stencils_armv7_O3.o
|
|
||||||
|
|
||||||
arm-none-eabi-objdump -d -x \
|
|
||||||
$DEST/stencils_armv7_O3.o \
|
|
||||||
> build/stencils/stencils_armv7_O3.asm
|
|
||||||
|
|
||||||
arm-linux-gnueabihf-gcc \
|
|
||||||
-march=armv7-a -mfpu=neon-vfpv3 -mfloat-abi=hard -marm -static \
|
|
||||||
-Wall -Wextra -Wconversion -Wsign-conversion \
|
|
||||||
-Wshadow -Wstrict-overflow -O3 \
|
|
||||||
-DENABLE_LOGGING \
|
|
||||||
src/coparun/runmem.c \
|
|
||||||
src/coparun/coparun.c \
|
|
||||||
src/coparun/mem_man.c \
|
|
||||||
-o build/runner/coparun-armv7
|
|
||||||
fi
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from copapy import value
|
from copapy import value
|
||||||
from copapy.backend import Store, compile_to_dag, stencil_db_from_package
|
from copapy.backend import Write, compile_to_dag, stencil_db_from_package
|
||||||
from copapy._binwrite import Command
|
from copapy._binwrite import Command
|
||||||
|
|
||||||
input = value(9.0)
|
input = value(9.0)
|
||||||
|
|
@ -8,7 +8,7 @@ result = input ** 2 / 3.3 + 5
|
||||||
|
|
||||||
arch = 'native'
|
arch = 'native'
|
||||||
sdb = stencil_db_from_package(arch)
|
sdb = stencil_db_from_package(arch)
|
||||||
dw, _ = compile_to_dag([Store(result)], sdb)
|
dw, _ = compile_to_dag([Write(result)], sdb)
|
||||||
|
|
||||||
# Instruct runner to dump patched code to a file:
|
# Instruct runner to dump patched code to a file:
|
||||||
dw.write_com(Command.DUMP_CODE)
|
dw.write_com(Command.DUMP_CODE)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue