@@ -448,6 +448,35 @@ void ggml_cann_norm(ggml_backend_cann_context & ctx, ggml_tensor * dst) {
448448 ggml_cann_release_resources (ctx, norm, acl_src, acl_dst);
449449}
450450
451+ void ggml_cann_l2_norm (ggml_backend_cann_context & ctx, ggml_tensor * dst) {
452+ ggml_tensor * src = dst->src [0 ];
453+
454+ aclTensor * acl_src = ggml_cann_create_tensor (src);
455+ aclTensor * acl_dst = ggml_cann_create_tensor (dst);
456+
457+ size_t type_size = ggml_type_size (src->type );
458+ int64_t n_bytes = src->ne [3 ]* src->ne [2 ]* src->ne [1 ]* type_size;
459+ ggml_cann_pool_alloc temp_buffer_allocator (ctx.pool (), n_bytes);
460+ void * buffer = temp_buffer_allocator.get ();
461+
462+ int64_t div_ne[] = {1 , src->ne [1 ], src->ne [2 ], src->ne [3 ]};
463+ size_t div_nb[GGML_MAX_DIMS];
464+ div_nb[0 ] = sizeof (float );
465+ for (int i = 1 ; i < GGML_MAX_DIMS; ++i) {
466+ div_nb[i] = div_nb[i - 1 ] * div_ne[i - 1 ];
467+ }
468+ aclTensor * acl_div = ggml_cann_create_tensor (buffer, ACL_FLOAT, type_size, div_ne, div_nb, GGML_MAX_DIMS);
469+
470+ std::vector<int64_t > norm_dims = { 3 };
471+ aclIntArray * dims_array = aclCreateIntArray (norm_dims.data (), norm_dims.size ());
472+
473+ float p_value = 2 .0f ;
474+ aclScalar * p_scalar = aclCreateScalar (&p_value, aclDataType::ACL_FLOAT);
475+ GGML_CANN_CALL_ACLNN_OP (ctx, Norm, acl_src, p_scalar, dims_array, true , acl_div);
476+ GGML_CANN_CALL_ACLNN_OP (ctx, Div, acl_src, acl_div, acl_dst);
477+ ggml_cann_release_resources (ctx, dims_array, p_scalar, acl_src, acl_dst, acl_div);
478+ }
479+
451480void ggml_cann_group_norm (ggml_backend_cann_context & ctx, ggml_tensor * dst) {
452481 ggml_tensor * src = dst->src [0 ];
453482
0 commit comments