From fbc73db5fce6c60050d3a2720115f3700372a22a Mon Sep 17 00:00:00 2001 From: Egor Orachev Date: Thu, 31 Aug 2023 12:10:50 +0300 Subject: [PATCH] gh-218: add unary ops & vec map to package --- include/spla.h | 50 ++++++++++++++- include/spla/op.hpp | 55 ++++++++++++++++- python/example.py | 3 + python/pyspla/__init__.py | 51 +-------------- python/pyspla/bridge.py | 92 ++++++++++++++++++++++++++-- python/pyspla/type.py | 126 ++++++++++++++++++++++++++++++++++++-- python/pyspla/vector.py | 38 ++++++++++++ registry.py | 104 ------------------------------- src/binding/c_op.cpp | 46 +++++++++++++- src/core/top.hpp | 26 ++++++++ src/op.cpp | 102 ++++++++++++++++++++++++++++-- 11 files changed, 514 insertions(+), 179 deletions(-) delete mode 100644 registry.py diff --git a/include/spla.h b/include/spla.h index f8219bd59..4a54229bf 100644 --- a/include/spla.h +++ b/include/spla.h @@ -154,6 +154,44 @@ SPLA_API spla_Type spla_Type_FLOAT(); ////////////////////////////////////////////////////////////////////////////////////// +/* Built-in unary element-wise operations */ + +SPLA_API spla_OpUnary spla_OpUnary_IDENTITY_INT(); +SPLA_API spla_OpUnary spla_OpUnary_IDENTITY_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_IDENTITY_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_AINV_INT(); +SPLA_API spla_OpUnary spla_OpUnary_AINV_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_AINV_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_MINV_INT(); +SPLA_API spla_OpUnary spla_OpUnary_MINV_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_MINV_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_LNOT_INT(); +SPLA_API spla_OpUnary spla_OpUnary_LNOT_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_LNOT_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_UONE_INT(); +SPLA_API spla_OpUnary spla_OpUnary_UONE_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_UONE_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_ABS_INT(); +SPLA_API spla_OpUnary spla_OpUnary_ABS_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_ABS_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_BNOT_INT(); +SPLA_API spla_OpUnary spla_OpUnary_BNOT_UINT(); +SPLA_API spla_OpUnary spla_OpUnary_SQRT_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_LOG_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_EXP_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_SIN_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_COS_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_TAN_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_ASIN_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_ACOS_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_ATAN_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_CEIL_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_FLOOR_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_ROUND_FLOAT(); +SPLA_API spla_OpUnary spla_OpUnary_TRUNC_FLOAT(); + +////////////////////////////////////////////////////////////////////////////////////// + /* Built-in binary element-wise operations */ SPLA_API spla_OpBinary spla_OpBinary_PLUS_INT(); @@ -177,15 +215,21 @@ SPLA_API spla_OpBinary spla_OpBinary_FIRST_FLOAT(); SPLA_API spla_OpBinary spla_OpBinary_SECOND_INT(); SPLA_API spla_OpBinary spla_OpBinary_SECOND_UINT(); SPLA_API spla_OpBinary spla_OpBinary_SECOND_FLOAT(); -SPLA_API spla_OpBinary spla_OpBinary_ONE_INT(); -SPLA_API spla_OpBinary spla_OpBinary_ONE_UINT(); -SPLA_API spla_OpBinary spla_OpBinary_ONE_FLOAT(); +SPLA_API spla_OpBinary spla_OpBinary_BONE_INT(); +SPLA_API spla_OpBinary spla_OpBinary_BONE_UINT(); +SPLA_API spla_OpBinary spla_OpBinary_BONE_FLOAT(); SPLA_API spla_OpBinary spla_OpBinary_MIN_INT(); SPLA_API spla_OpBinary spla_OpBinary_MIN_UINT(); SPLA_API spla_OpBinary spla_OpBinary_MIN_FLOAT(); SPLA_API spla_OpBinary spla_OpBinary_MAX_INT(); SPLA_API spla_OpBinary spla_OpBinary_MAX_UINT(); SPLA_API spla_OpBinary spla_OpBinary_MAX_FLOAT(); +SPLA_API spla_OpBinary spla_OpBinary_LOR_INT(); +SPLA_API spla_OpBinary spla_OpBinary_LOR_UINT(); +SPLA_API spla_OpBinary spla_OpBinary_LOR_FLOAT(); +SPLA_API spla_OpBinary spla_OpBinary_LAND_INT(); +SPLA_API spla_OpBinary spla_OpBinary_LAND_UINT(); +SPLA_API spla_OpBinary spla_OpBinary_LAND_FLOAT(); SPLA_API spla_OpBinary spla_OpBinary_BOR_INT(); SPLA_API spla_OpBinary spla_OpBinary_BOR_UINT(); SPLA_API spla_OpBinary spla_OpBinary_BAND_INT(); diff --git a/include/spla/op.hpp b/include/spla/op.hpp index de06adfdc..96dd16848 100644 --- a/include/spla/op.hpp +++ b/include/spla/op.hpp @@ -93,6 +93,46 @@ namespace spla { SPLA_API static ref_ptr make_float(std::string name, std::string code, std::function function); }; + //////////////////////////////// Unary //////////////////////////////// + + SPLA_API extern ref_ptr IDENTITY_INT; + SPLA_API extern ref_ptr IDENTITY_UINT; + SPLA_API extern ref_ptr IDENTITY_FLOAT; + SPLA_API extern ref_ptr AINV_INT; + SPLA_API extern ref_ptr AINV_UINT; + SPLA_API extern ref_ptr AINV_FLOAT; + SPLA_API extern ref_ptr MINV_INT; + SPLA_API extern ref_ptr MINV_UINT; + SPLA_API extern ref_ptr MINV_FLOAT; + SPLA_API extern ref_ptr LNOT_INT; + SPLA_API extern ref_ptr LNOT_UINT; + SPLA_API extern ref_ptr LNOT_FLOAT; + SPLA_API extern ref_ptr UONE_INT; + SPLA_API extern ref_ptr UONE_UINT; + SPLA_API extern ref_ptr UONE_FLOAT; + SPLA_API extern ref_ptr ABS_INT; + SPLA_API extern ref_ptr ABS_UINT; + SPLA_API extern ref_ptr ABS_FLOAT; + + SPLA_API extern ref_ptr BNOT_INT; + SPLA_API extern ref_ptr BNOT_UINT; + + SPLA_API extern ref_ptr SQRT_FLOAT; + SPLA_API extern ref_ptr LOG_FLOAT; + SPLA_API extern ref_ptr EXP_FLOAT; + SPLA_API extern ref_ptr SIN_FLOAT; + SPLA_API extern ref_ptr COS_FLOAT; + SPLA_API extern ref_ptr TAN_FLOAT; + SPLA_API extern ref_ptr ASIN_FLOAT; + SPLA_API extern ref_ptr ACOS_FLOAT; + SPLA_API extern ref_ptr ATAN_FLOAT; + SPLA_API extern ref_ptr CEIL_FLOAT; + SPLA_API extern ref_ptr FLOOR_FLOAT; + SPLA_API extern ref_ptr ROUND_FLOAT; + SPLA_API extern ref_ptr TRUNC_FLOAT; + + //////////////////////////////// Binary //////////////////////////////// + SPLA_API extern ref_ptr PLUS_INT; SPLA_API extern ref_ptr PLUS_UINT; SPLA_API extern ref_ptr PLUS_FLOAT; @@ -117,9 +157,9 @@ namespace spla { SPLA_API extern ref_ptr SECOND_UINT; SPLA_API extern ref_ptr SECOND_FLOAT; - SPLA_API extern ref_ptr ONE_INT; - SPLA_API extern ref_ptr ONE_UINT; - SPLA_API extern ref_ptr ONE_FLOAT; + SPLA_API extern ref_ptr BONE_INT; + SPLA_API extern ref_ptr BONE_UINT; + SPLA_API extern ref_ptr BONE_FLOAT; SPLA_API extern ref_ptr MIN_INT; SPLA_API extern ref_ptr MIN_UINT; @@ -128,6 +168,13 @@ namespace spla { SPLA_API extern ref_ptr MAX_UINT; SPLA_API extern ref_ptr MAX_FLOAT; + SPLA_API extern ref_ptr LOR_INT; + SPLA_API extern ref_ptr LOR_UINT; + SPLA_API extern ref_ptr LOR_FLOAT; + SPLA_API extern ref_ptr LAND_INT; + SPLA_API extern ref_ptr LAND_UINT; + SPLA_API extern ref_ptr LAND_FLOAT; + SPLA_API extern ref_ptr BOR_INT; SPLA_API extern ref_ptr BOR_UINT; SPLA_API extern ref_ptr BAND_INT; @@ -135,6 +182,8 @@ namespace spla { SPLA_API extern ref_ptr BXOR_INT; SPLA_API extern ref_ptr BXOR_UINT; + //////////////////////////////// Select //////////////////////////////// + SPLA_API extern ref_ptr EQZERO_INT; SPLA_API extern ref_ptr EQZERO_UINT; SPLA_API extern ref_ptr EQZERO_FLOAT; diff --git a/python/example.py b/python/example.py index 3968ca1bc..0ba5fef0d 100644 --- a/python/example.py +++ b/python/example.py @@ -1 +1,4 @@ from pyspla import * + +v = Vector.from_lists([0, 1, 3], [5, -1, 3], 4, INT) +print(v.map(INT.AINV)) diff --git a/python/pyspla/__init__.py b/python/pyspla/__init__.py index 4cc307033..c4e700341 100644 --- a/python/pyspla/__init__.py +++ b/python/pyspla/__init__.py @@ -102,7 +102,6 @@ | rgg_n_2_23_s0 | 8.4M | 127.0M | 15.1 | 3.9 | 40.0 | [link](https://suitesparse-collection-website.herokuapp.com/MM/DIMACS10/rgg_n_2_23_s0.tar.gz) | | road_central | 14.1M | 33.9M | 2.4 | 0.9 | 8.0 | [link](http://sparse.tamu.edu/DIMACS10/road_central) | - Containers ---------- @@ -115,20 +114,6 @@ managed by container internally. All required format conversion done in the context of particular primitive usage. -- `Matrix`. Generalized statically-typed sparse storage-invariant matrix primitive. -- `Vector`. Generalized statically-typed sparse storage-invariant vector primitive. -- `Scalar`. Generalized statically-typed scalar primitive. - -Schedule --------- - -Schedule allows to build sequence of tasks to be executed. It allows user -control the order of the tasks' execution, parallel execution of tasks -on some level, notification on some steps completion and etc. - -- `Schedule`. Schedule object which may be executed by library. -- `Task`. A particular wort to be done inside a step of schedule. - Types ----- @@ -138,11 +123,6 @@ can interpret stored data as her/she wants. Spla types set is limited due to the nature of GPUs accelerations, where arbitrary layout of data causes significant performance penalties. -- `BOOL`. 4-byte-sized signed logical value (auxiliary type). -- `INT`. 4-byte-sized signed integral value. -- `UINT`. 4-byte-sized unsigned integral value. -- `FLOAT`. 4-byte-sized single-precision floating point value. - Ops --- @@ -151,42 +131,13 @@ operations, binary operations used for reductions and products, select operations used for filtration and mask application. -List of built-in binary operations: - -| Name | Type | Meaning | -|:--------|:------------|:---------------| -|`PLUS` | binary(x,y) | r = x + y | -|`MINUS` | binary(x,y) | r = x - y | -|`MULT` | binary(x,y) | r = x * y | -|`DIV` | binary(x,y) | r = x / y | -|`FIRST` | binary(x,y) | r = x | -|`SECOND` | binary(x,y) | r = y | -|`ONE` | binary(x,y) | r = 1 | -|`MIN` | binary(x,y) | r = min(x, y) | -|`MAX` | binary(x,y) | r = max(x, y) | -|`BOR` | binary(x,y) | r = x or y | -|`BAND` | binary(x,y) | r = x & y | -|`BXOR` | binary(x,y) | r = x ^ y | - -List of built-in select operations: - -| Name | Type | Meaning | -|:--------|:------------|:---------------| -|`EQZERO` | select(x) | x == 0 | -|`NQZERO` | select(x) | x != 0 | -|`GTZERO` | select(x) | x > 0 | -|`GEZERO` | select(x) | x >= 0 | -|`LTZERO` | select(x) | x < 0 | -|`LEZERO` | select(x) | x <= 0 | -|`ALWAYS` | select(x) | true | -|`NEVER` | select(x) | false | - Details ------- Spla C/C++ backend compiled library is automatically loaded and initialized on package import. State of the library managed by internal `bridge` module. All resources are unloaded automatically on package exit. Library state finalized automatically. + """ __copyright__ = "Copyright (c) 2021-2023 SparseLinearAlgebra" diff --git a/python/pyspla/bridge.py b/python/pyspla/bridge.py index 5580a0cc1..9b12d9084 100644 --- a/python/pyspla/bridge.py +++ b/python/pyspla/bridge.py @@ -195,6 +195,74 @@ def load_library(lib_path): _spla.spla_Type_FLOAT.restype = _object_t _spla.spla_Type_FLOAT.argtypes = [] + _spla.spla_OpUnary_IDENTITY_INT.restype = _object_t + _spla.spla_OpUnary_IDENTITY_UINT.restype = _object_t + _spla.spla_OpUnary_IDENTITY_FLOAT.restype = _object_t + _spla.spla_OpUnary_AINV_INT.restype = _object_t + _spla.spla_OpUnary_AINV_UINT.restype = _object_t + _spla.spla_OpUnary_AINV_FLOAT.restype = _object_t + _spla.spla_OpUnary_MINV_INT.restype = _object_t + _spla.spla_OpUnary_MINV_UINT.restype = _object_t + _spla.spla_OpUnary_MINV_FLOAT.restype = _object_t + _spla.spla_OpUnary_LNOT_INT.restype = _object_t + _spla.spla_OpUnary_LNOT_UINT.restype = _object_t + _spla.spla_OpUnary_LNOT_FLOAT.restype = _object_t + _spla.spla_OpUnary_UONE_INT.restype = _object_t + _spla.spla_OpUnary_UONE_UINT.restype = _object_t + _spla.spla_OpUnary_UONE_FLOAT.restype = _object_t + _spla.spla_OpUnary_ABS_INT.restype = _object_t + _spla.spla_OpUnary_ABS_UINT.restype = _object_t + _spla.spla_OpUnary_ABS_FLOAT.restype = _object_t + _spla.spla_OpUnary_BNOT_INT.restype = _object_t + _spla.spla_OpUnary_BNOT_UINT.restype = _object_t + _spla.spla_OpUnary_SQRT_FLOAT.restype = _object_t + _spla.spla_OpUnary_LOG_FLOAT.restype = _object_t + _spla.spla_OpUnary_EXP_FLOAT.restype = _object_t + _spla.spla_OpUnary_SIN_FLOAT.restype = _object_t + _spla.spla_OpUnary_COS_FLOAT.restype = _object_t + _spla.spla_OpUnary_TAN_FLOAT.restype = _object_t + _spla.spla_OpUnary_ASIN_FLOAT.restype = _object_t + _spla.spla_OpUnary_ACOS_FLOAT.restype = _object_t + _spla.spla_OpUnary_ATAN_FLOAT.restype = _object_t + _spla.spla_OpUnary_CEIL_FLOAT.restype = _object_t + _spla.spla_OpUnary_FLOOR_FLOAT.restype = _object_t + _spla.spla_OpUnary_ROUND_FLOAT.restype = _object_t + _spla.spla_OpUnary_TRUNC_FLOAT.restype = _object_t + + _spla.spla_OpUnary_IDENTITY_INT.argtypes = [] + _spla.spla_OpUnary_IDENTITY_UINT.argtypes = [] + _spla.spla_OpUnary_IDENTITY_FLOAT.argtypes = [] + _spla.spla_OpUnary_AINV_INT.argtypes = [] + _spla.spla_OpUnary_AINV_UINT.argtypes = [] + _spla.spla_OpUnary_AINV_FLOAT.argtypes = [] + _spla.spla_OpUnary_MINV_INT.argtypes = [] + _spla.spla_OpUnary_MINV_UINT.argtypes = [] + _spla.spla_OpUnary_MINV_FLOAT.argtypes = [] + _spla.spla_OpUnary_LNOT_INT.argtypes = [] + _spla.spla_OpUnary_LNOT_UINT.argtypes = [] + _spla.spla_OpUnary_LNOT_FLOAT.argtypes = [] + _spla.spla_OpUnary_UONE_INT.argtypes = [] + _spla.spla_OpUnary_UONE_UINT.argtypes = [] + _spla.spla_OpUnary_UONE_FLOAT.argtypes = [] + _spla.spla_OpUnary_ABS_INT.argtypes = [] + _spla.spla_OpUnary_ABS_UINT.argtypes = [] + _spla.spla_OpUnary_ABS_FLOAT.argtypes = [] + _spla.spla_OpUnary_BNOT_INT.argtypes = [] + _spla.spla_OpUnary_BNOT_UINT.argtypes = [] + _spla.spla_OpUnary_SQRT_FLOAT.argtypes = [] + _spla.spla_OpUnary_LOG_FLOAT.argtypes = [] + _spla.spla_OpUnary_EXP_FLOAT.argtypes = [] + _spla.spla_OpUnary_SIN_FLOAT.argtypes = [] + _spla.spla_OpUnary_COS_FLOAT.argtypes = [] + _spla.spla_OpUnary_TAN_FLOAT.argtypes = [] + _spla.spla_OpUnary_ASIN_FLOAT.argtypes = [] + _spla.spla_OpUnary_ACOS_FLOAT.argtypes = [] + _spla.spla_OpUnary_ATAN_FLOAT.argtypes = [] + _spla.spla_OpUnary_CEIL_FLOAT.argtypes = [] + _spla.spla_OpUnary_FLOOR_FLOAT.argtypes = [] + _spla.spla_OpUnary_ROUND_FLOAT.argtypes = [] + _spla.spla_OpUnary_TRUNC_FLOAT.argtypes = [] + _spla.spla_OpBinary_PLUS_INT.restype = _object_t _spla.spla_OpBinary_PLUS_UINT.restype = _object_t _spla.spla_OpBinary_PLUS_FLOAT.restype = _object_t @@ -216,15 +284,21 @@ def load_library(lib_path): _spla.spla_OpBinary_SECOND_INT.restype = _object_t _spla.spla_OpBinary_SECOND_UINT.restype = _object_t _spla.spla_OpBinary_SECOND_FLOAT.restype = _object_t - _spla.spla_OpBinary_ONE_INT.restype = _object_t - _spla.spla_OpBinary_ONE_UINT.restype = _object_t - _spla.spla_OpBinary_ONE_FLOAT.restype = _object_t + _spla.spla_OpBinary_BONE_INT.restype = _object_t + _spla.spla_OpBinary_BONE_UINT.restype = _object_t + _spla.spla_OpBinary_BONE_FLOAT.restype = _object_t _spla.spla_OpBinary_MIN_INT.restype = _object_t _spla.spla_OpBinary_MIN_UINT.restype = _object_t _spla.spla_OpBinary_MIN_FLOAT.restype = _object_t _spla.spla_OpBinary_MAX_INT.restype = _object_t _spla.spla_OpBinary_MAX_UINT.restype = _object_t _spla.spla_OpBinary_MAX_FLOAT.restype = _object_t + _spla.spla_OpBinary_LOR_INT.restype = _object_t + _spla.spla_OpBinary_LOR_UINT.restype = _object_t + _spla.spla_OpBinary_LOR_FLOAT.restype = _object_t + _spla.spla_OpBinary_LAND_INT.restype = _object_t + _spla.spla_OpBinary_LAND_UINT.restype = _object_t + _spla.spla_OpBinary_LAND_FLOAT.restype = _object_t _spla.spla_OpBinary_BOR_INT.restype = _object_t _spla.spla_OpBinary_BOR_UINT.restype = _object_t _spla.spla_OpBinary_BAND_INT.restype = _object_t @@ -253,15 +327,21 @@ def load_library(lib_path): _spla.spla_OpBinary_SECOND_INT.argtypes = [] _spla.spla_OpBinary_SECOND_UINT.argtypes = [] _spla.spla_OpBinary_SECOND_FLOAT.argtypes = [] - _spla.spla_OpBinary_ONE_INT.argtypes = [] - _spla.spla_OpBinary_ONE_UINT.argtypes = [] - _spla.spla_OpBinary_ONE_FLOAT.argtypes = [] + _spla.spla_OpBinary_BONE_INT.argtypes = [] + _spla.spla_OpBinary_BONE_UINT.argtypes = [] + _spla.spla_OpBinary_BONE_FLOAT.argtypes = [] _spla.spla_OpBinary_MIN_INT.argtypes = [] _spla.spla_OpBinary_MIN_UINT.argtypes = [] _spla.spla_OpBinary_MIN_FLOAT.argtypes = [] _spla.spla_OpBinary_MAX_INT.argtypes = [] _spla.spla_OpBinary_MAX_UINT.argtypes = [] _spla.spla_OpBinary_MAX_FLOAT.argtypes = [] + _spla.spla_OpBinary_LOR_INT.argtypes = [] + _spla.spla_OpBinary_LOR_UINT.argtypes = [] + _spla.spla_OpBinary_LOR_FLOAT.argtypes = [] + _spla.spla_OpBinary_LAND_INT.argtypes = [] + _spla.spla_OpBinary_LAND_UINT.argtypes = [] + _spla.spla_OpBinary_LAND_FLOAT.argtypes = [] _spla.spla_OpBinary_BOR_INT.argtypes = [] _spla.spla_OpBinary_BOR_UINT.argtypes = [] _spla.spla_OpBinary_BAND_INT.argtypes = [] diff --git a/python/pyspla/type.py b/python/pyspla/type.py index cdc62d9be..51410b83c 100644 --- a/python/pyspla/type.py +++ b/python/pyspla/type.py @@ -28,8 +28,8 @@ import ctypes -from .bridge import backend, check -from .op import OpBinary, OpSelect +from .bridge import backend +from .op import OpUnary, OpBinary, OpSelect __all__ = [ "Type", @@ -44,6 +44,67 @@ class Type: """ Spla base Type for storage parametrization. + + List of built-in Unary operations + --------------------------------- + + | Name | Type | Meaning | + |:----------|:---------|:---------------| + |`IDENTITY` | unary(x) | r = x | + |`AINV` | unary(x) | r = -x | + |`MINV` | unary(x) | r = 1/x | + |`LNOT` | unary(x) | r = !(x!=0) | + |`UONE` | unary(x) | r = 1 | + |`ABS` | unary(x) | r = abs(x) | + |`BNOT` | unary(x) | r = ~x | + |`SQRT` | unary(x) | r = sqrt(x) | + |`LOG` | unary(x) | r = log(x) | + |`EXP` | unary(x) | r = exp(x) | + |`SIN` | unary(x) | r = sin(x) | + |`COS` | unary(x) | r = cos(x) | + |`TAN` | unary(x) | r = tan(x) | + |`ASIN` | unary(x) | r = asin(x) | + |`ACOS` | unary(x) | r = acos(x) | + |`ATAN` | unary(x) | r = atan(x) | + |`CEIL` | unary(x) | r = ceil(x) | + |`FLOOR` | unary(x) | r = floor(x) | + |`ROUND` | unary(x) | r = round(x) | + |`TRUNC` | unary(x) | r = trunc(x) | + + List of built-in Binary operations + ---------------------------------- + + | Name | Type | Meaning | + |:--------|:------------|:---------------| + |`PLUS` | binary(x,y) | r = x + y | + |`MINUS` | binary(x,y) | r = x - y | + |`MULT` | binary(x,y) | r = x * y | + |`DIV` | binary(x,y) | r = x / y | + |`FIRST` | binary(x,y) | r = x | + |`SECOND` | binary(x,y) | r = y | + |`BONE` | binary(x,y) | r = 1 | + |`MIN` | binary(x,y) | r = min(x, y) | + |`MAX` | binary(x,y) | r = max(x, y) | + |`LOR` | binary(x,y) | r = x lor y | + |`LAND` | binary(x,y) | r = x && y | + |`BOR` | binary(x,y) | r = x bor y | + |`BAND` | binary(x,y) | r = x & y | + |`BXOR` | binary(x,y) | r = x ^ y | + + List of built-in Select operations + ---------------------------------- + + | Name | Type | Meaning | + |:--------|:------------|:---------------| + |`EQZERO` | select(x) | x == 0 | + |`NQZERO` | select(x) | x != 0 | + |`GTZERO` | select(x) | x > 0 | + |`GEZERO` | select(x) | x >= 0 | + |`LTZERO` | select(x) | x < 0 | + |`LEZERO` | select(x) | x <= 0 | + |`ALWAYS` | select(x) | true | + |`NEVER` | select(x) | false | + """ _c_type = None @@ -59,6 +120,27 @@ class Type: _matrix_set = None _hnd = None + IDENTITY: OpUnary + AINV: OpUnary + MINV: OpUnary + LNOT: OpUnary + UONE: OpUnary + ABS: OpUnary + BNOT: OpUnary + SQRT: OpUnary + LOG: OpUnary + EXP: OpUnary + SIN: OpUnary + COS: OpUnary + TAN: OpUnary + ASIN: OpUnary + ACOS: OpUnary + ATAN: OpUnary + CEIL: OpUnary + FLOOR: OpUnary + ROUND: OpUnary + TRUNC: OpUnary + PLUS: OpBinary MINUS: OpBinary MULT: OpBinary @@ -66,9 +148,11 @@ class Type: MINUS_POW2: OpBinary FIRST: OpBinary SECOND: OpBinary - ONE: OpBinary + BONE: OpBinary MIN: OpBinary MAX: OpBinary + LOR: OpBinary + LAND: OpBinary BOR: OpBinary BAND: OpBinary BXOR: OpBinary @@ -122,6 +206,37 @@ def format_value(cls, value, width=2, precision=2): return f.format(value) return f.format("t") if value is True else f.format("f") + @classmethod + def _setup_op_unary(cls): + b = backend() + type_name = cls.__name__ + + def load_op(name): + f = f"spla_OpUnary_{name}_{type_name}" + func = getattr(b, f) if hasattr(b, f) else None + return OpUnary(hnd=func(), name=name, dtype_res=cls, dtype_arg0=cls) if func else None + + cls.IDENTITY = load_op('IDENTITY') + cls.AINV = load_op('AINV') + cls.MINV = load_op('MINV') + cls.LNOT = load_op('LNOT') + cls.UONE = load_op('UONE') + cls.ABS = load_op('ABS') + cls.BNOT = load_op('BNOT') + cls.SQRT = load_op('SQRT') + cls.LOG = load_op('LOG') + cls.EXP = load_op('EXP') + cls.SIN = load_op('SIN') + cls.COS = load_op('COS') + cls.TAN = load_op('TAN') + cls.ASIN = load_op('ASIN') + cls.ACOS = load_op('ACOS') + cls.ATAN = load_op('ATAN') + cls.CEIL = load_op('CEIL') + cls.FLOOR = load_op('FLOOR') + cls.ROUND = load_op('ROUND') + cls.TRUNC = load_op('TRUNC') + @classmethod def _setup_op_binary(cls): b = backend() @@ -139,9 +254,11 @@ def load_op(name): cls.MINUS_POW2 = load_op('MINUS_POW2') cls.FIRST = load_op('FIRST') cls.SECOND = load_op('SECOND') - cls.ONE = load_op('ONE') + cls.BONE = load_op('BONE') cls.MIN = load_op('MIN') cls.MAX = load_op('MAX') + cls.LOR = load_op('LOR') + cls.LAND = load_op('LAND') cls.BOR = load_op('BOR') cls.BAND = load_op('BAND') cls.BXOR = load_op('BXOR') @@ -184,6 +301,7 @@ def _setup(cls): cls._matrix_set = getattr(b, f"spla_Matrix_set_{type_name_lower}") cls._hnd = getattr(b, f"spla_Type_{type_name}")() + cls._setup_op_unary() cls._setup_op_binary() cls._setup_op_select() diff --git a/python/pyspla/vector.py b/python/pyspla/vector.py index 88e0dfdd0..7c0b77910 100644 --- a/python/pyspla/vector.py +++ b/python/pyspla/vector.py @@ -525,6 +525,44 @@ def assign(self, mask, value, op_assign, op_select, desc=None): return self + def map(self, op_map, out=None, desc=None): + """ + Map this vector by applying element-wise unary function to each element. + + >>> v = Vector.from_lists([0, 1, 3], [5, -1, 3], 4, INT) + >>> print(v.map(INT.AINV)) + ' + 0|-5 + 1| 1 + 2| . + 3|-3 + ' + + :param op_map: OpUnary. + Unary operation to apply to transform values. + + :param out: optional: Vector. default: None. + Optional vector where to store result. + + :param desc: optional: Descriptor. default: None. + Optional descriptor object to configure the execution. + + :return: Result of a map as vector. + """ + + if out is None: + out = Vector(self.n_rows, self.dtype) + + assert out + assert op_map + assert out.n_rows == self.n_rows + assert out.dtype == self.dtype + + check(backend().spla_Exec_v_map(out.hnd, self.hnd, op_map.hnd, + self._get_desc(desc), self._get_task(None))) + + return out + def reduce(self, op_reduce, out=None, init=None, desc=None): """ Reduce vector elements. diff --git a/registry.py b/registry.py deleted file mode 100644 index c0016037d..000000000 --- a/registry.py +++ /dev/null @@ -1,104 +0,0 @@ -################################################################################## -# This file is part of spla project # -# https://github.com/SparseLinearAlgebra/spla # -################################################################################## -# MIT License # -# # -# Copyright (c) 2023 SparseLinearAlgebra # -# # -# Permission is hereby granted, free of charge, to any person obtaining a copy # -# of this software and associated documentation files (the "Software"), to deal # -# in the Software without restriction, including without limitation the rights # -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # -# copies of the Software, and to permit persons to whom the Software is # -# furnished to do so, subject to the following conditions: # -# # -# The above copyright notice and this permission notice shall be included in all # -# copies or substantial portions of the Software. # -# # -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # -# SOFTWARE. # -################################################################################## - -import argparse - - -def make_signature(ops, platform, arity, algo, t): - return f"g_registry->add(MAKE_KEY_{platform.upper()}_{arity}(\"{algo}\"{ops}), " \ - f"std::make_shared>());\n" - - -def make_ops_list(ops, t): - return "{" + ",".join([f"{op}_{t}" for op in ops]) + "}" - - -def generate(file, algo, platform, ts, ops): - arity = len(ops) - - for t in ts: - for i, op in enumerate(ops): - file.write(f"for (const auto& op{i}:" + make_ops_list(op, t) + ") {") - - key = f",{t}" if arity == 0 else "".join([f",op{i}" for i in range(arity)]) - file.write(make_signature(key, platform, arity, algo, t)) - - for i in range(arity): - file.write("}") - - -def main(): - parser = argparse.ArgumentParser("generate all possible algorithm variation") - parser.add_argument("--out", help="file to save generated code", default="registry.txt") - parser.add_argument("--full", help="gen full signature or short", default=False) - parser.add_argument("--platform", help="target backend platform to generate", default="cpu") - args = parser.parse_args() - - ts = ["INT", "UINT", "FLOAT"] - ts_integral = ["INT", "UINT"] - ops_bin = ["PLUS", "MINUS", "MULT", "DIV", "FIRST", "SECOND", "ONE", "MIN", "MAX"] - ops_bin_x = ["BOR", "BAND", "BXOR"] - ops_select = ["EQZERO", "NQZERO", "GTZERO", "GEZERO", "LTZERO", "LEZERO", "ALWAYS", "NEVER"] - algos_0 = ["v_count_mf"] - algos_1 = ["v_map", "v_reduce", "v_eadd_fdb"] - algos_2 = ["v_assign_masked"] - algos_3 = ["mxv_masked", "vxm_masked"] - algos_all = algos_0 + algos_1 + algos_2 + algos_3 - - p = args.platform - - if not args.full: - with open(args.out, "w") as file: - for algo in algos_all: - file.write(f"// algorthm {algo}\n") - generate(file, algo, p, ts, []) - file.write("\n") - else: - with open(args.out, "w") as file: - for algo in algos_0: - file.write(f"// algorthm {algo}\n") - generate(file, algo, p, ts, []) - file.write("\n\n") - for algo in algos_1: - file.write(f"// algorthm {algo}\n") - generate(file, algo, p, ts, [ops_bin]) - generate(file, algo, p, ts_integral, [ops_bin_x]) - file.write("\n\n") - for algo in algos_2: - file.write(f"// algorthm {algo}\n") - generate(file, algo, p, ts, [ops_bin, ops_select]) - generate(file, algo, p, ts_integral, [ops_bin_x, ops_select]) - file.write("\n\n") - for algo in algos_3: - file.write(f"// algorthm {algo}\n") - generate(file, algo, p, ts, [ops_bin, ops_bin, ops_select]) - generate(file, algo, p, ts_integral, [ops_bin_x, ops_bin_x, ops_select]) - file.write("\n\n") - - -if __name__ == '__main__': - main() diff --git a/src/binding/c_op.cpp b/src/binding/c_op.cpp index fdf6d40ef..e3202e4f0 100644 --- a/src/binding/c_op.cpp +++ b/src/binding/c_op.cpp @@ -27,6 +27,40 @@ #include "c_config.hpp" +spla_OpUnary spla_OpUnary_IDENTITY_INT() { return as_ptr(spla::IDENTITY_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_IDENTITY_UINT() { return as_ptr(spla::IDENTITY_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_IDENTITY_FLOAT() { return as_ptr(spla::IDENTITY_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_AINV_INT() { return as_ptr(spla::AINV_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_AINV_UINT() { return as_ptr(spla::AINV_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_AINV_FLOAT() { return as_ptr(spla::AINV_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_MINV_INT() { return as_ptr(spla::MINV_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_MINV_UINT() { return as_ptr(spla::MINV_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_MINV_FLOAT() { return as_ptr(spla::MINV_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_LNOT_INT() { return as_ptr(spla::LNOT_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_LNOT_UINT() { return as_ptr(spla::LNOT_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_LNOT_FLOAT() { return as_ptr(spla::LNOT_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_UONE_INT() { return as_ptr(spla::UONE_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_UONE_UINT() { return as_ptr(spla::UONE_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_UONE_FLOAT() { return as_ptr(spla::UONE_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ABS_INT() { return as_ptr(spla::ABS_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ABS_UINT() { return as_ptr(spla::ABS_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ABS_FLOAT() { return as_ptr(spla::ABS_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_BNOT_INT() { return as_ptr(spla::BNOT_INT.ref_and_get()); } +spla_OpUnary spla_OpUnary_BNOT_UINT() { return as_ptr(spla::BNOT_UINT.ref_and_get()); } +spla_OpUnary spla_OpUnary_SQRT_FLOAT() { return as_ptr(spla::SQRT_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_LOG_FLOAT() { return as_ptr(spla::LOG_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_EXP_FLOAT() { return as_ptr(spla::EXP_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_SIN_FLOAT() { return as_ptr(spla::SIN_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_COS_FLOAT() { return as_ptr(spla::COS_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_TAN_FLOAT() { return as_ptr(spla::TAN_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ASIN_FLOAT() { return as_ptr(spla::ASIN_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ACOS_FLOAT() { return as_ptr(spla::ACOS_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ATAN_FLOAT() { return as_ptr(spla::ATAN_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_CEIL_FLOAT() { return as_ptr(spla::CEIL_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_FLOOR_FLOAT() { return as_ptr(spla::FLOOR_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_ROUND_FLOAT() { return as_ptr(spla::ROUND_FLOAT.ref_and_get()); } +spla_OpUnary spla_OpUnary_TRUNC_FLOAT() { return as_ptr(spla::TRUNC_FLOAT.ref_and_get()); } + spla_OpBinary spla_OpBinary_PLUS_INT() { return as_ptr(spla::PLUS_INT.ref_and_get()); } spla_OpBinary spla_OpBinary_PLUS_UINT() { return as_ptr(spla::PLUS_UINT.ref_and_get()); } spla_OpBinary spla_OpBinary_PLUS_FLOAT() { return as_ptr(spla::PLUS_FLOAT.ref_and_get()); } @@ -48,15 +82,21 @@ spla_OpBinary spla_OpBinary_FIRST_FLOAT() { return as_ptr(spla: spla_OpBinary spla_OpBinary_SECOND_INT() { return as_ptr(spla::SECOND_INT.ref_and_get()); } spla_OpBinary spla_OpBinary_SECOND_UINT() { return as_ptr(spla::SECOND_UINT.ref_and_get()); } spla_OpBinary spla_OpBinary_SECOND_FLOAT() { return as_ptr(spla::SECOND_FLOAT.ref_and_get()); } -spla_OpBinary spla_OpBinary_ONE_INT() { return as_ptr(spla::ONE_INT.ref_and_get()); } -spla_OpBinary spla_OpBinary_ONE_UINT() { return as_ptr(spla::ONE_UINT.ref_and_get()); } -spla_OpBinary spla_OpBinary_ONE_FLOAT() { return as_ptr(spla::ONE_FLOAT.ref_and_get()); } +spla_OpBinary spla_OpBinary_BONE_INT() { return as_ptr(spla::BONE_INT.ref_and_get()); } +spla_OpBinary spla_OpBinary_BONE_UINT() { return as_ptr(spla::BONE_UINT.ref_and_get()); } +spla_OpBinary spla_OpBinary_BONE_FLOAT() { return as_ptr(spla::BONE_FLOAT.ref_and_get()); } spla_OpBinary spla_OpBinary_MIN_INT() { return as_ptr(spla::MIN_INT.ref_and_get()); } spla_OpBinary spla_OpBinary_MIN_UINT() { return as_ptr(spla::MIN_UINT.ref_and_get()); } spla_OpBinary spla_OpBinary_MIN_FLOAT() { return as_ptr(spla::MIN_FLOAT.ref_and_get()); } spla_OpBinary spla_OpBinary_MAX_INT() { return as_ptr(spla::MAX_INT.ref_and_get()); } spla_OpBinary spla_OpBinary_MAX_UINT() { return as_ptr(spla::MAX_UINT.ref_and_get()); } spla_OpBinary spla_OpBinary_MAX_FLOAT() { return as_ptr(spla::MAX_FLOAT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LOR_INT() { return as_ptr(spla::LOR_INT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LOR_UINT() { return as_ptr(spla::LOR_UINT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LOR_FLOAT() { return as_ptr(spla::LOR_FLOAT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LAND_INT() { return as_ptr(spla::LAND_INT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LAND_UINT() { return as_ptr(spla::LAND_UINT.ref_and_get()); } +spla_OpBinary spla_OpBinary_LAND_FLOAT() { return as_ptr(spla::LAND_FLOAT.ref_and_get()); } spla_OpBinary spla_OpBinary_BOR_INT() { return as_ptr(spla::BOR_INT.ref_and_get()); } spla_OpBinary spla_OpBinary_BOR_UINT() { return as_ptr(spla::BOR_UINT.ref_and_get()); } spla_OpBinary spla_OpBinary_BAND_INT() { return as_ptr(spla::BAND_INT.ref_and_get()); } diff --git a/src/core/top.hpp b/src/core/top.hpp index 955904daf..654e928eb 100644 --- a/src/core/top.hpp +++ b/src/core/top.hpp @@ -39,6 +39,32 @@ namespace spla { +#define DECL_OP_UNA(fname, key_prefix, A0, R, ...) \ + { \ + auto func = make_ref>(); \ + \ + func->function = [](A0 a) -> R __VA_ARGS__; \ + func->name = #fname; \ + \ + std::stringstream source_builder; \ + source_builder << "(" \ + << func->get_type_arg_0()->get_cpp() \ + << " a)" #__VA_ARGS__; \ + \ + func->source = source_builder.str(); \ + \ + std::stringstream key_builder; \ + key_builder << #key_prefix << "_" \ + << func->get_type_arg_0()->get_code() \ + << func->get_type_res()->get_code(); \ + func->key = key_builder.str(); \ + \ + fname = func.as(); \ + } + +#define DECL_OP_UNA_S(name, key_prefix, T, ...) \ + DECL_OP_UNA(name, key_prefix, T, T, __VA_ARGS__) + #define DECL_OP_BIN(fname, key_prefix, A0, A1, R, ...) \ { \ auto func = make_ref>(); \ diff --git a/src/op.cpp b/src/op.cpp index 09c6d5168..0df9a6e09 100644 --- a/src/op.cpp +++ b/src/op.cpp @@ -33,6 +33,44 @@ namespace spla { + ref_ptr IDENTITY_INT; + ref_ptr IDENTITY_UINT; + ref_ptr IDENTITY_FLOAT; + ref_ptr AINV_INT; + ref_ptr AINV_UINT; + ref_ptr AINV_FLOAT; + ref_ptr MINV_INT; + ref_ptr MINV_UINT; + ref_ptr MINV_FLOAT; + ref_ptr LNOT_INT; + ref_ptr LNOT_UINT; + ref_ptr LNOT_FLOAT; + ref_ptr UONE_INT; + ref_ptr UONE_UINT; + ref_ptr UONE_FLOAT; + ref_ptr ABS_INT; + ref_ptr ABS_UINT; + ref_ptr ABS_FLOAT; + + ref_ptr BNOT_INT; + ref_ptr BNOT_UINT; + + ref_ptr SQRT_FLOAT; + ref_ptr LOG_FLOAT; + ref_ptr EXP_FLOAT; + ref_ptr SIN_FLOAT; + ref_ptr COS_FLOAT; + ref_ptr TAN_FLOAT; + ref_ptr ASIN_FLOAT; + ref_ptr ACOS_FLOAT; + ref_ptr ATAN_FLOAT; + ref_ptr CEIL_FLOAT; + ref_ptr FLOOR_FLOAT; + ref_ptr ROUND_FLOAT; + ref_ptr TRUNC_FLOAT; + + ////////////////////////////////////////////////////////////////////////////// + ref_ptr PLUS_INT; ref_ptr PLUS_UINT; ref_ptr PLUS_FLOAT; @@ -57,9 +95,9 @@ namespace spla { ref_ptr SECOND_UINT; ref_ptr SECOND_FLOAT; - ref_ptr ONE_INT; - ref_ptr ONE_UINT; - ref_ptr ONE_FLOAT; + ref_ptr BONE_INT; + ref_ptr BONE_UINT; + ref_ptr BONE_FLOAT; ref_ptr MIN_INT; ref_ptr MIN_UINT; @@ -68,6 +106,13 @@ namespace spla { ref_ptr MAX_UINT; ref_ptr MAX_FLOAT; + ref_ptr LOR_INT; + ref_ptr LOR_UINT; + ref_ptr LOR_FLOAT; + ref_ptr LAND_INT; + ref_ptr LAND_UINT; + ref_ptr LAND_FLOAT; + ref_ptr BOR_INT; ref_ptr BOR_UINT; ref_ptr BAND_INT; @@ -75,6 +120,8 @@ namespace spla { ref_ptr BXOR_INT; ref_ptr BXOR_UINT; + ////////////////////////////////////////////////////////////////////////////// + ref_ptr EQZERO_INT; ref_ptr EQZERO_UINT; ref_ptr EQZERO_FLOAT; @@ -107,6 +154,42 @@ namespace spla { inline T max(T a, T b) { return std::max(a, b); } void register_ops() { + DECL_OP_UNA_S(IDENTITY_INT, IDENSTITY, T_INT, { return a; }); + DECL_OP_UNA_S(IDENTITY_UINT, IDENSTITY, T_UINT, { return a; }); + DECL_OP_UNA_S(IDENTITY_FLOAT, IDENSTITY, T_FLOAT, { return a; }); + DECL_OP_UNA_S(AINV_INT, AINV, T_INT, { return -a; }); + DECL_OP_UNA_S(AINV_UINT, AINV, T_UINT, { return -a; }); + DECL_OP_UNA_S(AINV_FLOAT, AINV, T_FLOAT, { return -a; }); + DECL_OP_UNA_S(MINV_INT, MINV, T_INT, { return 1 / a; }); + DECL_OP_UNA_S(MINV_UINT, MINV, T_UINT, { return 1 / a; }); + DECL_OP_UNA_S(MINV_FLOAT, MINV, T_FLOAT, { return 1.0f / a; }); + DECL_OP_UNA_S(LNOT_INT, LNOT, T_INT, { return !(a != 0); }); + DECL_OP_UNA_S(LNOT_UINT, LNOT, T_UINT, { return !(a != 0); }); + DECL_OP_UNA_S(LNOT_FLOAT, LNOT, T_FLOAT, { return !(a != 0); }); + DECL_OP_UNA_S(UONE_INT, UONE, T_INT, { return 1; }); + DECL_OP_UNA_S(UONE_UINT, UONE, T_UINT, { return 1; }); + DECL_OP_UNA_S(UONE_FLOAT, UONE, T_FLOAT, { return 1; }); + DECL_OP_UNA_S(ABS_INT, ABS, T_INT, { return abs(a); }); + DECL_OP_UNA_S(ABS_UINT, ABS, T_UINT, { return a; }); + DECL_OP_UNA_S(ABS_FLOAT, ABS, T_FLOAT, { return fabs(a); }); + + DECL_OP_UNA_S(BNOT_INT, BNOT, T_INT, { return ~a; }); + DECL_OP_UNA_S(BNOT_UINT, BNOT, T_UINT, { return ~a; }); + + DECL_OP_UNA_S(SQRT_FLOAT, SQRT, T_FLOAT, { return sqrt(a); }); + DECL_OP_UNA_S(LOG_FLOAT, LOG, T_FLOAT, { return log(a); }); + DECL_OP_UNA_S(EXP_FLOAT, EXP, T_FLOAT, { return exp(a); }); + DECL_OP_UNA_S(SIN_FLOAT, SIN, T_FLOAT, { return sin(a); }); + DECL_OP_UNA_S(COS_FLOAT, COS, T_FLOAT, { return cos(a); }); + DECL_OP_UNA_S(TAN_FLOAT, TAN, T_FLOAT, { return tan(a); }); + DECL_OP_UNA_S(ASIN_FLOAT, ASIN, T_FLOAT, { return asin(a); }); + DECL_OP_UNA_S(ACOS_FLOAT, ACOS, T_FLOAT, { return acos(a); }); + DECL_OP_UNA_S(ATAN_FLOAT, ATAN, T_FLOAT, { return atan(a); }); + DECL_OP_UNA_S(CEIL_FLOAT, CEIL, T_FLOAT, { return ceil(a); }); + DECL_OP_UNA_S(FLOOR_FLOAT, FLOOR, T_FLOAT, { return floor(a); }); + DECL_OP_UNA_S(ROUND_FLOAT, ROUND, T_FLOAT, { return round(a); }); + DECL_OP_UNA_S(TRUNC_FLOAT, TRUNC, T_FLOAT, { return trunc(a); }); + DECL_OP_BIN_S(PLUS_INT, PLUS, T_INT, { return a + b; }); DECL_OP_BIN_S(PLUS_UINT, PLUS, T_UINT, { return a + b; }); DECL_OP_BIN_S(PLUS_FLOAT, PLUS, T_FLOAT, { return a + b; }); @@ -131,9 +214,9 @@ namespace spla { DECL_OP_BIN_S(SECOND_UINT, SECOND, T_UINT, { return b; }); DECL_OP_BIN_S(SECOND_FLOAT, SECOND, T_FLOAT, { return b; }); - DECL_OP_BIN_S(ONE_INT, ONE, T_INT, { return 1; }); - DECL_OP_BIN_S(ONE_UINT, ONE, T_UINT, { return 1; }); - DECL_OP_BIN_S(ONE_FLOAT, ONE, T_FLOAT, { return 1; }); + DECL_OP_BIN_S(BONE_INT, BONE, T_INT, { return 1; }); + DECL_OP_BIN_S(BONE_UINT, BONE, T_UINT, { return 1; }); + DECL_OP_BIN_S(BONE_FLOAT, BONE, T_FLOAT, { return 1; }); DECL_OP_BIN_S(MIN_INT, MIN, T_INT, { return min(a, b); }); DECL_OP_BIN_S(MIN_UINT, MIN, T_UINT, { return min(a, b); }); @@ -142,6 +225,13 @@ namespace spla { DECL_OP_BIN_S(MAX_UINT, MAX, T_UINT, { return max(a, b); }); DECL_OP_BIN_S(MAX_FLOAT, MAX, T_FLOAT, { return max(a, b); }); + DECL_OP_BIN_S(LOR_INT, LOR, T_INT, { return a || b; }); + DECL_OP_BIN_S(LOR_UINT, LOR, T_UINT, { return a || b; }); + DECL_OP_BIN_S(LOR_FLOAT, LOR, T_FLOAT, { return a || b; }); + DECL_OP_BIN_S(LAND_INT, LAND, T_INT, { return a && b; }); + DECL_OP_BIN_S(LAND_UINT, LAND, T_UINT, { return a && b; }); + DECL_OP_BIN_S(LAND_FLOAT, LAND, T_FLOAT, { return a && b; }); + DECL_OP_BIN_S(BOR_INT, BOR, T_INT, { return a | b; }); DECL_OP_BIN_S(BOR_UINT, BOR, T_UINT, { return a | b; }); DECL_OP_BIN_S(BAND_INT, BAND, T_INT, { return a & b; });