@@ -736,44 +736,65 @@ template <void unary_op(ggml_backend_cann_context&, aclTensor*, aclTensor*)>
736736    aclTensor* acl_dst = ggml_cann_create_tensor (dst);
737737
738738    unary_op (ctx, acl_src, acl_dst);
739+ 
740+     ACL_CHECK (aclDestroyTensor (acl_src));
741+     ACL_CHECK (aclDestroyTensor (acl_dst));
742+ }
743+ 
744+ /* *
745+  * @brief   Applies a unary operation to a ggml tensor using the CANN backend. 
746+  * 
747+  * @details This function performs a unary operation on the input tensor using 
748+  * a user-provided lambda or callable object `unary_op`, which accepts the CANN 
749+  * context and two ACL tensors (source and destination). Internally, this function 
750+  * creates ACL representations of the ggml tensors and invokes the unary operation. 
751+  * The result is stored in the destination tensor `dst`. This utility abstracts the 
752+  * common boilerplate of tensor conversion and cleanup when implementing unary ops. 
753+  * 
754+  * @param unary_op A callable that performs the unary operation using CANN APIs. 
755+  * @param ctx The CANN context used for operations. 
756+  * @param dst The destination tensor where the result will be stored. 
757+  *            The source tensor is retrieved from `dst->src[0]`. 
758+  */  
759+ static  void  ggml_cann_unary_op_func (
760+     std::function<void (ggml_backend_cann_context&, aclTensor*, aclTensor*)> unary_op,
761+     ggml_backend_cann_context& ctx, ggml_tensor* dst) {
762+     ggml_tensor* src = dst->src [0 ];
763+ 
764+     aclTensor* acl_src = ggml_cann_create_tensor (src);
765+     aclTensor* acl_dst = ggml_cann_create_tensor (dst);
766+ 
767+     unary_op (ctx, acl_src, acl_dst);
768+ 
739769    ACL_CHECK (aclDestroyTensor (acl_src));
740770    ACL_CHECK (aclDestroyTensor (acl_dst));
741771}
742772
743773/* *
744-  * @brief Launches a unary aclnn operator on a destination tensor . 
774+  * @brief Helper macro to invoke a unary ACL operation using ggml_cann_unary_op . 
745775 * 
746-  * This macro prepares the source and destination tensors from the given  
747-  * ggml_tensor `dst`, then invokes  the specified aclnn operator using  
748-  * the provided parameters . 
776+  * This macro defines an inline lambda wrapping a specific ACL operation name,  
777+  * and passes it to  the templated ggml_cann_unary_op function. It simplifies  
778+  * calling unary ops by hiding  the lambda boilerplate . 
749779 * 
750-  * It automatically handles tensor conversion to `aclTensor` format, memory  
751-  * allocation, and resource destruction. The aclnn operator will be launched  
752-  * asynchronously on the specified stream using the workspace allocator, and  
753-  * will follow the stream's execution order.  
780+  * Internally, the lambda will call:  
781+  * @code  
782+  * GGML_CANN_CALL_ACLNN_OP(OP_NAME, acl_src, acl_dst);  
783+  * @endcode  
754784 * 
755-  * @param OP_NAME The name of the aclnn operator (e.g., Gelu, Relu, etc.). 
756-  * @param __VA_ARGS__ Optional additional arguments to pass between the source 
757-  *        and destination tensors (e.g., scalar parameters for the operator). 
785+  * @param OP_NAME The name of the ACL unary operator to invoke via GGML_CANN_CALL_ACLNN_OP. 
758786 * 
759-  * @note 
760-  * This macro assumes that `dst` is a unary operation output tensor, 
761-  * i.e., `dst->src[0]` is its input tensor. 
762-  * 
763-  * The macro handles the conversion from `ggml_tensor` to `aclTensor` and ensures 
764-  * proper destruction after the operator is launched. It should be used in 
765-  * contexts where `ctx` (of type `ggml_backend_cann_context&`) and `dst` 
766-  * (of type `ggml_tensor*`) are available. 
767-  */  
768- #define  GGML_CANN_CALL_UNARY_OP (OP_NAME, ...)                              \
769-     do  {                                                                   \
770-         ggml_tensor* src = dst->src [0 ];                                    \
771-         aclTensor* acl_src = ggml_cann_create_tensor (src);                 \
772-         aclTensor* acl_dst = ggml_cann_create_tensor (dst);                 \
773-                                                                            \
774-         GGML_CANN_CALL_ACLNN_OP (OP_NAME, acl_src, ##__VA_ARGS__, acl_dst); \
775-                                                                            \
776-         ACL_CHECK (aclDestroyTensor (acl_src));                              \
777-         ACL_CHECK (aclDestroyTensor (acl_dst));                              \
778-     } while  (0 )
787+  * @see ggml_cann_unary_op 
788+  * @see GGML_CANN_CALL_ACLNN_OP 
789+  */  
790+ #define  GGML_CANN_CALL_UNARY_OP (OP_NAME )                         \
791+     do  {                                                         \
792+         auto  lambda = [](ggml_backend_cann_context& ctx,         \
793+             aclTensor* acl_src,                                  \
794+             aclTensor* acl_dst) {                                \
795+             GGML_CANN_CALL_ACLNN_OP (OP_NAME, acl_src, acl_dst);  \
796+         };                                                       \
797+         ggml_cann_unary_op_func (lambda, ctx, dst);               \
798+     }                                                            \
799+     while  (0 )
779800#endif   //  CANN_ACLNN_OPS
0 commit comments