/* ****************************************************************************** * * * This program and the accompanying materials are made available under the * terms of the Apache License, Version 2.0 which is available at * https://www.apache.org/licenses/LICENSE-2.0. * * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * * SPDX-License-Identifier: Apache-2.0 ******************************************************************************/ #pragma once #ifndef OP_MACROS_UNARY_H_ #define OP_MACROS_UNARY_H_ #include "op_types.h" #include namespace simdOps { // ============================================================================= // UNARY MATH OPERATION MACROS // ============================================================================= /** * @brief Declares a unary math operation with proper SIMD handling */ #define DECLARE_UNARY_MATH_OP(OP_NAME, MATH_FUNC) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { return sd::math::MATH_FUNC(d1); } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; /** * @brief Declares a unary math operation with different input/output types */ #define DECLARE_UNARY_MATH_OP_XZ(OP_NAME, MATH_FUNC) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static Z op_logic(X d1, Z* params) { return sd::math::MATH_FUNC(d1); } \ static SD_HOST_DEVICE Z op_simd(X d1, Z* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special no_op_exec_special_cuda; \ static SD_HOST_DEVICE Z op(X d1, Z* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; // ============================================================================= // UNARY SIMPLE OPERATION MACROS // ============================================================================= /** * @brief Declares a simple unary operation with direct expression */ #define DECLARE_UNARY_SIMPLE_OP(OP_NAME, OPERATION) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { \ if constexpr (std::is_same_v) { \ return d1; /* Safe default for bool to avoid multiplication warnings */ \ } else { \ return OPERATION; \ } \ } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value || std::is_same_v) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; // ============================================================================= // UNARY CONDITIONAL OPERATION MACROS // ============================================================================= /** * @brief Declares a unary conditional operation */ #define DECLARE_UNARY_CONDITIONAL_OP(OP_NAME, CONDITION, TRUE_VAL, FALSE_VAL) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { return (CONDITION) ? (TRUE_VAL) : (FALSE_VAL); } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; // ============================================================================= // UNARY COMPLEX CONDITIONAL OPERATION MACROS // ============================================================================= /** * @brief Declares a unary operation with complex conditional logic (if-else chains) */ /** * @brief Declares a unary operation with complex conditional logic (if-else chains) */ #define DECLARE_UNARY_COMPLEX_CONDITIONAL_OP(OP_NAME, IF_CONDITION1, RETURN1, ELIF_CONDITION2, RETURN2, ELSE_RETURN) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { \ if (IF_CONDITION1) \ return RETURN1; \ else if (ELIF_CONDITION2) \ return RETURN2; \ else \ return ELSE_RETURN; \ } \ SD_OP_DEF static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same; \ no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value || \ simdOps::is_simd_unsupported_argument_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; // ============================================================================= // UNARY COMPLEX MATH EXPRESSION MACROS // ============================================================================= /** * @brief Declares a unary operation with complex mathematical expressions */ #define DECLARE_UNARY_COMPLEX_MATH_OP(OP_NAME, MATH_EXPRESSION) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { return MATH_EXPRESSION; } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; /** * @brief Declares a unary operation with complex math expression and different input/output types */ #define DECLARE_UNARY_COMPLEX_MATH_OP_XZ(OP_NAME, MATH_EXPRESSION) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static Z op_logic(X d1, Z* params) { return MATH_EXPRESSION; } \ static SD_HOST_DEVICE SD_INLINE Z op_simd(X d1, Z* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special no_op_exec_special_cuda; \ static SD_HOST_DEVICE Z op(X d1, Z* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; // ============================================================================= // UNARY IDENTITY OPERATION MACROS // ============================================================================= /** * @brief Declares a unary identity operation (just returns input) */ #define DECLARE_UNARY_IDENTITY_OP(OP_NAME) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { return d1; } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; /** * @brief DECLARE_UNARY_SIMD_SAFE_OP macro - Add this to op_macros_unary.h * This macro creates unary operations with proper SIMD handling */ #define DECLARE_UNARY_SIMD_SAFE_OP(OP_NAME, OPERATION) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { OPERATION } \ static SD_HOST_DEVICE X op_simd(X d1, X* params) { return op_logic(d1, params); } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; /** * @brief Alternative version using the new SIMD-safe pattern for consistency */ #define DECLARE_UNARY_SIMD_SAFE_OP_V2(OP_NAME, OPERATION) \ template \ class OP_NAME { \ private: \ SD_HOST_DEVICE SD_INLINE static X op_logic(X d1, X* params) { OPERATION } \ \ template \ SD_HOST_DEVICE SD_INLINE static enable_if_simd_safe op_simd(TX d1, TX* params) { \ return op_logic(d1, params); \ } \ \ template \ SD_HOST_DEVICE SD_INLINE static enable_if_simd_unsafe op_simd(TX d1, TX* params) { \ return op_logic(d1, params); \ } \ \ public: \ no_op_exec_special_same no_op_exec_special_same_cuda; \ static SD_HOST_DEVICE X op(X d1, X* params) { \ if constexpr (simdOps::is_simd_unsupported_return_type::value) \ return op_logic(d1, params); \ else \ return op_simd(d1, params); \ } \ }; } // namespace simdOps #endif // OP_MACROS_UNARY_H_