char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Aman Guptaggml: add SWIGLU_CLAMP (#27930)0190529ec

char/aliceai-t5-moe
52.9 KiB1191 linesraw
1/**
2 * Copyright (c) 2023-2026 The ggml authors
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to
6 * deal in the Software without restriction, including without limitation the
7 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22
23#ifndef CANN_ACLNN_OPS
24#define CANN_ACLNN_OPS
25
26#include "acl_tensor.h"
27#include "common.h"
28
29#include <aclnnop/aclnn_abs.h>
30#include <aclnnop/aclnn_arange.h>
31#include <aclnnop/aclnn_argsort.h>
32#include <aclnnop/aclnn_cat.h>
33#include <aclnnop/aclnn_clamp.h>
34#include <aclnnop/aclnn_cos.h>
35#include <aclnnop/aclnn_cumsum.h>
36#include <aclnnop/aclnn_tril.h>
37#include <aclnnop/aclnn_triu.h>
38#include <aclnnop/aclnn_exp.h>
39#include <aclnnop/aclnn_gelu.h>
40#include <aclnnop/aclnn_gelu_v2.h>
41#include <aclnnop/aclnn_hardsigmoid.h>
42#include <aclnnop/aclnn_hardswish.h>
43#include <aclnnop/aclnn_leaky_relu.h>
44#include <aclnnop/aclnn_log.h>
45#include <aclnnop/aclnn_logsoftmax.h>
46#include <aclnnop/aclnn_neg.h>
47#include <aclnnop/aclnn_norm.h>
48#include <aclnnop/aclnn_relu.h>
49#include <aclnnop/aclnn_sigmoid.h>
50#include <aclnnop/aclnn_sign.h>
51#include <aclnnop/aclnn_silu.h>
52#include <aclnnop/aclnn_sin.h>
53#include <aclnnop/aclnn_softplus.h>
54#include <aclnnop/aclnn_swi_glu.h>
55#include <aclnnop/aclnn_geglu.h>
56#include <aclnnop/aclnn_slice.h>
57#include <aclnnop/aclnn_sqrt.h>
58#include <aclnnop/aclnn_tanh.h>
59
60#include <functional>
61#include <unordered_set>
62
63/**
64 * @brief   Repeats a ggml tensor along each dimension to match the dimensions
65 *          of another tensor.
66 *
67 * @details This function repeats the elements of a source ggml tensor along
68 *          each dimension to create a destination tensor with the specified
69 *          dimensions. The operation is performed using the ACL backend and
70 *          executed asynchronously on the device.
71 *
72 * @param   ctx The CANN context used for operations.
73 * @param   dst The ggml tensor representing the destination, which op is
74 *              GGML_OP_REPEAT and specifies the desired dimensions.
75 */
76void ggml_cann_repeat(ggml_backend_cann_context & ctx, ggml_tensor * dst);
77
78void ggml_cann_swiglu(ggml_backend_cann_context & ctx, ggml_tensor * dst);
79void ggml_cann_swiglu_clamp(ggml_backend_cann_context & ctx, ggml_tensor * dst);
80void ggml_cann_geglu(ggml_backend_cann_context & ctx, ggml_tensor * dst, int64_t approximate);
81
82/**
83 * @brief   Applies the Leaky ReLU activation function to a tensor using the CANN
84 *          backend.
85 *
86 * @details This function computes the Leaky ReLU activation for each element of
87 *          the input tensor. The Leaky ReLU function allows a small gradient
88 *          when the unit is not active (i.e., when the input is negative). The
89 *          Leaky ReLU function is defined as:
90 *          \f[
91 *              \text{dst} = \max(0, src) + \text{negativeSlope} \cdot \min(0,
92 *               src)
93 *          \f]
94 *          `negativeSlope` is in dst->params.
95 *
96 * @param ctx The CANN context used for operations.
97 * @param dst The destination tensor where the result of the Leaky ReLU
98 *            activation is stored, which op is `GGML_OP_LEAKY_RELU`
99 */
100void ggml_cann_leaky_relu(ggml_backend_cann_context & ctx, ggml_tensor * dst);
101
102/**
103 * @brief    Concatenates multiple tensors along a specified dimension using the
104 *           CANN backend.
105 *
106 * @param ctx        The CANN context used for operations.
107 * @param tensorList A pointer to the list of tensors to be concatenated.
108 * @param dst        The destination tensor where the result of the
109 *                   concatenation is stored. dst->op is `GGML_OP_CONCAT`.
110 * @param concat_dim The dimension along which the tensors are concatenated.
111 *
112 * @attention tensorList length should be 2 and the dimension using for concat
113 *            default to 1.
114 */
115void ggml_cann_concat(ggml_backend_cann_context & ctx, ggml_tensor * dst);
116
117/**
118 * @brief   Generates a sequence of evenly spaced values within a specified
119 *          interval for a ggml tensor using the CANN backend.
120 *
121 * @details This function creates a sequence of numbers over a specified i
122 *          nterval, starting from `start`, ending before `stop`, and
123 *          incrementing by `step`. The sequence is stored in the destination
124 *          tensor `dst`.
125 *
126 * @param ctx The CANN context used for operations.
127 * @param dst The destination tensor where the generated sequence will be stored.
128 *            `start`, 'stop' and 'step' are in dst->op_params and dst->op is
129 *            `GGML_OP_ARANGE`.
130 */
131void ggml_cann_arange(ggml_backend_cann_context & ctx, ggml_tensor * dst);
132
133/**
134 * @brief   Applies a clamp operation to the elements of a ggml tensor using the
135 *          CANN backend.
136 *
137 * @details This function clamps the elements of the input tensor `src` to a
138 *          specified range defined by `min` and `max` values. The result is
139 *          stored in the destination tensor `dst`. The operation is defined as:
140 *          \f[
141 *              y = \max(\min(x, max\_value), min\_value)
142 *           \f]
143 *          where `x` is an element of the input tensor, and `y` is the
144 *          corresponding element in the output tensor.
145 * @param ctx The CANN context used for operations.
146 * @param dst The destination tensor where the clamped values will be stored.
147 *            dst->op is `GGML_OP_CLAMP`, `min` and `max` value is in dst->params.
148 */
149void ggml_cann_clamp(ggml_backend_cann_context & ctx, ggml_tensor * dst);
150
151/**
152 * @brief   Scales the elements of a ggml tensor by a constant factor using the
153 *          CANN backend.
154 *
155 * @details This function multiplies each element of the input tensor `src` by
156 *          a scaling factor `scale`, storing the result in the destination
157 *          tensor `dst`. The operation is defined as:
158 *          \f[
159 *             dst = src \times scale
160 *          \f]
161 *
162 * @param ctx The CANN context used for operations.
163 * @param dst The destination tensor where the scaled values will be stored.
164 *            dst->op is `GGML_OP_SCALE` and `scale` value is in dst->params.
165 */
166void ggml_cann_scale(ggml_backend_cann_context & ctx, ggml_tensor * dst);
167
168/**
169 * @brief   Sorts the elements of a ggml tensor and returns the indices that
170 *          would sort the tensor using the CANN backend.
171 *
172 * @details This function performs an argsort operation on the input tensor
173 *          `src`. It sorts the elements of `src` in either ascending or
174 *          descending order, depending on the `GGML_SORT_ORDER_DESC`,
175 *          and returns the indices that would sort the original tensor.
176 *
177 * @param ctx The CANN context used for operations.
178 * @param dst The destination tensor where the sorted indices will be stored.
179 *            dst->op is `GGML_OP_ARGSORT`.
180 */
181void ggml_cann_argsort(ggml_backend_cann_context & ctx, ggml_tensor * dst);
182
183/**
184 * @brief   Computes the Layer Normalization for a ggml tensor using the CANN
185 *          backend.
186 *
187 * @details This function applies the Layer Normalization operation on the
188 *          input tensor `src` and stores the result in the destination tensor
189 *          `dst`. Layer Normalization normalizes the features at each sample in
190 *          a mini-batch independently. It is commonly used in neural networks
191 *          to normalize the activations of a layer by adjusting and scaling
192 *          the outputs.
193 *          The operation is defined as:
194 *          \f[
195 *              \text { out }=\frac{x-\mathrm{E}[x]}{\sqrt{\text{Var}[x]+eps}}
196 *          \f]
197 *          `Var` defaults dst->ne[0]. `eps` is in dst->params.
198 *
199 * @param ctx The CANN context used for operations.
200 * @param dst The destination tensor where the normalized values will be stored.
201 * @attention `Var` defaults to dst->ne[0].
202 */
203void ggml_cann_norm(ggml_backend_cann_context & ctx, ggml_tensor * dst);
204
205/**
206 * @brief   Computes the L2 Normalization for a ggml tensor using the CANN
207 *          backend.
208 *
209 * @details This function applies the L2 Normalization operation on the
210 *          input tensor `src` and stores the result in the destination tensor
211 *          `dst`. L2 Normalization scales the input tensor such that the
212 *          L2 norm along the specified dimension equals 1. This operation
213 *          is commonly used in neural networks for feature normalization
214 *          and vector scaling.
215 *          The operation is defined as:
216 *          \f[
217 *              \text{out} = \frac{x}{\sqrt{\sum{x^2}}}
218 *          \f]
219 *          The normalization is performed along the last dimension by default.
220 *
221 * @param ctx The CANN context used for operations.
222 * @param dst The destination tensor where the normalized values will be stored.
223 * @attention The normalization is performed along the last dimension of the
224 *            input tensor by default.
225 */
226void ggml_cann_l2_norm(ggml_backend_cann_context & ctx, ggml_tensor * dst);
227
228/**
229 * @brief   Computes the Cross Entropy Loss for a ggml tensor using the CANN
230 *          backend.
231 *
232 * @details This function computes the cross entropy loss between the predicted
233 *          logits and target probability distributions. The operation follows
234 *          the same computation pattern as the CPU implementation:
235 *          1. Applies log_softmax to the logits along the class dimension
236 *          2. Element-wise multiplication with target distributions
237 *          3. Summation along the class dimension to get per-sample losses
238 *          4. Global summation and scaling by -1/nr to get final loss
239 *
240 *          The computation can be expressed as:
241 *          \f[
242 *              \text{loss} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{C} y_{ij} \cdot \log(\text{softmax}(x_{ij}))
243 *          \f]
244 *          where \f$N\f$ is the total number of samples, \f$C\f$ is the number
245 *          of classes, \f$x\f$ are the logits, and \f$y\f$ are the target
246 *          probability distributions.
247 *
248 * @param ctx The CANN context used for operations.
249 * @param dst The destination tensor where the computed loss will be stored.
250 *            This should be a scalar tensor containing the final loss value.
251 *
252 * @note This implementation computes cross entropy between probability
253 *       distributions, not the typical classification cross entropy that
254 *       expects class indices as targets. Both input tensors (src0 and src1)
255 *       should have the same shape and represent probability distributions
256 *       over the class dimension.
257 * @note The function expects two source tensors:
258 *       - dst->src[0]: Logits tensor (before softmax)
259 *       - dst->src[1]: Target probability distributions tensor
260 * @note The computation is performed using CANN backend operators including
261 *       LogSoftmax, Mul, ReduceSum, and Muls for the final scaling.
262 */
263void ggml_cann_cross_entropy_loss(ggml_backend_cann_context & ctx, ggml_tensor * dst);
264
265/**
266 * @brief  Computes the Group Normalization for a ggml tensor using the CANN
267 *         backend.
268 *
269 * @brief  This function applies the Group Normalization operation on the input
270 *         tensor `src` and stores the result in the destination tensor `dst`.
271 *         Group Normalization divides the channels into groups and normalizes
272 *         the features within each group across spatial locations.
273 *         It is commonly used in convolutional neural networks to improve
274 *         training stability and performance.
275 *         The operation is defined as:
276 *         \f[
277 *             \text { out }=\frac{x-\mathrm{E}[x]}{\sqrt{\text{Var}[x]+eps}}
278 *         \f]
279 *
280 * @param ctx The CANN context used for operations.
281 * @param dst The destination tensor where the normalized values will be stored.
282 *            `n_groups` is in dst->params, which split C channel to `n_groups`.
283 *            dst->op is `GGML_OP_GROUP_NORM`.
284 *
285 * @attention eps defaults to 1e-6f.
286 */
287void ggml_cann_group_norm(ggml_backend_cann_context & ctx, ggml_tensor * dst);
288
289/**
290 * @brief   Computes the accumulation of tensors using the CANN backend.
291 *
292 * @details This function performs an accumulation operation on two tensors.
293 *          Depending on the `inplace` flag, it either updates the destination
294 *          tensor `dst` in place by adding `alpha * src1` to it, or it creates
295 *          a new tensor as the result of `src0 + alpha * src1` and stores it in
296 *          `dst`.
297 *          The operation is defined as:
298 *          \f[
299 *               dst = src0 + alpha \times src1
300 *          \f]
301 *          if `inplace` is `true`, `src0` is equal to 'dst'.
302 * @param ctx The CANN context used for operations.
303 * @param dst The destination tensor where the accumulated values will be stored.
304 *            `inplace` is in dst->params, and dst->op is `GGML_OP_ACC`.
305 */
306void ggml_cann_acc(ggml_backend_cann_context & ctx, ggml_tensor * dst);
307
308/**
309 * @brief   Computes the sum of elements along the last dimension of a ggml tensor
310 *          using the CANN backend.
311 *
312 * @details This function performs a reduction sum operation along the last
313 *          dimension of the input tensor `src`. The result of the sum is stored
314 *          in the destination tensor `dst`.
315 *
316 * @param ctx The CANN context used for operations.
317 * @param dst The destination tensor where the reduced values will be stored。
318 *            dst->op is `GGML_OP_SUM_ROWS`.
319 *
320 * @attention `reduce_dims` defaults to 3, which means the last dimension.
321 */
322void ggml_cann_sum_rows(ggml_backend_cann_context & ctx, ggml_tensor * dst);
323
324/**
325 * @brief   Computes the sum of elements in a ggml tensor.
326 *
327 * @details This function performs a reduction sum operation along the last
328 *          dimension of the input tensor `src`. The result of the sum is stored
329 *          in the destination tensor `dst`.
330 *
331 * @param ctx The CANN context used for operations.
332 * @param dst The destination tensor where the reduced values will be stored。
333 *
334 */
335
336void ggml_cann_sum(ggml_backend_cann_context & ctx, ggml_tensor * dst);
337
338/**
339 * @brief   Computes the cumulative sum of a ggml tensor along dim 0 using the
340 *          CANN backend.
341 *
342 * @param ctx The CANN context used for operations.
343 * @param dst The destination tensor. dst->op is `GGML_OP_CUMSUM`.
344 */
345void ggml_cann_cumsum(ggml_backend_cann_context & ctx, ggml_tensor * dst);
346
347/**
348 * @brief   Computes a triangular mask (tril/triu) of a square ggml tensor
349 *          using the CANN backend.
350 *
351 * @param ctx The CANN context used for operations.
352 * @param dst The destination tensor. dst->op is `GGML_OP_TRI`.
353 */
354void ggml_cann_tri(ggml_backend_cann_context & ctx, ggml_tensor * dst);
355
356/**
357 * @brief   Solves a triangular linear system AX=B using the CANN backend.
358 *
359 * @param ctx The CANN context used for operations.
360 * @param dst The destination tensor. dst->op is `GGML_OP_SOLVE_TRI`.
361 */
362void ggml_cann_solve_tri(ggml_backend_cann_context & ctx, ggml_tensor * dst);
363
364/**
365 * @brief   Creates a diagonal matrix from a vector using the CANN backend.
366 *
367 * @param ctx The CANN context used for operations.
368 * @param dst The destination tensor. dst->op is `GGML_OP_DIAG`.
369 */
370void ggml_cann_diag(ggml_backend_cann_context & ctx, ggml_tensor * dst);
371
372/**
373 * @brief   Fills a tensor with a constant scalar value using the CANN backend.
374 *
375 * @param ctx The CANN context used for operations.
376 * @param dst The destination tensor. dst->op is `GGML_OP_FILL`.
377 */
378void ggml_cann_fill(ggml_backend_cann_context & ctx, ggml_tensor * dst);
379
380/**
381 * @brief   Upsamples a ggml tensor using nearest neighbor interpolation using
382 *          the CANN backend.
383 *
384 * @details This function performs upsampling of the input tensor `src` using
385 *          nearest neighbor interpolation. The upsampling is applied to the
386 *          height and width dimensions (last two dimensions) of the tensor. The
387 *          result is stored in the destination tensor `dst`, which must have
388 *          the appropriate dimensions for the upsampled output.
389 *
390 * @param ctx The CANN context used for operations.
391 * @param dst The destination tensor where the upsampled values will be stored.
392 *            dst->op is `GGML_OP_UPSCALE`.
393 */
394void ggml_cann_upsample_nearest2d(ggml_backend_cann_context & ctx, ggml_tensor * dst);
395
396/**
397 * @brief   Pads a ggml tensor to match the dimensions of the destination tensor
398 *          using the CANN backend.
399 *
400 * @details This function pads the input tensor `src` so that it matches the
401 *          dimensions of the destination tensor `dst`. The amount of padding
402 *          is calculated based on the difference in sizes between `src` and
403 *          `dst` along each dimension. The padded tensor is stored in `dst`.
404 *
405 * @param ctx The CANN context used for operations.
406 * @param dst The destination tensor, which specifies the target dimensions for
407 *            padding. dst->op is `GGML_OP_PAD`.
408 */
409void ggml_cann_pad(ggml_backend_cann_context & ctx, ggml_tensor * dst);
410
411/**
412 * @brief   Executes a 2D pooling operation on a ggml tensor using the CANN
413 *          backend.
414 *
415 * @details This function dispatches the execution of a 2D pooling operation on
416 *          the input tensor `dst`. The type of pooling (average or max) is
417 *          determined by the `op` parameter, which is read from the operation
418 *          parameters of `dst`. The function supports average pooling
419 *          (`GGML_OP_POOL_AVG`) and max pooling (`GGML_OP_POOL_MAX`). If an
420 *          invalid operation is encountered, the function asserts a failure.
421 *
422 * @param ctx The CANN context used for operations.
423 * @param dst The destination tensor on which the pooling operation is to be
424 *            performed. dst->op is `GGML_OP_POOL_2D`.
425 */
426void ggml_cann_pool2d(ggml_backend_cann_context & ctx, ggml_tensor * dst);
427
428/**
429 * @brief   Duplicates a ggml tensor using the CANN backend.
430 *
431 * @details This function duplicates the contents of the source tensor `src` to
432 *          the destination tensor `dst`. The function supports various tensor
433 *          types and configurations, including handling of extra data, type
434 *          conversions, and special cases for contiguous and non-contiguous
435 *          tensors.
436 *
437 * @param ctx The CANN context used for operations.
438 * @param dst The destination tensor where the duplicated data will be stored.
439 *            dst->op is `GGML_OP_DUP`
440 *
441 * @attention Only support Fp16/FP32. Not support when src and dst have
442 *            different shape and dst is no-contiguous.
443 * @note:     This func need to simplify.
444 */
445void ggml_cann_dup(ggml_backend_cann_context & ctx, ggml_tensor * dst);
446
447/**
448 * @brief   Computes the Root Mean Square (RMS) normalization of a ggml tensor
449 *          using the CANN backend.
450 *
451 * @details This function applies RMS normalization to the input tensor `src`
452 *          and stores the result in the destination tensor `dst`. RMS
453 *          normalization involves computing the root mean square of the input
454 *          tensor along a specified dimension and then dividing each element of
455 *          the tensor by this value, adjusted by a small epsilon value to
456 *          prevent division by zero.
457 *          The operation is defined as:
458 *          \f[
459 *               \text{RmsNorm}\left(x_i\right)=\frac{x_i}{\text{Rms}(\mathbf{x})} g_i,
460 *               \quad \text { where } \text{Rms}(\mathbf{x})=\sqrt{\frac{1}{n} \sum_{i=1}^n x_i^2+e p s}
461 *          \f]
462 *          `eps` is in dst->op_params.
463 * @param ctx The CANN context used for operations.
464 * @param dst The destination tensor where the normalized values will be stored.
465 *            dst->op is `GGML_OP_RMS_NORM`.
466 */
467void ggml_cann_rms_norm(ggml_backend_cann_context & ctx, ggml_tensor * dst);
468
469/**
470 * @brief   Applies a diagonal mask to the tensor with a specified value.
471 *
472 * @details This function creates a mask tensor filled with ones, then applies
473 *          an upper triangular and lower triangular operation to it based on
474 *          the number of past elements specified. Afterward, it adds the masked
475 *          tensor to the destination tensor in-place.
476 *
477 * @param ctx The backend CANN context used for operations.
478 * @param dst The destination tensor where the result will be stored. dst->op is
479 *            `GGML_OP_DIAG_MASK`
480 * @param value The value to use for masking.
481 */
482void ggml_cann_diag_mask(ggml_backend_cann_context & ctx, ggml_tensor * dst, float value);
483
484/**
485 * @brief   Performs an image-to-column transformation on the input tensor.
486 *
487 * @details This function takes an input tensor and applies an image-to-column
488 *          operation, converting spatial dimensions into column-like
489 *          structures suitable for convolutional operations. It supports both
490 *          half-precision (F16) and single-precision (F32) floating-point data
491 *          types.
492 *
493 * @param ctx The backend CANN context for executing operations.
494 * @param dst The destination tensor that stores the result of the operation.
495 *            dst->op is `GGML_OP_IM2COL`.
496 */
497void ggml_cann_im2col(ggml_backend_cann_context & ctx, ggml_tensor * dst);
498
499/**
500 * @brief   Computes time step embeddings using sine and cosine functions.
501 *
502 * @details This function calculates time step embeddings by applying sine and
503 *          cosine transformations to a given input tensor, which is typically
504 *          used in temporal models like diffusion models or transformers to
505 *          encode time information effectively.
506 *
507 * @param ctx The backend CANN context for executing operations.
508 * @param dst The destination tensor where the result of the embedding operation
509 *            will be stored. dst->op is `GGML_OP_TIMESTEP_EMBEDDING`.
510 */
511void ggml_cann_timestep_embedding(ggml_backend_cann_context & ctx, ggml_tensor * dst);
512
513// @see ggml_cann_dup.
514void ggml_cann_cpy(ggml_backend_cann_context & ctx, ggml_tensor * dst);
515
516// @see ggml_cann_acc, but copies src1 into dst instead of adding.
517void ggml_cann_set(ggml_backend_cann_context & ctx, ggml_tensor * dst);
518
519/**
520 * @brief   Computes the softmax activation with optional masking.
521 *
522 * @details This function computes the softmax activation over the input tensor,
523 *          optionally applying a mask and scaling factor. It supports both FP16
524 *          and FP32 data types and can handle masking by broadcasting the mask
525 *          across rows if necessary.
526 *          The function performs the following steps:
527 *          1. Multiplies the input tensor by a scale factor.
528 *          2. Optionally casts the mask tensor to FP32 if it is in FP16 format.
529 *          3. Broadcasts the mask tensor if its dimensions do not match the
530 *             input tensor's dimensions.
531 *          4. Adds the mask to the scaled input tensor.
532 *          5. Applies the softmax activation function along the specified
533 *             dimension.
534 *
535 * @param ctx The backend CANN context for executing operations.
536 * @param dst The destination tensor where the result will be stored. dst->op is
537 *            `GGML_OP_SOFTMAX`.
538 */
539void ggml_cann_softmax(ggml_backend_cann_context & ctx, ggml_tensor * dst);
540
541/**
542 * @brief   Extracts specific rows from a tensor based on indices.
543 *
544 * @details This function retrieves rows from a source tensor src0 according to
545 *          the indices provided in another tensor src1 and stores the result in
546 *          a destination tensor (\p dst).
547 *
548 * @param ctx The backend CANN context for executing operations.
549 * @param dst The destination tensor where the extracted rows will be stored.
550 */
551void ggml_cann_get_rows(ggml_backend_cann_context & ctx, ggml_tensor * dst);
552
553/**
554 * @brief   Writes specific rows into a tensor at positions specified by indices.
555 *
556 * @details This function copies rows from a source tensor into a destination
557 *          tensor (\p dst) at the positions indicated by the indices in another
558 *          tensor.
559 *
560 * @param ctx The backend CANN context for executing operations.
561 * @param dst The destination tensor where the specified rows will be updated.
562 */
563void ggml_cann_set_rows(ggml_backend_cann_context & ctx, ggml_tensor * dst);
564
565/**
566 * @brief   Executes matrix multiplication for the given tensor.
567 *
568 * @details This function performs matrix multiplication on the source tensors
569 *          associated with the destination tensor. It supports matrix
570 *          multiplication F32, F16, and Q8_0.
571 *
572 * @param ctx The backend CANN context for executing operations.
573 * @param dst The destination tensor for storing the result of the matrix
574 *            multiplication. dst->op is `GGML_OP_MUL_MAT`.
575 */
576void ggml_cann_mul_mat(ggml_backend_cann_context & ctx, ggml_tensor * dst);
577
578/**
579 * @brief Applies Rotary Positional Embedding (RoPE) to the input tensor.
580 *
581 * @details This function implements the RoPE mechanism, which is a method to
582 *          encode positional information into sequence data, particularly
583 *          useful in transformer models. It supports both F32 and F16 data
584 *          types.
585 *
586 * @param ctx The backend CANN context for executing operations.
587 * @param dst The destination tensor where the RoPE-transformed data will be
588 *            stored. dst->op is `GGML_OP_ROPE`.
589 *
590 * @note The function currently does not support cases where the n_dims is less
591 *       than the input tensor's first dimension.
592 * @note The function currently does not support cases where the freq_factors is
593 *       not NULL.
594 * @note The function currently does not support cases where the ext_factor is
595 *       not equal 0.
596 * @note The function currently does not support cases where the freq_scale is
597 *       not equal 1.
598 */
599void ggml_cann_rope(ggml_backend_cann_context & ctx, ggml_tensor * dst);
600
601/**
602 * @brief Pre-load the RoPE cache before ACL graph capture.
603 *
604 * This function must be called outside of graph capture to perform
605 * host-to-device memory copies and device memory allocations that are
606 * not allowed on a captured stream.  After pre-loading, the rope cache
607 * metadata is updated so that the subsequent call to
608 * aclnn_rope_cache_init (inside graph capture) skips these operations
609 * and only records the on-device computations into the captured graph.
610 *
611 * @param ctx  CANN backend context.
612 * @param dst  A ROPE destination tensor from the computation graph.
613 */
614void ggml_cann_rope_cache_preload(ggml_backend_cann_context & ctx, ggml_tensor * dst);
615
616/**
617 * @brief   Computes the index of the maximum value along the specified dimension
618 *          of a ggml tensor using the CANN backend.
619 *
620 * @details This function performs an argmax operation on the input tensor.
621 *          It finds the index of the maximum value along the specified axis
622 *          and stores these indices in the destination tensor `dst`. The
623 *          operation is executed using the CANN backend for optimized performance.
624 *
625 * @param ctx The CANN context used for operations.
626 * @param dst The destination tensor where the indices of the maximum values will
627 *            be stored. dst->op is `GGML_OP_ARGMAX`.
628 */
629void ggml_cann_argmax(ggml_backend_cann_context & ctx, ggml_tensor * dst);
630
631/**
632 * @brief Adds two tensors element-wise and stores the result in a destination
633 * tensor.
634 *
635 * This function performs the operation:
636 * \f[
637 *    dst = acl\_src0 + alpha \times acl\_src1
638 * \f]
639 * where alpha is a scalar value and defaults to 1.0f.
640 *
641 * @param ctx The context for the CANN backend operations.
642 * @param acl_src0 The first source tensor.
643 * @param acl_src1 The second source tensor.
644 * @param acl_dst The destination tensor where the result will be stored.
645 */
646void aclnn_add(ggml_backend_cann_context & ctx,
647               aclTensor *                 acl_src0,
648               aclTensor *                 acl_src1,
649               aclTensor *                 acl_dst = nullptr);
650
651/**
652 * @brief Sub two tensors element-wise and stores the result in a destination
653 * tensor.
654 *
655 * This function performs the operation:
656 * \f[
657 *    dst = acl\_src0 - alpha \times acl\_src1
658 * \f]
659 * where alpha is a scalar value and defaults to 1.0f.
660 *
661 * @param ctx The context for the CANN backend operations.
662 * @param acl_src0 The first source tensor.
663 * @param acl_src1 The second source tensor.
664 * @param acl_dst The destination tensor where the result will be stored.
665 */
666void aclnn_sub(ggml_backend_cann_context & ctx,
667               aclTensor *                 acl_src0,
668               aclTensor *                 acl_src1,
669               aclTensor *                 acl_dst = nullptr);
670
671/**
672 * @brief Performs element-wise multiplication of two tensors and stores the
673 * result in a destination tensor.
674 *
675 * This function performs element-wise multiplication of the tensors `acl_src`
676 * and `acl_other` and stores the result in the destination tensor `acl_dst`.
677 * The operation is defined as:
678 * \f[
679 *     \text {acl_dst }_i=\text {acl_src }_i \times \text {acl_other }_i
680 * \f]
681 *
682 * @param ctx The context for the CANN backend operations.
683 * @param acl_src The first tensor for element-wise multiplication.
684 * @param acl_other The second tensor for element-wise multiplication.
685 * @param acl_dst The destination tensor where the result will be stored.
686 */
687void aclnn_mul(ggml_backend_cann_context & ctx,
688               aclTensor *                 acl_src,
689               aclTensor *                 acl_other,
690               aclTensor *                 acl_dst = nullptr);
691
692/**
693 * @brief Matrix division, optionally in-place.
694 *
695 * This function division each element of the source tensor `acl_src` by the
696 * tensor `acl_other` and stores the result in the destination tensor `acl_dst`.
697 * If `inplace` is true, `acl_dst` will not be used and the operation is
698 * performed in-place on `acl_src`. The operation is defined as: \f[
699 *     \text{dst}_i = \frac{\text{acl_src}_i}{\text{acl_other}_i}
700 * \f]
701 *
702 * @param ctx The context for the CANN backend operations.
703 * @param acl_src Numerator tensor..
704 * @param acl_other Denominator tensor.
705 * @param acl_dst The destination tensor where the result will be stored if
706 * `inplace` is false.
707 * @param inplace Flag indicating whether to perform the operation in-place on
708 * `acl_src`.
709 */
710void aclnn_div(ggml_backend_cann_context & ctx,
711               aclTensor *                 acl_src,
712               aclTensor *                 acl_other,
713               aclTensor *                 acl_dst = nullptr);
714
715/**
716 * @brief Applies element-wise cosine function to the elements of a tensor.
717 *
718 * This function computes the cosine of each element in the source tensor
719 * `acl_src` and stores the result in the destination tensor `acl_dst`. The
720 * operation is defined as: \f[ \text {acl_dst }_i=\cos \left(\text {acl_src
721 * }_i\right) \f]
722 *
723 * @param ctx The context for the CANN backend operations.
724 * @param acl_src The source tensor on which the cosine function will be
725 * applied.
726 * @param acl_dst The destination tensor where the cosine results will be
727 * stored.
728 */
729void aclnn_cos(ggml_backend_cann_context & ctx, aclTensor * acl_src, aclTensor * acl_dst);
730
731/**
732 * @brief Applies element-wise sine function to the elements of a tensor.
733 *
734 * This function computes the sine of each element in the source tensor
735 `acl_src`
736 * and stores the result in the destination tensor `acl_dst`.
737 * The operation is defined as:
738 * \f[
739 *     \text {acl_dst }_i=\sin \left(\text {acl_src }_i\right)
740 * \f]
741
742 * @param ctx The context for the CANN backend operations.
743 * @param acl_src The source tensor on which the sine function will be applied.
744 * @param acl_dst The destination tensor where the sine results will be stored.
745 */
746void aclnn_sin(ggml_backend_cann_context & ctx, aclTensor * acl_src, aclTensor * acl_dst);
747
748/**
749 * @brief Prepares broadcast-compatible ACL tensors for two input tensors and one
750 * output tensor.
751 *
752 * This function checks whether broadcasting is needed between `src0` and `src1`.
753 * If broadcasting is required, it calculates the proper shapes and creates
754 * ACL tensors with broadcast parameters. Otherwise, it directly creates ACL tensors
755 * based on the original tensor shapes.
756 *
757 * @param src0     The first input tensor (reference shape).
758 * @param src1     The second input tensor (possibly broadcasted).
759 * @param dst      The destination/output tensor.
760 * @param acl_src0 Output pointer to the created ACL tensor corresponding to src0.
761 * @param acl_src1 Output pointer to the created ACL tensor corresponding to src1.
762 * @param acl_dst  Output pointer to the created ACL tensor corresponding to dst.
763 */
764void bcast_shape(ggml_tensor *    src0,
765                 ggml_tensor *    src1,
766                 ggml_tensor *    dst,
767                 acl_tensor_ptr & acl_src0,
768                 acl_tensor_ptr & acl_src1,
769                 acl_tensor_ptr & acl_dst);
770
771/**
772 * @brief   Computes the 1D transposed convolution (deconvolution) of a ggml
773 * tensor using the CANN backend.
774 *
775 * @details This function performs a 1D transposed convolution (also known as
776 * deconvolution) operation on the input tensor. The computed result is stored
777 * in the destination tensor `dst`. The operation is optimized using the CANN
778 * backend for improved performance.
779 *
780 * @param ctx The CANN context used for operations.
781 * @param dst The destination tensor where the transposed convolution result
782 * will be stored. dst->op is `GGML_OP_CONV_TRANSPOSE_1D`.
783 */
784void ggml_cann_conv_transpose_1d(ggml_backend_cann_context & ctx, ggml_tensor * dst);
785
786/**
787 * @brief   Applies the ELU (Exponential Linear Unit) activation to a ggml tensor
788 * using the CANN backend.
789 *
790 * @details This function performs an element-wise ELU activation on the input
791 *          tensor.
792 *          The result is written to the destination tensor `dst` in-place.
793 *          The ELU function is defined as:
794 *
795 *          \text{ELU}(x) =
796 *          \begin{cases}
797 *          x, & \text{if } x > 0 \\
798 *          \alpha \left( \exp(x) - 1 \right), & \text{if } x \leq 0
799 *          \end{cases}
800 *
801 *          where α (alpha) is a hyperparameter, typically set to 1.0.
802 *          This operation is optimized using the CANN backend for high-performance
803 *          inference or training.
804 *
805 * @param ctx The CANN context used for operations.
806 * @param dst The destination tensor where the ELU-activated result will be stored.
807 *            dst->op is expected to be `GGML_OP_ELU`.
808 */
809void ggml_cann_elu(ggml_backend_cann_context & ctx, ggml_tensor * dst);
810
811/**
812 * @brief   Computes the mean of a ggml tensor element-wise using the CANN backend.
813 *
814 * @details This function calculates the element-wise mean of the input tensor.
815 *          The result is written to the destination tensor `dst`.
816 *          The mean is computed by averaging the values across the entire tensor.
817 *
818 *          This operation is optimized using the CANN backend for high-performance inference or training.
819 *
820 * @param ctx The CANN context used for operations.
821 * @param dst The destination tensor where the mean result will be stored.
822 *            dst->op is expected to be `GGML_OP_MEAN`.
823 */
824void ggml_cann_mean(ggml_backend_cann_context & ctx, ggml_tensor * dst);
825
826/**
827 * @brief   Applies 1D reflect padding to a ggml tensor using the CANN backend.
828 *
829 * @details This function performs 1D reflect padding on the input tensor.
830 *          The amount of padding on each side is specified by parameters stored in `dst->op_params`.
831 *          The operation reflects the values at the borders of the tensor to generate the padded output.
832 *
833 *          This operation is optimized using the CANN backend for high-performance inference or training.
834 *
835 * @param ctx The CANN context used for operations.
836 * @param dst The destination tensor where the padded result will be stored.
837 *            dst->op is expected to be `GGML_OP_PAD_REFLECT_1D`.
838 */
839void ggml_cann_pad_reflect_1d(ggml_backend_cann_context & ctx, ggml_tensor * dst);
840
841/**
842 * @brief   Counts the number of equal elements in two ggml tensors using the CANN backend.
843 *
844 * @details This function performs an element-wise comparison between two input tensors,
845 *          and counts the number of positions where the elements are equal. The result is
846 *          stored in the destination tensor `dst` as a scalar.
847 *
848 *          The operation is optimized using the CANN backend, making it suitable for
849 *          high-performance inference or training scenarios.
850 *
851 * @param ctx The CANN context used for operations.
852 * @param dst The destination tensor where the result will be stored.
853 *            dst->op is expected to be `GGML_OP_COUNT_EQUAL`.
854 */
855void ggml_cann_count_equal(ggml_backend_cann_context & ctx, ggml_tensor * dst);
856
857/**
858 * @brief   Applies the Step activation function to a ggml tensor using the CANN backend.
859 *
860 * @details This function applies a step function element-wise to the input tensor, where
861 *          each element is transformed to 1.0 if it is greater than 0, and 0.0 otherwise.
862 *          The result is stored in the destination tensor `dst`.
863 *
864 *          This operation is accelerated using the CANN backend to improve runtime performance.
865 *
866 * @param ctx The CANN context used for operations.
867 * @param dst The destination tensor where the result will be stored.
868 *            dst->op is expected to be `GGML_OP_STEP`.
869 */
870void ggml_cann_step(ggml_backend_cann_context & ctx, ggml_tensor * dst);
871void ggml_cann_softplus(ggml_backend_cann_context & ctx, ggml_tensor * dst);
872void ggml_cann_geglu_quick(ggml_backend_cann_context & ctx, ggml_tensor * dst);
873
874/**
875 * @brief   Performs the Flash Attention extended operator using the CANN backend.
876 *
877 * @details This function implements the memory-efficient Flash Attention algorithm
878 *          for computing scaled dot-product attention with hardware acceleration.
879 *          The result is stored in the destination tensor `dst`.
880 *
881 *          This operation is accelerated using the CANN backend to improve runtime performance.
882 *
883 * @param ctx The CANN context used for operations.
884 * @param dst The destination tensor where the result will be stored.
885 *            dst->op is expected to be `GGML_OP_FLASH_ATTN_EXT`.
886 */
887void ggml_cann_flash_attn_ext(ggml_backend_cann_context & ctx, ggml_tensor * dst);
888
889/**
890 * @brief Forward Gated Linear Attention on the CANN backend.
891 *
892 * Expects dst->src[0..4] = {k, v, q, g, s} with shape conventions:
893 *   k, v, q, g: [D] with outer dims T x H batched as ne[2]=T, ne[1]=H
894 *   s: initial state [B, H, D, D], where B is batch and D=C/H
895 * dst holds both outputs (o) and updated state; a scale factor is read from op params.
896 *
897 * The kernel updates per time step l: S_new = g ⊗ S_old + k ⊗ v, then computes o = (S_new^T q) * scale.
898 *
899 * @param ctx Backend context providing stream/allocator utilities.
900 * @param dst Output tensor; src deps are k, v, q, g, s as above.
901 */
902void ggml_cann_gated_linear_attn(ggml_backend_cann_context & ctx, ggml_tensor * dst);
903
904/**
905 * @brief Launches an asynchronous task using the memory allocator.
906 *
907 * This macro submit an asynchronous task on the specified stream.
908 * The task uses memory allocated by the allocator. It is guaranteed
909 * that the memory will not be accessed by other tasks until this task
910 * completes, due to the sequential execution order within the same stream.
911 *
912 * @param OP_NAME aclnn operator name.
913 * @param args Additional arguments required by the task.
914 *
915 * @note
916 * Memory from the allocator will be "freed" immediately and can be
917 * reallocated to other pointers. However, it won't be accessed by any
918 * other task before this asynchronous task ends, because all tasks in the
919 * same stream are executed in queue order.
920 */
921
922#    define GGML_CANN_CALL_ACLNN_OP(CTX, OP_NAME, ...)                                           \
923        do {                                                                                     \
924            uint64_t        workspaceSize = 0;                                                   \
925            aclOpExecutor * executor;                                                            \
926            void *          workspaceAddr = nullptr;                                             \
927            ACL_CHECK(aclnn##OP_NAME##GetWorkspaceSize(__VA_ARGS__, &workspaceSize, &executor)); \
928            /* workspace should alloced in main thread to keep malloc order when using vmm. */   \
929            if (workspaceSize > 0) {                                                             \
930                ggml_cann_pool_alloc workspace_allocator(CTX.pool(), workspaceSize);             \
931                workspaceAddr = workspace_allocator.get();                                       \
932            }                                                                                    \
933            ACL_CHECK(aclnn##OP_NAME(workspaceAddr, workspaceSize, executor, CTX.stream()));     \
934        } while (0)
935
936/**
937 * @brief   Performs sparse expert-based matrix multiplication using the CANN backend.
938 *
939 * @details This function implements a MoE-style batched matrix multiplication, where each input token
940 *          is routed to one or more experts, and each expert corresponds to a specific [D, M] weight matrix
941 *          in the source tensor `src0`. The routing indices are provided via the `ids` tensor.
942 *
943 *          For each token (from `src1`), the function selects the corresponding expert(s) as specified by `ids`,
944 *          performs the matrix multiplication with the selected expert's weight submatrix (from `src0`),
945 *          and stores the results in `dst`. This operation is optimized and executed on the CANN backend.
946 *
947 *          Dimensions:
948 *              - src0: [D, M, A, 1], where A is the number of experts
949 *              - src1: [D, B, N, 1], where N is batch size and B is the slot count per sample
950 *              - ids : [K, N],       where K is the number of experts each token is routed to
951 *              - dst : [M, K, N, 1], output tensor storing the result of expert × token multiplication
952 *
953 *          The function handles two main modes:
954 *              - If `ne12 == 1`, a simpler per-token loop is used.
955 *              - TODO: If `ne12 > 1`, grouped multiplication and memory copying is used for efficiency.
956 *
957 * @param ctx The CANN context used for operations.
958 * @param dst The destination tensor where the expert-weighted token outputs are stored.
959 *            Expected to be of shape [M, K, N, 1].
960 */
961void ggml_cann_mul_mat_id(ggml_backend_cann_context & ctx, ggml_tensor * dst);
962
963/**
964 * @brief Performs fused ADD + RMS_NORM operation using the CANN backend.
965 *
966 * This function fuses the ADD and RMS_NORM operations into a single kernel call
967 * for better performance. It first adds two input tensors (x1 + x2), then applies
968 * RMS normalization to the result.
969 *
970 * @param ctx The context for the CANN backend operations.
971 * @param dst The ADD operation node, contains the two input tensors to be added.
972 * @param rms_norm_tensor The RMS_NORM operation node, contains the gamma weights
973 *                        and epsilon parameter.
974 */
975void ggml_cann_op_add_rms_norm_fused(ggml_backend_cann_context & ctx,
976                                     ggml_tensor *               add_node,
977                                     ggml_tensor *               rms_norm_node);
978
979/**
980 * @brief   Check whether a tensor is a weight tensor for matrix multiplication.
981 *
982 * @details Checks whether the given tensor serves as weight parameters in matrix multiplication operations,
983 *          typically within neural network layers. The function maintains a static set of canonical weight
984 *          naming suffixes from Transformer-based architectures. Uses substring matching to identify weight
985 *          tensors even with hierarchical naming patterns.
986 *
987 * @param tensor Pointer to the target ggml_tensor object (const-qualified).
988 */
989static bool is_matmul_weight(const ggml_tensor * tensor) {
990    std::string                                  name = ggml_get_name(tensor);
991    static const std::unordered_set<std::string> weight_suffixes{ "output.weight",      "attn_q.weight",
992                                                                  "attn_k.weight",      "attn_v.weight",
993                                                                  "attn_output.weight", "ffn_gate.weight",
994                                                                  "ffn_up.weight",      "ffn_down.weight" };
995
996    for (const auto & suffix : weight_suffixes) {
997        if (name.find(suffix) != std::string::npos) {
998            return true;
999        }
1000    }
1001    return false;
1002}
1003
1004/**
1005 * @brief Applies a element-wise operation to two input tensors using the CANN
1006 * backend.
1007 *
1008 * This templated function takes a binary operator and applies it to two source
1009 * tensors
1010 * associated with the destination tensor. The function handles broadcasting as
1011 * needed.
1012 *
1013 * @tparam binary_op A callable object (e.g., lambda or function pointer) representing
1014 *         the binary operation to be performed. It must take three arguments:
1015 *         (ggml_backend_cann_context&, aclTensor*, aclTensor*, aclTensor*).
1016 *
1017 * @param ctx The CANN backend context used to manage execution and resources.
1018 * @param dst The destination tensor.
1019 */
1020template <auto binary_op> void ggml_cann_binary_op(ggml_backend_cann_context & ctx, ggml_tensor * dst) {
1021    ggml_tensor * src0 = dst->src[0];
1022    ggml_tensor * src1 = dst->src[1];
1023
1024    acl_tensor_ptr acl_src0, acl_src1, acl_dst;
1025
1026    // Need bcast
1027    bcast_shape(src0, src1, dst, acl_src0, acl_src1, acl_dst);
1028    binary_op(ctx, acl_src0.get(), acl_src1.get(), acl_dst.get());
1029}
1030
1031/**
1032 * @brief Applies a unary operation to an input tensor using the CANN backend.
1033 *
1034 * This templated function applies a unary operator to the source tensor of `dst`
1035 * and stores the result in the destination tensor.
1036 *
1037 * @tparam unary_op A callable with the signature:
1038 *         void(ggml_backend_cann_context&, aclTensor *, aclTensor *)
1039 *         where the first aclTensor is the source and the second is the destination.
1040 * @param ctx The CANN backend context for managing resources and execution.
1041 * @param dst The destination tensor. Its src[0] is treated as the input tensor.
1042 */
1043template <void unary_op(ggml_backend_cann_context &, aclTensor *, aclTensor *)>
1044void ggml_cann_op_unary(ggml_backend_cann_context & ctx, ggml_tensor * dst) {
1045    ggml_tensor * src = dst->src[0];
1046
1047    acl_tensor_ptr acl_src = ggml_cann_create_tensor(src);
1048    acl_tensor_ptr acl_dst = ggml_cann_create_tensor(dst);
1049
1050    unary_op(ctx, acl_src.get(), acl_dst.get());
1051}
1052
1053/**
1054 * @brief Applies a unary operation to a ggml tensor using the CANN backend.
1055 *
1056 * @details This function applies a unary operation to the input tensor using
1057 * a user-provided lambda or callable `unary_op`. The lambda receives the
1058 * CANN backend context and two ACL tensors: the source and the destination.
1059 *
1060 * Internally, this function handles the conversion from GGML tensors to ACL tensors,
1061 * calls the provided unary op, and manages resource cleanup. The input is assumed
1062 * to be `dst->src[0]`, and the result is written to `dst`.
1063 *
1064 * This utility simplifies writing unary op wrappers by abstracting tensor preparation.
1065 *
1066 * @param unary_op A callable that performs the unary operation using CANN ACL APIs.
1067 * @param ctx The CANN context for operation execution.
1068 * @param dst The destination ggml_tensor where the result will be stored.
1069 *            The input tensor is assumed to be `dst->src[0]`.
1070 *
1071 * @see GGML_CANN_CALL_OP_UNARY
1072 */
1073void ggml_cann_op_unary(std::function<void(ggml_backend_cann_context &, aclTensor *, aclTensor *)> unary_op,
1074                        ggml_backend_cann_context &                                                ctx,
1075                        ggml_tensor *                                                              dst);
1076
1077void ggml_cann_ssm_conv(ggml_backend_cann_context & ctx, ggml_tensor * dst);
1078
1079/**
1080 * @brief Applies a gated (GLU-style) unary operation using the CANN backend.
1081 *
1082 * @details This function performs a gated activation such as GEGLU or ReGLU.
1083 * It supports two input modes:
1084 *
1085 * 1. **Dual input mode**: `dst->src[0]` and `dst->src[1]` are both valid tensors.
1086 *    These are used directly as the value and gate tensors.
1087 *
1088 * 2. **Packed input mode**: Only `dst->src[0]` is valid, and it is assumed to
1089 *    contain a concatenation of value and gate along the first dimension. This tensor
1090 *    will be split into two equal halves to form the value and gate inputs.
1091 *
1092 * The function applies a user-provided unary operation (e.g., GELU) to the value tensor,
1093 * then multiplies the result in-place with the gate tensor:
1094 *
1095 * @code
1096 * dst = unary_op(value) * gate;
1097 * @endcode
1098 *
1099 * The `swapped` parameter (from `dst->op_params[1]`) allows flipping the
1100 * order of value/gate in the packed input case.
1101 *
1102 * @param unary_op A callable that performs the unary operation using CANN ACL APIs.
1103 *                 It receives (ctx, acl_value_tensor, acl_output_tensor).
1104 * @param ctx      The CANN context used for execution.
1105 * @param dst      The destination ggml_tensor. Source tensors are in `dst->src[0]` and optionally `src[1]`.
1106 *
1107 * @see GGML_CANN_CALL_OP_UNARY_GATED
1108 */
1109void ggml_cann_op_unary_gated(std::function<void(ggml_backend_cann_context &, aclTensor *, aclTensor *)> unary_op,
1110                              ggml_backend_cann_context &                                                ctx,
1111                              ggml_tensor *                                                              dst);
1112
1113/**
1114 * @brief Helper macro to call a unary ACL operator via ggml_cann_op_unary.
1115 *
1116 * This macro wraps the specified ACLNN unary operator name into a lambda expression,
1117 * and passes it to `ggml_cann_op_unary`, which handles the common logic for executing
1118 * unary ops in the CANN backend.
1119 *
1120 * Internally, this macro expands to a lambda like:
1121 * @code
1122 * [](ggml_backend_cann_context& ctx, aclTensor* acl_src, aclTensor* acl_dst) {
1123 *     GGML_CANN_CALL_ACLNN_OP(ctx, OP_NAME, acl_src, acl_dst);
1124 * };
1125 * @endcode
1126 *
1127 * This lambda is then passed to `ggml_cann_op_unary`, which applies the operation.
1128 *
1129 * @param OP_NAME The name of the ACL unary operator to invoke via GGML_CANN_CALL_ACLNN_OP.
1130 *
1131 * @see ggml_cann_op_unary
1132 * @see GGML_CANN_CALL_ACLNN_OP
1133 */
1134#    define GGML_CANN_CALL_OP_UNARY(OP_NAME)                                                              \
1135        do {                                                                                              \
1136            auto lambda = [](ggml_backend_cann_context & ctx, aclTensor * acl_src, aclTensor * acl_dst) { \
1137                GGML_CANN_CALL_ACLNN_OP(ctx, OP_NAME, acl_src, acl_dst);                                  \
1138            };                                                                                            \
1139            ggml_cann_op_unary(lambda, ctx, dst);                                                         \
1140        } while (0)
1141
1142/**
1143 * @brief Helper macro to call a gated unary ACL operator via ggml_cann_op_unary_gated.
1144 *
1145 * This macro wraps the specified ACLNN unary operator name into a lambda expression,
1146 * and passes it to `ggml_cann_op_unary_gated`, which handles the common logic for
1147 * executing gated unary ops in the CANN backend.
1148 *
1149 * Internally, this macro expands to a lambda like:
1150 * @code
1151 * [](ggml_backend_cann_context& ctx, aclTensor* acl_src, aclTensor* acl_dst) {
1152 *     GGML_CANN_CALL_ACLNN_OP(ctx, OP_NAME, acl_src, acl_dst);
1153 * };
1154 * @endcode
1155 *
1156 * This lambda is then passed to `ggml_cann_op_unary_gated`, which applies the operation.
1157 *
1158 * @param OP_NAME The name of the ACL unary operator to invoke via GGML_CANN_CALL_ACLNN_OP.
1159 *
1160 * @see ggml_cann_op_unary_gated
1161 * @see GGML_CANN_CALL_ACLNN_OP
1162 */
1163#    define GGML_CANN_CALL_OP_UNARY_GATED(OP_NAME)                                                        \
1164        do {                                                                                              \
1165            auto lambda = [](ggml_backend_cann_context & ctx, aclTensor * acl_src, aclTensor * acl_dst) { \
1166                GGML_CANN_CALL_ACLNN_OP(ctx, OP_NAME, acl_src, acl_dst);                                  \
1167            };                                                                                            \
1168            ggml_cann_op_unary_gated(lambda, ctx, dst);                                                   \
1169        } while (0)
1170
1171#endif  // CANN_ACLNN_OPS
1172
1173/**
1174 * @brief Performs outer product operation on two ggml tensors using the CANN backend.
1175 *
1176 * @details This function computes the outer product of two input tensors (src0 and src1)
1177 * and stores the result in the destination tensor. The outer product operation is defined as:
1178 * dst[i,j,k,l] = sum_m (src0[i,m,k,l] * src1[j,m,k,l])
1179 *
1180 * The function supports multiple data types including F32, F16. For floating-point
1181 * types, it uses batch matrix multiplication for efficient computation.
1182 *
1183 * The implementation handles 4D tensor broadcasting and batch processing automatically.
1184 *
1185 * @param ctx The CANN backend context for operation execution and memory management.
1186 * @param dst The destination ggml_tensor where the outer product result will be stored.
1187 *            The input tensors are assumed to be `dst->src[0]` and `dst->src[1]`.
1188 *
1189 * @see GGML_CANN_CALL_ACLNN_OP for CANN operator invocation
1190 */
1191void ggml_cann_out_prod(ggml_backend_cann_context & ctx, ggml_tensor * dst);