diff --git a/CHANGELOG.md b/CHANGELOG.md index 03e1f4d7..4c33b344 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ - Add faster Torch interop path using `return_ctype` argument to `wp.from_torch()` - Handle incompatible CUDA driver versions gracefully - Fix handling of `upaxis` variable in `ModelBuilder` and the rendering thereof in `OpenGLRenderer` +- Add `wp.abs()` and `wp.sign()` for vectors ## [1.2.2] - 2024-07-04 @@ -43,7 +44,6 @@ - Add documentation for dynamic loop autograd limitations - Conform to Python's syntax for function arguments when calling built-ins inside of kernels, thus extending support for keyword arguments - Implement the assignment operator for `wp.quat` -- Add `wp.abs()`, `wp.clamp()`, and `wp.sign()` for vectors ## [1.2.1] - 2024-06-14 diff --git a/docs/modules/functions.rst b/docs/modules/functions.rst index 984fe308..dd87d2ad 100644 --- a/docs/modules/functions.rst +++ b/docs/modules/functions.rst @@ -145,13 +145,6 @@ Scalar Math Clamp the value of ``x`` to the range [a, b]. -.. py:function:: clamp(a: Vector[Any,Scalar], low: Vector[Any,Scalar], high: Vector[Any,Scalar]) -> Vector[Any,Scalar] - :noindex: - :nocontentsentry: - - Clamp the elements of ``a`` to the elements from the range [low, high]. - - .. py:function:: abs(x: Scalar) -> Scalar Return the absolute value of ``x``. diff --git a/warp/builtins.py b/warp/builtins.py index c8f97e3c..9e954f04 100644 --- a/warp/builtins.py +++ b/warp/builtins.py @@ -502,19 +502,6 @@ def float_sametypes_value_func(arg_types: Mapping[str, type], arg_values: Mappin missing_grad=True, ) -add_builtin( - "clamp", - input_types={ - "a": vector(length=Any, dtype=Scalar), - "low": vector(length=Any, dtype=Scalar), - "high": vector(length=Any, dtype=Scalar), - }, - constraint=sametypes, - value_func=sametypes_create_value_func(vector(length=Any, dtype=Scalar)), - doc="Clamp the elements of ``a`` to the elements from the range [low, high].", - group="Vector Math", -) - add_builtin( "abs", input_types={"a": vector(length=Any, dtype=Scalar)}, diff --git a/warp/native/exports.h b/warp/native/exports.h index 975b5838..7c2e6013 100644 --- a/warp/native/exports.h +++ b/warp/native/exports.h @@ -179,42 +179,6 @@ WP_API void builtin_clamp_uint16_uint16_uint16(uint16 x, uint16 a, uint16 b, uin WP_API void builtin_clamp_uint32_uint32_uint32(uint32 x, uint32 a, uint32 b, uint32* ret) { *ret = wp::clamp(x, a, b); } WP_API void builtin_clamp_uint64_uint64_uint64(uint64 x, uint64 a, uint64 b, uint64* ret) { *ret = wp::clamp(x, a, b); } WP_API void builtin_clamp_uint8_uint8_uint8(uint8 x, uint8 a, uint8 b, uint8* ret) { *ret = wp::clamp(x, a, b); } -WP_API void builtin_clamp_vec2h_vec2h_vec2h(vec2h& a, vec2h& low, vec2h& high, vec2h* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3h_vec3h_vec3h(vec3h& a, vec3h& low, vec3h& high, vec3h* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4h_vec4h_vec4h(vec4h& a, vec4h& low, vec4h& high, vec4h* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_spatial_vectorh_spatial_vectorh_spatial_vectorh(spatial_vectorh& a, spatial_vectorh& low, spatial_vectorh& high, spatial_vectorh* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2f_vec2f_vec2f(vec2f& a, vec2f& low, vec2f& high, vec2f* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3f_vec3f_vec3f(vec3f& a, vec3f& low, vec3f& high, vec3f* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4f_vec4f_vec4f(vec4f& a, vec4f& low, vec4f& high, vec4f* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_spatial_vectorf_spatial_vectorf_spatial_vectorf(spatial_vectorf& a, spatial_vectorf& low, spatial_vectorf& high, spatial_vectorf* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2d_vec2d_vec2d(vec2d& a, vec2d& low, vec2d& high, vec2d* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3d_vec3d_vec3d(vec3d& a, vec3d& low, vec3d& high, vec3d* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4d_vec4d_vec4d(vec4d& a, vec4d& low, vec4d& high, vec4d* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_spatial_vectord_spatial_vectord_spatial_vectord(spatial_vectord& a, spatial_vectord& low, spatial_vectord& high, spatial_vectord* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2s_vec2s_vec2s(vec2s& a, vec2s& low, vec2s& high, vec2s* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3s_vec3s_vec3s(vec3s& a, vec3s& low, vec3s& high, vec3s* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4s_vec4s_vec4s(vec4s& a, vec4s& low, vec4s& high, vec4s* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2i_vec2i_vec2i(vec2i& a, vec2i& low, vec2i& high, vec2i* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3i_vec3i_vec3i(vec3i& a, vec3i& low, vec3i& high, vec3i* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4i_vec4i_vec4i(vec4i& a, vec4i& low, vec4i& high, vec4i* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2l_vec2l_vec2l(vec2l& a, vec2l& low, vec2l& high, vec2l* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3l_vec3l_vec3l(vec3l& a, vec3l& low, vec3l& high, vec3l* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4l_vec4l_vec4l(vec4l& a, vec4l& low, vec4l& high, vec4l* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2b_vec2b_vec2b(vec2b& a, vec2b& low, vec2b& high, vec2b* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3b_vec3b_vec3b(vec3b& a, vec3b& low, vec3b& high, vec3b* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4b_vec4b_vec4b(vec4b& a, vec4b& low, vec4b& high, vec4b* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2us_vec2us_vec2us(vec2us& a, vec2us& low, vec2us& high, vec2us* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3us_vec3us_vec3us(vec3us& a, vec3us& low, vec3us& high, vec3us* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4us_vec4us_vec4us(vec4us& a, vec4us& low, vec4us& high, vec4us* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2ui_vec2ui_vec2ui(vec2ui& a, vec2ui& low, vec2ui& high, vec2ui* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3ui_vec3ui_vec3ui(vec3ui& a, vec3ui& low, vec3ui& high, vec3ui* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4ui_vec4ui_vec4ui(vec4ui& a, vec4ui& low, vec4ui& high, vec4ui* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2ul_vec2ul_vec2ul(vec2ul& a, vec2ul& low, vec2ul& high, vec2ul* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3ul_vec3ul_vec3ul(vec3ul& a, vec3ul& low, vec3ul& high, vec3ul* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4ul_vec4ul_vec4ul(vec4ul& a, vec4ul& low, vec4ul& high, vec4ul* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec2ub_vec2ub_vec2ub(vec2ub& a, vec2ub& low, vec2ub& high, vec2ub* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec3ub_vec3ub_vec3ub(vec3ub& a, vec3ub& low, vec3ub& high, vec3ub* ret) { *ret = wp::clamp(a, low, high); } -WP_API void builtin_clamp_vec4ub_vec4ub_vec4ub(vec4ub& a, vec4ub& low, vec4ub& high, vec4ub* ret) { *ret = wp::clamp(a, low, high); } WP_API void builtin_abs_float16(float16 x, float16* ret) { *ret = wp::abs(x); } WP_API void builtin_abs_float32(float32 x, float32* ret) { *ret = wp::abs(x); } WP_API void builtin_abs_float64(float64 x, float64* ret) { *ret = wp::abs(x); } diff --git a/warp/native/vec.h b/warp/native/vec.h index dc1ddec5..30c8e742 100644 --- a/warp/native/vec.h +++ b/warp/native/vec.h @@ -648,18 +648,6 @@ inline CUDA_CALLABLE unsigned argmax(vec_t v) return ret; } -template -inline CUDA_CALLABLE vec_t clamp(vec_t v, vec_t a, vec_t b) -{ - vec_t ret; - for (unsigned i=0; i < Length; ++i) - { - ret[i] = v[i] < a[i] ? a[i] : v[i] > b[i] ? b[i] : v[i]; - } - - return ret; -} - template inline CUDA_CALLABLE vec_t abs(vec_t v) { @@ -1082,30 +1070,6 @@ inline CUDA_CALLABLE void adj_max(const vec_t &v, vec_t -inline CUDA_CALLABLE void adj_clamp( - const vec_t& v, const vec_t& a, const vec_t& b, - vec_t& adj_v, vec_t& adj_a, vec_t& adj_b, - const vec_t& adj_ret -) -{ - for (unsigned i=0; i < Length; ++i) - { - if (v[i] < a[i]) - { - adj_a[i] += adj_ret[i]; - } - else if (v[i] > b[i]) - { - adj_b[i] += adj_ret[i]; - } - else - { - adj_v[i] += adj_ret[i]; - } - } -} - template inline CUDA_CALLABLE void adj_abs( const vec_t& v, diff --git a/warp/stubs.py b/warp/stubs.py index b43bfd22..fcdb036b 100644 --- a/warp/stubs.py +++ b/warp/stubs.py @@ -161,12 +161,6 @@ def clamp(x: Scalar, a: Scalar, b: Scalar) -> Scalar: ... -@over -def clamp(a: Vector[Any, Scalar], low: Vector[Any, Scalar], high: Vector[Any, Scalar]) -> Vector[Any, Scalar]: - """Clamp the elements of ``a`` to the elements from the range [low, high].""" - ... - - @over def abs(x: Scalar) -> Scalar: """Return the absolute value of ``x``.""" diff --git a/warp/tests/test_vec_scalar_ops.py b/warp/tests/test_vec_scalar_ops.py index 9bcc1c36..5ff06660 100644 --- a/warp/tests/test_vec_scalar_ops.py +++ b/warp/tests/test_vec_scalar_ops.py @@ -1902,44 +1902,6 @@ def check_vector_constants(): wp.launch(kernel, dim=1, inputs=[], device=device) -def test_clamp(test, device, dtype, register_kernels=False): - wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)] - vec2 = wp.types.vector(length=2, dtype=wptype) - vec3 = wp.types.vector(length=3, dtype=wptype) - vec4 = wp.types.vector(length=4, dtype=wptype) - vec5 = wp.types.vector(length=5, dtype=wptype) - - def check_vector_clamp(): - v2 = vec2(wptype(1), wptype(2)) - res2 = wp.clamp(v2, vec2(wptype(0), wptype(1)), vec2(wptype(2), wptype(2))) - wp.expect_eq(res2, vec2(wptype(1), wptype(2))) - - v3 = vec3(wptype(1), wptype(2), wptype(3)) - res3 = wp.clamp(v3, vec3(wptype(2), wptype(1), wptype(3)), vec3(wptype(3), wptype(3), wptype(4))) - wp.expect_eq(res3, vec3(wptype(2), wptype(2), wptype(3))) - - v4 = vec4(wptype(1), wptype(2), wptype(3), wptype(4)) - res4 = wp.clamp( - v4, vec4(wptype(0), wptype(1), wptype(3), wptype(3)), vec4(wptype(1), wptype(2), wptype(3), wptype(5)) - ) - wp.expect_eq(res4, vec4(wptype(1), wptype(2), wptype(3), wptype(4))) - - v5 = vec5(wptype(1), wptype(2), wptype(3), wptype(4), wptype(5)) - res5 = wp.clamp( - v5, - vec5(wptype(0), wptype(1), wptype(2), wptype(4), wptype(6)), - vec5(wptype(1), wptype(2), wptype(5), wptype(5), wptype(7)), - ) - wp.expect_eq(res5, vec5(wptype(1), wptype(2), wptype(3), wptype(4), wptype(6))) - - kernel = getkernel(check_vector_clamp, suffix=dtype.__name__) - - if register_kernels: - return - - wp.launch(kernel, dim=1, inputs=[], device=device) - - def test_abs(test, device, dtype, register_kernels=False): wptype = wp.types.np_dtype_to_warp_type[np.dtype(dtype)] vec2 = wp.types.vector(length=2, dtype=wptype) @@ -2200,9 +2162,6 @@ class TestVecScalarOps(unittest.TestCase): add_function_test_register_kernel( TestVecScalarOps, f"test_constants_{dtype.__name__}", test_constants, devices=devices, dtype=dtype ) - add_function_test_register_kernel( - TestVecScalarOps, f"test_clamp_{dtype.__name__}", test_clamp, devices=devices, dtype=dtype - ) if dtype not in np_unsigned_int_types: add_function_test_register_kernel(