mirror of https://github.com/Nonannet/copapy.git
Merge branch 'main' into vector_feature
This commit is contained in:
commit
38a0959c82
|
|
@ -38,7 +38,7 @@ dev = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.mypy]
|
[tool.mypy]
|
||||||
files = ["src", "tools"]
|
files = ["src", "tools", "stencils"]
|
||||||
strict = true
|
strict = true
|
||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
warn_unused_configs = true
|
warn_unused_configs = true
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
from ._target import Target
|
from ._target import Target
|
||||||
from ._basic_types import NumLike, cpbool, cpfloat, cpint, \
|
from ._basic_types import NumLike, variable, \
|
||||||
CPNumber, cpvalue, cpvector, generic_sdb, iif
|
CPNumber, cpvector, generic_sdb, iif
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Target",
|
"Target",
|
||||||
"NumLike",
|
"NumLike",
|
||||||
"cpbool",
|
"variable",
|
||||||
"cpfloat",
|
|
||||||
"cpint",
|
|
||||||
"CPNumber",
|
"CPNumber",
|
||||||
"cpvalue",
|
|
||||||
"cpvector",
|
"cpvector",
|
||||||
"generic_sdb",
|
"generic_sdb",
|
||||||
"iif",
|
"iif",
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
import pkgutil
|
import pkgutil
|
||||||
from typing import Any, TypeVar, overload, TypeAlias
|
from typing import Any, TypeVar, overload, TypeAlias, Generic, cast
|
||||||
from ._stencils import stencil_database
|
from ._stencils import stencil_database
|
||||||
import platform
|
import platform
|
||||||
|
|
||||||
NumLike: TypeAlias = 'cpint | cpfloat | cpbool | int | float| bool'
|
NumLike: TypeAlias = 'variable[int] | variable[float] | variable[bool] | int | float | bool'
|
||||||
NumLikeAndNet: TypeAlias = 'cpint | cpfloat | cpbool | int | float | bool | Net'
|
NumLikeAndNet: TypeAlias = 'variable[int] | variable[float] | variable[bool] | int | float | bool | Net'
|
||||||
NetAndNum: TypeAlias = 'Net | int | float'
|
NetAndNum: TypeAlias = 'Net | int | float'
|
||||||
|
|
||||||
unifloat: TypeAlias = 'cpfloat | float'
|
unifloat: TypeAlias = 'variable[float] | float'
|
||||||
uniint: TypeAlias = 'cpint | int'
|
uniint: TypeAlias = 'variable[int] | int'
|
||||||
unibool: TypeAlias = 'cpbool | bool'
|
unibool: TypeAlias = 'variable[bool] | bool'
|
||||||
|
|
||||||
TNumber = TypeVar("TNumber", bound='CPNumber')
|
TNumber = TypeVar("TNumber", bound='CPNumber')
|
||||||
T = TypeVar("T")
|
T = TypeVar("T")
|
||||||
|
|
@ -40,7 +40,7 @@ class Node:
|
||||||
self.name: str = ''
|
self.name: str = ''
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"Node:{self.name}({', '.join(str(a) for a in self.args) if self.args else (self.value if isinstance(self, InitVar) else '')})"
|
return f"Node:{self.name}({', '.join(str(a) for a in self.args) if self.args else (self.value if isinstance(self, CPConstant) else '')})"
|
||||||
|
|
||||||
|
|
||||||
class Device():
|
class Device():
|
||||||
|
|
@ -70,7 +70,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __mul__(self, other: unifloat) -> 'cpfloat':
|
def __mul__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __mul__(self, other: NumLike) -> 'CPNumber':
|
def __mul__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -81,7 +81,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rmul__(self, other: unifloat) -> 'cpfloat':
|
def __rmul__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __rmul__(self, other: NumLike) -> 'CPNumber':
|
def __rmul__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -92,7 +92,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __add__(self, other: unifloat) -> 'cpfloat':
|
def __add__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __add__(self, other: NumLike) -> 'CPNumber':
|
def __add__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -103,7 +103,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __radd__(self, other: unifloat) -> 'cpfloat':
|
def __radd__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __radd__(self, other: NumLike) -> 'CPNumber':
|
def __radd__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -114,7 +114,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __sub__(self, other: unifloat) -> 'cpfloat':
|
def __sub__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __sub__(self, other: NumLike) -> 'CPNumber':
|
def __sub__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -125,28 +125,24 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rsub__(self, other: unifloat) -> 'cpfloat':
|
def __rsub__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __rsub__(self, other: NumLike) -> 'CPNumber':
|
def __rsub__(self, other: NumLike) -> 'CPNumber':
|
||||||
return _add_op('sub', [other, self])
|
return _add_op('sub', [other, self])
|
||||||
|
|
||||||
def __truediv__(self, other: NumLike) -> 'cpfloat':
|
def __truediv__(self, other: NumLike) -> 'variable[float]':
|
||||||
ret = _add_op('div', [self, other])
|
return _add_op('div', [self, other])
|
||||||
assert isinstance(ret, cpfloat)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rtruediv__(self, other: NumLike) -> 'cpfloat':
|
def __rtruediv__(self, other: NumLike) -> 'variable[float]':
|
||||||
ret = _add_op('div', [other, self])
|
return _add_op('div', [other, self])
|
||||||
assert isinstance(ret, cpfloat)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __floordiv__(self: TNumber, other: uniint) -> TNumber:
|
def __floordiv__(self: TNumber, other: uniint) -> TNumber:
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __floordiv__(self, other: unifloat) -> 'cpfloat':
|
def __floordiv__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __floordiv__(self, other: NumLike) -> 'CPNumber':
|
def __floordiv__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -157,39 +153,38 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rfloordiv__(self, other: unifloat) -> 'cpfloat':
|
def __rfloordiv__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __rfloordiv__(self, other: NumLike) -> 'CPNumber':
|
def __rfloordiv__(self, other: NumLike) -> 'CPNumber':
|
||||||
return _add_op('floordiv', [other, self])
|
return _add_op('floordiv', [other, self])
|
||||||
|
|
||||||
def __neg__(self: TNumber) -> TNumber:
|
def __neg__(self: TNumber) -> TNumber:
|
||||||
ret = _add_op('sub', [cpvalue(0), self])
|
assert isinstance(T, variable)
|
||||||
assert isinstance(ret, type(self))
|
return cast(TNumber, _add_op('sub', [variable(0), self]))
|
||||||
return ret
|
|
||||||
|
|
||||||
def __gt__(self, other: NumLike) -> 'cpbool':
|
def __gt__(self, other: NumLike) -> 'variable[bool]':
|
||||||
ret = _add_op('gt', [self, other])
|
ret = _add_op('gt', [self, other])
|
||||||
return cpbool(ret.source)
|
return variable(ret.source, dtype='bool')
|
||||||
|
|
||||||
def __lt__(self, other: NumLike) -> 'cpbool':
|
def __lt__(self, other: NumLike) -> 'variable[bool]':
|
||||||
ret = _add_op('gt', [other, self])
|
ret = _add_op('gt', [other, self])
|
||||||
return cpbool(ret.source)
|
return variable(ret.source, dtype='bool')
|
||||||
|
|
||||||
def __eq__(self, other: NumLike) -> 'cpbool': # type: ignore
|
def __eq__(self, other: NumLike) -> 'variable[bool]': # type: ignore
|
||||||
ret = _add_op('eq', [self, other], True)
|
ret = _add_op('eq', [self, other], True)
|
||||||
return cpbool(ret.source)
|
return variable(ret.source, dtype='bool')
|
||||||
|
|
||||||
def __ne__(self, other: NumLike) -> 'cpbool': # type: ignore
|
def __ne__(self, other: NumLike) -> 'variable[bool]': # type: ignore
|
||||||
ret = _add_op('ne', [self, other], True)
|
ret = _add_op('ne', [self, other], True)
|
||||||
return cpbool(ret.source)
|
return variable(ret.source, dtype='bool')
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __mod__(self: TNumber, other: uniint) -> TNumber:
|
def __mod__(self: TNumber, other: uniint) -> TNumber:
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __mod__(self, other: unifloat) -> 'cpfloat':
|
def __mod__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __mod__(self, other: NumLike) -> 'CPNumber':
|
def __mod__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -200,7 +195,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rmod__(self, other: unifloat) -> 'cpfloat':
|
def __rmod__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __rmod__(self, other: NumLike) -> 'CPNumber':
|
def __rmod__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -211,7 +206,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __pow__(self, other: unifloat) -> 'cpfloat':
|
def __pow__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __pow__(self, other: NumLike) -> 'CPNumber':
|
def __pow__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -222,7 +217,7 @@ class CPNumber(Net):
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def __rpow__(self, other: unifloat) -> 'cpfloat':
|
def __rpow__(self, other: unifloat) -> 'variable[float]':
|
||||||
...
|
...
|
||||||
|
|
||||||
def __rpow__(self, other: NumLike) -> 'CPNumber':
|
def __rpow__(self, other: NumLike) -> 'CPNumber':
|
||||||
|
|
@ -232,86 +227,57 @@ class CPNumber(Net):
|
||||||
return super().__hash__()
|
return super().__hash__()
|
||||||
|
|
||||||
|
|
||||||
class cpint(CPNumber):
|
class variable(Generic[T], CPNumber):
|
||||||
def __init__(self, source: int | Node):
|
def __init__(self, source: T | Node, dtype: str | None = None):
|
||||||
if isinstance(source, Node):
|
if isinstance(source, Node):
|
||||||
self.source = source
|
self.source = source
|
||||||
|
assert dtype, 'For source type Node a dtype argument is required.'
|
||||||
|
self.dtype = dtype
|
||||||
|
elif isinstance(source, bool):
|
||||||
|
self.source = CPConstant(source)
|
||||||
|
self.dtype = 'bool'
|
||||||
|
elif isinstance(source, int):
|
||||||
|
self.source = CPConstant(source)
|
||||||
|
self.dtype = 'int'
|
||||||
|
elif isinstance(source, float):
|
||||||
|
self.source = CPConstant(source)
|
||||||
|
self.dtype = 'float'
|
||||||
else:
|
else:
|
||||||
self.source = InitVar(int(source))
|
raise ValueError(f'Non supported data type: {type(source).__name__}')
|
||||||
self.dtype = 'int'
|
|
||||||
|
|
||||||
def __lshift__(self, other: uniint) -> 'cpint':
|
# Bitwise and shift operations for cp[int]
|
||||||
ret = _add_op('lshift', [self, other])
|
def __lshift__(self, other: uniint) -> 'variable[int]':
|
||||||
assert isinstance(ret, cpint)
|
return _add_op('lshift', [self, other])
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rlshift__(self, other: uniint) -> 'cpint':
|
def __rlshift__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('lshift', [other, self])
|
return _add_op('lshift', [other, self])
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rshift__(self, other: uniint) -> 'cpint':
|
def __rshift__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('rshift', [self, other])
|
return _add_op('rshift', [self, other])
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rrshift__(self, other: uniint) -> 'cpint':
|
def __rrshift__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('rshift', [other, self])
|
return _add_op('rshift', [other, self])
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __and__(self, other: uniint) -> 'cpint':
|
def __and__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('bwand', [self, other], True)
|
return _add_op('bwand', [self, other], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rand__(self, other: uniint) -> 'cpint':
|
def __rand__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('rwand', [other, self], True)
|
return _add_op('rwand', [other, self], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __or__(self, other: uniint) -> 'cpint':
|
def __or__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('bwor', [self, other], True)
|
return _add_op('bwor', [self, other], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __ror__(self, other: uniint) -> 'cpint':
|
def __ror__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('bwor', [other, self], True)
|
return _add_op('bwor', [other, self], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __xor__(self, other: uniint) -> 'cpint':
|
def __xor__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('bwxor', [self, other], True)
|
return _add_op('bwxor', [self, other], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __rxor__(self, other: uniint) -> 'cpint':
|
def __rxor__(self, other: uniint) -> 'variable[int]':
|
||||||
ret = _add_op('bwxor', [other, self], True)
|
return _add_op('bwxor', [other, self], True)
|
||||||
assert isinstance(ret, cpint)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class cpfloat(CPNumber):
|
class CPConstant(Node):
|
||||||
def __init__(self, source: float | Node | CPNumber):
|
|
||||||
if isinstance(source, Node):
|
|
||||||
self.source = source
|
|
||||||
elif isinstance(source, CPNumber):
|
|
||||||
self.source = _add_op('cast_float', [source]).source
|
|
||||||
else:
|
|
||||||
self.source = InitVar(float(source))
|
|
||||||
self.dtype = 'float'
|
|
||||||
|
|
||||||
|
|
||||||
class cpbool(cpint):
|
|
||||||
def __init__(self, source: bool | Node):
|
|
||||||
if isinstance(source, Node):
|
|
||||||
self.source = source
|
|
||||||
else:
|
|
||||||
self.source = InitVar(bool(source))
|
|
||||||
self.dtype = 'bool'
|
|
||||||
|
|
||||||
|
|
||||||
class InitVar(Node):
|
|
||||||
def __init__(self, value: int | float):
|
def __init__(self, value: int | float):
|
||||||
self.dtype, self.value = _get_data_and_dtype(value)
|
self.dtype, self.value = _get_data_and_dtype(value)
|
||||||
self.name = 'const_' + self.dtype
|
self.name = 'const_' + self.dtype
|
||||||
|
|
@ -323,7 +289,7 @@ class Write(Node):
|
||||||
if isinstance(input, Net):
|
if isinstance(input, Net):
|
||||||
net = input
|
net = input
|
||||||
else:
|
else:
|
||||||
node = InitVar(input)
|
node = CPConstant(input)
|
||||||
net = Net(node.dtype, node)
|
net = Net(node.dtype, node)
|
||||||
|
|
||||||
self.name = 'write_' + transl_type(net.dtype)
|
self.name = 'write_' + transl_type(net.dtype)
|
||||||
|
|
@ -338,22 +304,22 @@ class Op(Node):
|
||||||
|
|
||||||
|
|
||||||
def net_from_value(value: Any) -> Net:
|
def net_from_value(value: Any) -> Net:
|
||||||
vi = InitVar(value)
|
vi = CPConstant(value)
|
||||||
return Net(vi.dtype, vi)
|
return Net(vi.dtype, vi)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def iif(expression: CPNumber, true_result: unibool, false_result: unibool) -> cpbool: # pyright: ignore[reportOverlappingOverload]
|
def iif(expression: CPNumber, true_result: unibool, false_result: unibool) -> variable[bool]: # pyright: ignore[reportOverlappingOverload]
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def iif(expression: CPNumber, true_result: uniint, false_result: uniint) -> cpint:
|
def iif(expression: CPNumber, true_result: uniint, false_result: uniint) -> variable[int]:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def iif(expression: CPNumber, true_result: unifloat, false_result: unifloat) -> cpfloat:
|
def iif(expression: CPNumber, true_result: unifloat, false_result: unifloat) -> variable[float]:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -363,16 +329,15 @@ def iif(expression: NumLike, true_result: T, false_result: T) -> T:
|
||||||
|
|
||||||
|
|
||||||
def iif(expression: Any, true_result: Any, false_result: Any) -> Any:
|
def iif(expression: Any, true_result: Any, false_result: Any) -> Any:
|
||||||
# TODO: check that input types are matching
|
allowed_type = (variable, int, float, bool)
|
||||||
alowed_type = cpint | cpfloat | cpbool | int | float | bool
|
assert isinstance(true_result, allowed_type) and isinstance(false_result, allowed_type), "Result type not supported"
|
||||||
assert isinstance(true_result, alowed_type) and isinstance(false_result, alowed_type), "Result type not supported"
|
|
||||||
if isinstance(expression, CPNumber):
|
if isinstance(expression, CPNumber):
|
||||||
return (expression != 0) * true_result + (expression == 0) * false_result
|
return (expression != 0) * true_result + (expression == 0) * false_result
|
||||||
else:
|
else:
|
||||||
return true_result if expression else false_result
|
return true_result if expression else false_result
|
||||||
|
|
||||||
|
|
||||||
def _add_op(op: str, args: list[CPNumber | int | float], commutative: bool = False) -> CPNumber:
|
def _add_op(op: str, args: list[CPNumber | int | float], commutative: bool = False) -> variable[Any]:
|
||||||
arg_nets = [a if isinstance(a, Net) else net_from_value(a) for a in args]
|
arg_nets = [a if isinstance(a, Net) else net_from_value(a) for a in args]
|
||||||
|
|
||||||
if commutative:
|
if commutative:
|
||||||
|
|
@ -386,35 +351,9 @@ def _add_op(op: str, args: list[CPNumber | int | float], commutative: bool = Fal
|
||||||
result_type = generic_sdb.stencil_definitions[typed_op].split('_')[0]
|
result_type = generic_sdb.stencil_definitions[typed_op].split('_')[0]
|
||||||
|
|
||||||
if result_type == 'int':
|
if result_type == 'int':
|
||||||
return cpint(Op(typed_op, arg_nets))
|
return variable[int](Op(typed_op, arg_nets), result_type)
|
||||||
else:
|
else:
|
||||||
return cpfloat(Op(typed_op, arg_nets))
|
return variable[float](Op(typed_op, arg_nets), result_type)
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def cpvalue(value: bool) -> cpbool: # pyright: ignore[reportOverlappingOverload]
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def cpvalue(value: int) -> cpint:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
@overload
|
|
||||||
def cpvalue(value: float) -> cpfloat:
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
def cpvalue(value: bool | int | float) -> cpbool | cpint | cpfloat:
|
|
||||||
vi = InitVar(value)
|
|
||||||
|
|
||||||
if isinstance(value, bool):
|
|
||||||
return cpbool(vi)
|
|
||||||
elif isinstance(value, float):
|
|
||||||
return cpfloat(vi)
|
|
||||||
else:
|
|
||||||
return cpint(vi)
|
|
||||||
|
|
||||||
|
|
||||||
def _get_data_and_dtype(value: Any) -> tuple[str, float | int]:
|
def _get_data_and_dtype(value: Any) -> tuple[str, float | int]:
|
||||||
|
|
|
||||||
|
|
@ -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, Write, InitVar, 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]:
|
||||||
|
|
@ -76,7 +76,7 @@ def get_const_nets(nodes: list[Node]) -> list[Net]:
|
||||||
List of nets whose source node is a Const
|
List of nets whose source node is a Const
|
||||||
"""
|
"""
|
||||||
net_lookup = {net.source: net for node in nodes for net in node.args}
|
net_lookup = {net.source: net for node in nodes for net in node.args}
|
||||||
return [net_lookup[node] for node in nodes if isinstance(node, InitVar)]
|
return [net_lookup[node] for node in nodes if isinstance(node, CPConstant)]
|
||||||
|
|
||||||
|
|
||||||
def add_read_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]:
|
||||||
|
|
@ -97,7 +97,7 @@ def add_read_ops(node_list: list[Node]) -> Generator[tuple[Net | None, Node], No
|
||||||
net_lookup = {net.source: net for node in node_list for net in node.args}
|
net_lookup = {net.source: net for node in node_list for net in node.args}
|
||||||
|
|
||||||
for node in node_list:
|
for node in node_list:
|
||||||
if not isinstance(node, InitVar):
|
if not isinstance(node, CPConstant):
|
||||||
for i, net in enumerate(node.args):
|
for i, net in enumerate(node.args):
|
||||||
if id(net) != id(registers[i]):
|
if id(net) != id(registers[i]):
|
||||||
#if net in registers:
|
#if net in registers:
|
||||||
|
|
@ -230,7 +230,7 @@ def compile_to_instruction_list(node_list: Iterable[Node], sdb: stencil_database
|
||||||
# Heap variables
|
# Heap variables
|
||||||
for net, out_offs, lengths in variable_mem_layout:
|
for net, out_offs, lengths in variable_mem_layout:
|
||||||
variables[net] = (out_offs, lengths, net.dtype)
|
variables[net] = (out_offs, lengths, net.dtype)
|
||||||
if isinstance(net.source, InitVar):
|
if isinstance(net.source, CPConstant):
|
||||||
dw.write_com(binw.Command.COPY_DATA)
|
dw.write_com(binw.Command.COPY_DATA)
|
||||||
dw.write_int(out_offs)
|
dw.write_int(out_offs)
|
||||||
dw.write_int(lengths)
|
dw.write_int(lengths)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from . import _binwrite as binw
|
||||||
from coparun_module import coparun, read_data_mem
|
from coparun_module import coparun, read_data_mem
|
||||||
import struct
|
import struct
|
||||||
from ._basic_types import stencil_db_from_package
|
from ._basic_types import stencil_db_from_package
|
||||||
from ._basic_types import cpbool, cpint, cpfloat, Net, Node, Write, NumLike
|
from ._basic_types import variable, Net, Node, Write, NumLike
|
||||||
from ._compiler import compile_to_instruction_list
|
from ._compiler import compile_to_instruction_list
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ class Target():
|
||||||
self.sdb = stencil_db_from_package(arch, optimization)
|
self.sdb = stencil_db_from_package(arch, optimization)
|
||||||
self._variables: dict[Net, tuple[int, int, str]] = dict()
|
self._variables: dict[Net, tuple[int, int, str]] = dict()
|
||||||
|
|
||||||
def compile(self, *variables: int | float | cpint | cpfloat | cpbool | Iterable[int | float | cpint | cpfloat | cpbool]) -> None:
|
def compile(self, *variables: int | float | variable[int] | variable[float] | variable[bool] | Iterable[int | float | variable[int] | variable[float] | variable[bool]]) -> None:
|
||||||
nodes: list[Node] = []
|
nodes: list[Node] = []
|
||||||
for s in variables:
|
for s in variables:
|
||||||
if isinstance(s, Iterable):
|
if isinstance(s, Iterable):
|
||||||
|
|
@ -42,15 +42,15 @@ class Target():
|
||||||
assert coparun(dw.get_data()) > 0
|
assert coparun(dw.get_data()) > 0
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def read_value(self, net: cpbool) -> bool:
|
def read_value(self, net: variable[bool]) -> bool:
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def read_value(self, net: cpfloat) -> float:
|
def read_value(self, net: variable[float]) -> float:
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
def read_value(self, net: cpint) -> int:
|
def read_value(self, net: variable[int]) -> int:
|
||||||
...
|
...
|
||||||
|
|
||||||
@overload
|
@overload
|
||||||
|
|
@ -61,6 +61,7 @@ class Target():
|
||||||
assert isinstance(net, Net), "Variable must be a copapy variable object"
|
assert isinstance(net, Net), "Variable must be a copapy variable object"
|
||||||
assert net in self._variables, f"Variable {net} not found"
|
assert net in self._variables, f"Variable {net} not found"
|
||||||
addr, lengths, var_type = self._variables[net]
|
addr, lengths, var_type = self._variables[net]
|
||||||
|
print('...', self._variables[net], net.dtype)
|
||||||
assert lengths > 0
|
assert lengths > 0
|
||||||
data = read_data_mem(addr, lengths)
|
data = read_data_mem(addr, lengths)
|
||||||
assert data is not None and len(data) == lengths, f"Failed to read variable {net}"
|
assert data is not None and len(data) == lengths, f"Failed to read variable {net}"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from ._target import add_read_command
|
from ._target import add_read_command
|
||||||
from ._basic_types import Net, Op, Node, InitVar, Write
|
from ._basic_types import Net, Op, Node, CPConstant, Write
|
||||||
from ._compiler import compile_to_instruction_list, \
|
from ._compiler import compile_to_instruction_list, \
|
||||||
stable_toposort, get_const_nets, get_all_dag_edges, add_read_ops, \
|
stable_toposort, get_const_nets, get_all_dag_edges, add_read_ops, \
|
||||||
add_write_ops
|
add_write_ops
|
||||||
|
|
@ -9,7 +9,7 @@ __all__ = [
|
||||||
"Net",
|
"Net",
|
||||||
"Op",
|
"Op",
|
||||||
"Node",
|
"Node",
|
||||||
"InitVar",
|
"CPConstant",
|
||||||
"Write",
|
"Write",
|
||||||
"compile_to_instruction_list",
|
"compile_to_instruction_list",
|
||||||
"stable_toposort",
|
"stable_toposort",
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ stack_size = 64
|
||||||
|
|
||||||
includes = ['aux_functions.c']
|
includes = ['aux_functions.c']
|
||||||
|
|
||||||
|
|
||||||
def read_files(files: list[str]) -> str:
|
def read_files(files: list[str]) -> str:
|
||||||
ret = ''
|
ret = ''
|
||||||
script_dir = Path(__file__).parent
|
script_dir = Path(__file__).parent
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import cpvalue
|
from copapy import variable
|
||||||
from copapy.backend import Write
|
from copapy.backend import Write
|
||||||
import copapy.backend as cpbe
|
import copapy.backend as cpbe
|
||||||
|
|
||||||
|
|
@ -21,8 +21,8 @@ def test_ast_generation():
|
||||||
#r2 = i1 + 9
|
#r2 = i1 + 9
|
||||||
#out = [Write(r1), Write(r2)]
|
#out = [Write(r1), Write(r2)]
|
||||||
|
|
||||||
c1 = cpvalue(4)
|
c1 = variable(4)
|
||||||
c2 = cpvalue(2)
|
c2 = variable(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
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import cpvalue, NumLike
|
from copapy import variable, NumLike
|
||||||
from copapy.backend import Write, compile_to_instruction_list, add_read_command
|
from copapy.backend import Write, compile_to_instruction_list, add_read_command
|
||||||
import copapy
|
import copapy
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
@ -41,8 +41,8 @@ def function(c1: NumLike, c2: NumLike) -> tuple[NumLike, ...]:
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
|
|
||||||
c1 = cpvalue(4)
|
c1 = variable(4)
|
||||||
c2 = cpvalue(2)
|
c2 = variable(2)
|
||||||
|
|
||||||
ret = function(c1, c2)
|
ret = function(c1, c2)
|
||||||
#ret = [c1 // 3.3 + 5]
|
#ret = [c1 // 3.3 + 5]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import cpvalue, NumLike
|
from copapy import variable, NumLike
|
||||||
from copapy.backend import Write, compile_to_instruction_list
|
from copapy.backend import Write, compile_to_instruction_list
|
||||||
import copapy
|
import copapy
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
@ -20,7 +20,7 @@ def function(c1: NumLike) -> list[NumLike]:
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
|
|
||||||
c1 = cpvalue(16)
|
c1 = variable(16)
|
||||||
|
|
||||||
ret = function(c1)
|
ret = function(c1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import cpvalue, Target, NumLike
|
from copapy import variable, Target, NumLike
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ def function(c1: NumLike) -> list[NumLike]:
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
|
|
||||||
c1 = cpvalue(16)
|
c1 = variable(16)
|
||||||
|
|
||||||
ret = function(c1)
|
ret = function(c1)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from coparun_module import coparun
|
from coparun_module import coparun
|
||||||
from copapy import cpvalue
|
from copapy import variable
|
||||||
from copapy.backend import Write, compile_to_instruction_list, add_read_command
|
from copapy.backend import Write, compile_to_instruction_list, add_read_command
|
||||||
import copapy
|
import copapy
|
||||||
from copapy import _binwrite
|
from copapy import _binwrite
|
||||||
|
|
@ -7,8 +7,8 @@ from copapy import _binwrite
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
|
|
||||||
c1 = cpvalue(4)
|
c1 = variable(4)
|
||||||
c2 = cpvalue(2) * 4
|
c2 = variable(2) * 4
|
||||||
|
|
||||||
i1 = c2 * 2
|
i1 = c2 * 2
|
||||||
r1 = i1 + 7 + (c1 + 7 * 9)
|
r1 = i1 + 7 + (c1 + 7 * 9)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import NumLike, cpvalue
|
from copapy import NumLike, variable
|
||||||
from copapy.backend import Write, Net, compile_to_instruction_list, add_read_command
|
from copapy.backend import Write, Net, compile_to_instruction_list, add_read_command
|
||||||
import copapy
|
import copapy
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
@ -24,8 +24,8 @@ def function(c1: NumLike, c2: NumLike) -> tuple[NumLike, ...]:
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
|
|
||||||
c1 = cpvalue(4)
|
c1 = variable(4)
|
||||||
c2 = cpvalue(2)
|
c2 = variable(2)
|
||||||
|
|
||||||
ret = function(c1, c2)
|
ret = function(c1, c2)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
from copapy import cpvalue, Target
|
from copapy import variable, Target
|
||||||
import pytest
|
import pytest
|
||||||
import copapy
|
import copapy
|
||||||
|
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
c_i = cpvalue(9)
|
c_i = variable(9)
|
||||||
c_f = cpvalue(2.5)
|
c_f = variable(2.5)
|
||||||
# c_b = cpvalue(True)
|
# c_b = variable(True)
|
||||||
|
|
||||||
ret_test = (c_f ** c_f, c_i ** c_i)
|
ret_test = (c_f ** c_f, c_i ** c_i)
|
||||||
ret_ref = (2.5 ** 2.5, 9 ** 9)
|
ret_ref = (2.5 ** 2.5, 9 ** 9)
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from copapy import cpvalue, Target, NumLike, iif, cpint
|
from copapy import variable, Target, NumLike, iif
|
||||||
import pytest
|
import pytest
|
||||||
import copapy
|
import copapy
|
||||||
|
|
||||||
|
|
@ -42,11 +42,11 @@ def iiftests(c1: NumLike) -> list[NumLike]:
|
||||||
|
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
c_i = cpvalue(9)
|
c_i = variable(9)
|
||||||
c_f = cpvalue(1.111)
|
c_f = variable(1.111)
|
||||||
c_b = cpvalue(True)
|
c_b = variable(True)
|
||||||
|
|
||||||
ret_test = function1(c_i) + function1(c_f) + function2(c_i) + function2(c_f) + function3(c_i) + function4(c_i) + function5(c_b) + [cpint(9) % 2] + iiftests(c_i) + iiftests(c_f)
|
ret_test = function1(c_i) + function1(c_f) + function2(c_i) + function2(c_f) + function3(c_i) + function4(c_i) + function5(c_b) + [variable(9) % 2] + iiftests(c_i) + iiftests(c_f)
|
||||||
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)
|
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)
|
||||||
|
|
||||||
tg = Target()
|
tg = Target()
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
from copapy import cpvalue, Target, iif
|
from copapy import variable, Target, iif
|
||||||
import pytest
|
import pytest
|
||||||
import copapy
|
import copapy
|
||||||
|
|
||||||
|
|
||||||
def test_compile():
|
def test_compile():
|
||||||
c_i = cpvalue(9)
|
c_i = variable(9)
|
||||||
c_f = cpvalue(2.5)
|
c_f = variable(2.5)
|
||||||
# c_b = cpvalue(True)
|
# c_b = variable(True)
|
||||||
|
|
||||||
ret_test = (iif(c_f > 5, c_f, -1), iif(c_i > 5, c_f, 8.8), iif(c_i > 2, c_i, 1))
|
ret_test = (iif(c_f > 5, c_f, -1), iif(c_i > 5, c_f, 8.8), iif(c_i > 2, c_i, 1))
|
||||||
ret_ref = (iif(2.5 > 5, 2.5, -1), iif(9 > 5, 2.5, 8.8), iif(9 > 2, 9, 1))
|
ret_ref = (iif(2.5 > 5, 2.5, -1), iif(9 > 5, 2.5, 8.8), iif(9 > 2, 9, 1))
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
from copapy import _binwrite, cpvalue
|
from copapy import _binwrite, variable
|
||||||
from copapy.backend import Write, compile_to_instruction_list
|
from copapy.backend import Write, compile_to_instruction_list
|
||||||
import copapy
|
import copapy
|
||||||
|
|
||||||
|
|
||||||
def test_compile() -> None:
|
def test_compile() -> None:
|
||||||
|
|
||||||
c1 = cpvalue(9)
|
c1 = variable(9)
|
||||||
|
|
||||||
#ret = [c1 / 4, c1 / -4, c1 // 4, c1 // -4, (c1 * -1) // 4]
|
#ret = [c1 / 4, c1 / -4, c1 // 4, c1 // -4, (c1 * -1) // 4]
|
||||||
ret = [c1 // 3.3 + 5]
|
ret = [c1 // 3.3 + 5]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue