* Copyright (c) 2026 Huawei Technologies Co., Ltd.
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
* CANN Open Software License Agreement Version 2.0 (the "License").
* Please refer to the License for details. You may not use this file except in compliance with the License.
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
* See LICENSE in the root of the software repository for the full text of the License.
*/
#if !defined(ASCENDC_TENSOR_API_INCLUDE_COMPILER_INTERNAL_HEADERS)
#warning \
"impl/tensor_api/utils/npu_debug_assert.h is an internal header file and must not be used directly. Functions or variables defined in this file maybe removed in the future. Please use "#include "tensor_api/tensor.h"" and use public functions or variables defined in interface headers files."
#define ASCENDC_TENSOR_API_INCLUDE_COMPILER_INTERNAL_HEADERS
#define TENSOR_API_DEBUG_ASSERT_OWNS_INTERNAL_HEADER_ACCESS
#endif
* \file npu_debug_assert.h
* \brief
*/
#ifndef IMPL_TENSOR_API_UTILS_NPU_DEBUG_ASSERT_H
#define IMPL_TENSOR_API_UTILS_NPU_DEBUG_ASSERT_H
#ifdef ASCENDC_DEBUG
#include "impl/tensor_api/utils/npu_debug_utils.h"
#include "utils/debug/asc_printf.h"
namespace asc {
namespace te {
struct tensor_api_assert_context {
__gm__ const char* file;
uint32_t line;
__gm__ const char* function;
};
template <typename... ArgTypes>
__aicore__ inline void tensor_api_debug_assert_fail(__gm__ const char* full_format, ArgTypes&&... args)
{
__asc_aicore::printf_impl_assert(full_format, args...);
trap();
}
}
}
#define TENSOR_API_DEBUG_CONTEXT \
::asc::te::tensor_api_assert_context { __FILE__, static_cast<uint32_t>(__LINE__), __FUNCTION__ }
#define TENSOR_API_DETAIL_VA_ARGS_IS_EMPTY(...) (sizeof(#__VA_ARGS__) == 1)
#define TENSOR_API_DETAIL_ASSERT_FAIL(context, format, ...) \
do { \
::asc::te::tensor_api_debug_assert_fail( \
"[ASSERT] %s:%u: %s: " format "\n", (context).file, (context).line, (context).function, ##__VA_ARGS__); \
} while (0)
#define TENSOR_API_DETAIL_DEBUG_ASSERT_AT(context, expr, ...) \
do { \
if (!(expr)) { \
const ::asc::te::tensor_api_assert_context tensor_api_assert_context_instance = (context); \
if (TENSOR_API_DETAIL_VA_ARGS_IS_EMPTY(__VA_ARGS__)) { \
TENSOR_API_DETAIL_ASSERT_FAIL(tensor_api_assert_context_instance, ""); \
} else { \
__VA_ARGS__; \
} \
} \
} while (0)
#define TENSOR_API_DETAIL_DEBUG_ASSERT(expr, ...) \
TENSOR_API_DETAIL_DEBUG_ASSERT_AT(TENSOR_API_DEBUG_CONTEXT, expr, ##__VA_ARGS__)
#define TENSOR_API_LOG_INTERNAL(format, ...) \
TENSOR_API_DETAIL_ASSERT_FAIL(tensor_api_assert_context_instance, format, ##__VA_ARGS__)
#define TENSOR_API_REPORT_INTERNAL(reporter, ...) reporter(tensor_api_assert_context_instance, ##__VA_ARGS__)
#define TENSOR_API_DEBUG_ASSERT_AT(context, ...) TENSOR_API_DETAIL_DEBUG_ASSERT_AT(context, __VA_ARGS__)
#define TENSOR_API_DEBUG_ASSERT(...) TENSOR_API_DETAIL_DEBUG_ASSERT(__VA_ARGS__)
#define TENSOR_API_DEBUG_CHECK(checker, ...) checker(TENSOR_API_DEBUG_CONTEXT, ##__VA_ARGS__)
namespace asc {
namespace te {
#define TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS(value_format, batch_value_format) \
do { \
if constexpr (view_type::has_batch) { \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, \
"Failed to check %s tensor %s in %s, current %sLayoutPtn=%s, %s%s=" batch_value_format \
"; all %s tensor %s must be %s.", \
tensor_name, traits_type::value_name(), api_name, tensor_name, view_type::pattern_name(), tensor_name, \
traits_type::field_name(), static_cast<long long>(traits_type::batch(layout)), \
static_cast<long long>(get_debug_tuple_leaf<indices>(value))..., tensor_name, \
traits_type::value_description(), traits_type::requirement()); \
} else { \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, \
"Failed to check %s tensor %s in %s, current %sLayoutPtn=%s, %s%s=" value_format \
"; all %s tensor %s must be %s.", \
tensor_name, traits_type::value_name(), api_name, tensor_name, view_type::pattern_name(), tensor_name, \
traits_type::field_name(), static_cast<long long>(get_debug_tuple_leaf<indices>(value))..., \
tensor_name, traits_type::value_description(), traits_type::requirement()); \
} \
} while (0)
template <tensor_layout_error_kind kind, typename LayoutType, typename ValueType, size_t... indices>
__aicore__ inline void report_tensor_layout_error_impl(
const tensor_api_assert_context& context, const LayoutType& layout, const ValueType& value,
__gm__ const char* tensor_name, __gm__ const char* api_name, Std::index_sequence<indices...>)
{
using view_type = debug_layout_view<LayoutType>;
using traits_type = tensor_layout_error_traits<kind>;
using format_type = debug_tuple_format_t<ValueType>;
if constexpr (Std::is_same_v<format_type, debug_tuple_flat_1>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("(%lld)", "(%lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_flat_2>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("(%lld, %lld)", "(%lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_flat_3>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("(%lld, %lld, %lld)", "(%lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_flat_4>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("(%lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_flat_5>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS(
"(%lld, %lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_flat_6>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS(
"(%lld, %lld, %lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_nested_2x2>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("((%lld, %lld), (%lld, %lld))", "(%lld, (%lld, %lld), (%lld, %lld))");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_leading_scalar_flat_2>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS("(%lld, (%lld, %lld))", "(%lld, %lld, (%lld, %lld))");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_leading_scalar_nested_2x2>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS(
"(%lld, ((%lld, %lld), (%lld, %lld)))", "(%lld, %lld, ((%lld, %lld), (%lld, %lld)))");
} else if constexpr (Std::is_same_v<format_type, debug_tuple_leading_scalar_two_flat_2>) {
TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS(
"(%lld, (%lld, %lld), (%lld, %lld))", "(%lld, %lld, (%lld, %lld), (%lld, %lld))");
} else if constexpr (view_type::has_batch) {
TENSOR_API_DETAIL_ASSERT_FAIL(
context,
"Failed to check %s tensor %s in %s, current %sLayoutPtn=%s, %s%s=(%lld, <unsupported tuple structure>), "
"%s%sLeafCount=%u; all %s tensor %s must be %s.",
tensor_name, traits_type::value_name(), api_name, tensor_name, view_type::pattern_name(), tensor_name,
traits_type::field_name(), static_cast<long long>(traits_type::batch(layout)), tensor_name,
traits_type::field_name(), static_cast<unsigned int>(nesting_depth_v<ValueType> + 1), tensor_name,
traits_type::value_description(), traits_type::requirement());
} else {
TENSOR_API_DETAIL_ASSERT_FAIL(
context,
"Failed to check %s tensor %s in %s, current %sLayoutPtn=%s, %s%s=<unsupported tuple structure>, "
"%s%sLeafCount=%u; all %s tensor %s must be %s.",
tensor_name, traits_type::value_name(), api_name, tensor_name, view_type::pattern_name(), tensor_name,
traits_type::field_name(), tensor_name, traits_type::field_name(),
static_cast<unsigned int>(nesting_depth_v<ValueType>), tensor_name, traits_type::value_description(),
traits_type::requirement());
}
}
#undef TENSOR_API_DETAIL_REPORT_LAYOUT_FORMATS
template <tensor_layout_error_kind kind = tensor_layout_error_kind::shape, typename LayoutType>
__aicore__ inline void report_tensor_layout_error(
const tensor_api_assert_context& context, const LayoutType& layout, __gm__ const char* tensor_name,
__gm__ const char* api_name)
{
using traits_type = tensor_layout_error_traits<kind>;
auto value = traits_type::value(layout);
report_tensor_layout_error_impl<kind>(
context, layout, value, tensor_name, api_name, Std::make_index_sequence<nesting_depth_v<decltype(value)>>{});
}
#define TENSOR_API_DETAIL_COPY_SIZE_FAIL(fields_format, ...) \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, \
"Failed to check copy data size in %s, " fields_format \
"; the amount of data to copy must not exceed the destination tensor size.", \
api_name, __VA_ARGS__)
#define TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, dst_shape_format, dst_batch_shape_format) \
do { \
if constexpr (src_view_type::has_batch && dst_view_type::has_batch) { \
TENSOR_API_DETAIL_COPY_SIZE_FAIL( \
"srcLayoutPtn=%s, srcShape=" src_batch_shape_format \
", copyDataSize=%lld, dstLayoutPtn=%s, dstShape=" dst_batch_shape_format ", dstTensorSize=%lld", \
src_view_type::pattern_name(), static_cast<long long>(src_view_type::batch(src.layout())), \
static_cast<long long>(get_debug_tuple_leaf<src_indices>(src_shape))..., \
static_cast<long long>(src.size()), dst_view_type::pattern_name(), \
static_cast<long long>(dst_view_type::batch(dst.layout())), \
static_cast<long long>(get_debug_tuple_leaf<dst_indices>(dst_shape))..., \
static_cast<long long>(dst.size())); \
} else if constexpr (src_view_type::has_batch) { \
TENSOR_API_DETAIL_COPY_SIZE_FAIL( \
"srcLayoutPtn=%s, srcShape=" src_batch_shape_format \
", copyDataSize=%lld, dstLayoutPtn=%s, dstShape=" dst_shape_format ", dstTensorSize=%lld", \
src_view_type::pattern_name(), static_cast<long long>(src_view_type::batch(src.layout())), \
static_cast<long long>(get_debug_tuple_leaf<src_indices>(src_shape))..., \
static_cast<long long>(src.size()), dst_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<dst_indices>(dst_shape))..., \
static_cast<long long>(dst.size())); \
} else if constexpr (dst_view_type::has_batch) { \
TENSOR_API_DETAIL_COPY_SIZE_FAIL( \
"srcLayoutPtn=%s, srcShape=" src_shape_format \
", copyDataSize=%lld, dstLayoutPtn=%s, dstShape=" dst_batch_shape_format ", dstTensorSize=%lld", \
src_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<src_indices>(src_shape))..., \
static_cast<long long>(src.size()), dst_view_type::pattern_name(), \
static_cast<long long>(dst_view_type::batch(dst.layout())), \
static_cast<long long>(get_debug_tuple_leaf<dst_indices>(dst_shape))..., \
static_cast<long long>(dst.size())); \
} else { \
TENSOR_API_DETAIL_COPY_SIZE_FAIL( \
"srcLayoutPtn=%s, srcShape=" src_shape_format \
", copyDataSize=%lld, dstLayoutPtn=%s, dstShape=" dst_shape_format ", dstTensorSize=%lld", \
src_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<src_indices>(src_shape))..., \
static_cast<long long>(src.size()), dst_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<dst_indices>(dst_shape))..., \
static_cast<long long>(dst.size())); \
} \
} while (0)
#define TENSOR_API_DETAIL_DISPATCH_COPY_DST(src_shape_format, src_batch_shape_format) \
do { \
if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_1>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld)", "(%lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_2>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, %lld)", "(%lld, %lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_3>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, %lld, %lld)", "(%lld, %lld, %lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_4>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, %lld, %lld, %lld)", \
"(%lld, %lld, %lld, %lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_5>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, %lld, %lld, %lld, %lld)", \
"(%lld, %lld, %lld, %lld, %lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_flat_6>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, %lld, %lld, %lld, %lld, %lld)", \
"(%lld, %lld, %lld, %lld, %lld, %lld, %lld)"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_nested_2x2>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "((%lld, %lld), (%lld, %lld))", \
"(%lld, (%lld, %lld), (%lld, %lld))"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_leading_scalar_flat_2>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, (%lld, %lld))", "(%lld, %lld, (%lld, %lld))"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_leading_scalar_nested_2x2>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, ((%lld, %lld), (%lld, %lld)))", \
"(%lld, %lld, ((%lld, %lld), (%lld, %lld)))"); \
} else if constexpr (Std::is_same_v<dst_format_type, debug_tuple_leading_scalar_two_flat_2>) { \
TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS( \
src_shape_format, src_batch_shape_format, "(%lld, (%lld, %lld), (%lld, %lld))", \
"(%lld, %lld, (%lld, %lld), (%lld, %lld))"); \
} else { \
report_copy_size_unsupported(context, src, dst, api_name); \
} \
} while (0)
template <typename SrcTensorType, typename DstTensorType>
__aicore__ inline void report_copy_size_unsupported(
const tensor_api_assert_context& context, const SrcTensorType& src, const DstTensorType& dst,
__gm__ const char* api_name)
{
using src_view_type = debug_layout_view<decltype(src.layout())>;
using dst_view_type = debug_layout_view<decltype(dst.layout())>;
if constexpr (src_view_type::has_batch && dst_view_type::has_batch) {
TENSOR_API_DETAIL_COPY_SIZE_FAIL(
"srcLayoutPtn=%s, srcShape=(%lld, <unsupported tuple structure>), copyDataSize=%lld, "
"dstLayoutPtn=%s, dstShape=(%lld, <unsupported tuple structure>), dstTensorSize=%lld",
src_view_type::pattern_name(), static_cast<long long>(src_view_type::batch(src.layout())),
static_cast<long long>(src.size()), dst_view_type::pattern_name(),
static_cast<long long>(dst_view_type::batch(dst.layout())), static_cast<long long>(dst.size()));
} else if constexpr (src_view_type::has_batch) {
TENSOR_API_DETAIL_COPY_SIZE_FAIL(
"srcLayoutPtn=%s, srcShape=(%lld, <unsupported tuple structure>), copyDataSize=%lld, "
"dstLayoutPtn=%s, dstShape=<unsupported tuple structure>, dstTensorSize=%lld",
src_view_type::pattern_name(), static_cast<long long>(src_view_type::batch(src.layout())),
static_cast<long long>(src.size()), dst_view_type::pattern_name(), static_cast<long long>(dst.size()));
} else if constexpr (dst_view_type::has_batch) {
TENSOR_API_DETAIL_COPY_SIZE_FAIL(
"srcLayoutPtn=%s, srcShape=<unsupported tuple structure>, copyDataSize=%lld, "
"dstLayoutPtn=%s, dstShape=(%lld, <unsupported tuple structure>), dstTensorSize=%lld",
src_view_type::pattern_name(), static_cast<long long>(src.size()), dst_view_type::pattern_name(),
static_cast<long long>(dst_view_type::batch(dst.layout())), static_cast<long long>(dst.size()));
} else {
TENSOR_API_DETAIL_COPY_SIZE_FAIL(
"srcLayoutPtn=%s, srcShape=<unsupported tuple structure>, copyDataSize=%lld, "
"dstLayoutPtn=%s, dstShape=<unsupported tuple structure>, dstTensorSize=%lld",
src_view_type::pattern_name(), static_cast<long long>(src.size()), dst_view_type::pattern_name(),
static_cast<long long>(dst.size()));
}
}
template <
typename SrcTensorType, typename DstTensorType, typename SrcShapeType, typename DstShapeType, size_t... src_indices,
size_t... dst_indices>
__aicore__ inline void report_copy_size_error_impl(
const tensor_api_assert_context& context, const SrcTensorType& src, const DstTensorType& dst,
const SrcShapeType& src_shape, const DstShapeType& dst_shape, __gm__ const char* api_name,
Std::index_sequence<src_indices...>, Std::index_sequence<dst_indices...>)
{
using src_view_type = debug_layout_view<decltype(src.layout())>;
using dst_view_type = debug_layout_view<decltype(dst.layout())>;
using src_format_type = debug_tuple_format_t<SrcShapeType>;
using dst_format_type = debug_tuple_format_t<DstShapeType>;
if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_1>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld)", "(%lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_2>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld, %lld)", "(%lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_3>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld, %lld, %lld)", "(%lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_4>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_5>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld, %lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_flat_6>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST(
"(%lld, %lld, %lld, %lld, %lld, %lld)", "(%lld, %lld, %lld, %lld, %lld, %lld, %lld)");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_nested_2x2>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("((%lld, %lld), (%lld, %lld))", "(%lld, (%lld, %lld), (%lld, %lld))");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_leading_scalar_flat_2>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST("(%lld, (%lld, %lld))", "(%lld, %lld, (%lld, %lld))");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_leading_scalar_nested_2x2>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST(
"(%lld, ((%lld, %lld), (%lld, %lld)))", "(%lld, %lld, ((%lld, %lld), (%lld, %lld)))");
} else if constexpr (Std::is_same_v<src_format_type, debug_tuple_leading_scalar_two_flat_2>) {
TENSOR_API_DETAIL_DISPATCH_COPY_DST(
"(%lld, (%lld, %lld), (%lld, %lld))", "(%lld, %lld, (%lld, %lld), (%lld, %lld))");
} else {
report_copy_size_unsupported(context, src, dst, api_name);
}
}
#undef TENSOR_API_DETAIL_DISPATCH_COPY_DST
#undef TENSOR_API_DETAIL_REPORT_COPY_SIZE_WITH_FORMATS
template <typename SrcTensorType, typename DstTensorType>
__aicore__ inline void report_copy_size_error(
const tensor_api_assert_context& context, const SrcTensorType& src, const DstTensorType& dst,
__gm__ const char* api_name)
{
using src_view_type = debug_layout_view<decltype(src.layout())>;
using dst_view_type = debug_layout_view<decltype(dst.layout())>;
auto src_shape = src_view_type::shape(src.layout());
auto dst_shape = dst_view_type::shape(dst.layout());
report_copy_size_error_impl(
context, src, dst, src_shape, dst_shape, api_name,
Std::make_index_sequence<nesting_depth_v<decltype(src_shape)>>{},
Std::make_index_sequence<nesting_depth_v<decltype(dst_shape)>>{});
}
#undef TENSOR_API_DETAIL_COPY_SIZE_FAIL
#define TENSOR_API_DETAIL_SLICE_FAIL(fields_format, ...) \
do { \
if constexpr (kind == slice_error_kind::source_shape) { \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, \
"Failed to check source tensor shape in slice, " fields_format \
"; sourceShape must be greater than 0.", \
__VA_ARGS__); \
} else if constexpr (kind == slice_error_kind::slice_shape) { \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, \
"Failed to check slice shape in slice, " fields_format "; sliceShape must be greater than 0.", \
__VA_ARGS__); \
} else { \
static_assert(kind == slice_error_kind::coord, "Unsupported slice error kind."); \
TENSOR_API_DETAIL_ASSERT_FAIL( \
context, "Failed to check coord in slice, " fields_format "; coord must be within shape.", \
__VA_ARGS__); \
} \
} while (0)
#define TENSOR_API_DETAIL_REPORT_SLICE_WITH_FORMATS( \
source_shape_format, source_batch_shape_format, coord_format, slice_shape_format, slice_batch_shape_format) \
do { \
if constexpr (view_type::has_batch) { \
if constexpr (slice_view_type::has_layout && slice_view_type::has_batch) { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_batch_shape_format ", coord=" coord_format \
", sliceLayoutPtn=%s, sliceShape=" slice_batch_shape_format, \
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
slice_view_type::pattern_name(), static_cast<long long>(slice_view_type::batch(info)), \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} else if constexpr (slice_view_type::has_layout) { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_batch_shape_format ", coord=" coord_format \
", sliceLayoutPtn=%s, sliceShape=" slice_shape_format, \
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
slice_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} else { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_batch_shape_format ", coord=" coord_format \
", sliceShape=" slice_shape_format, \
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} \
} else { \
if constexpr (slice_view_type::has_layout && slice_view_type::has_batch) { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_shape_format ", coord=" coord_format \
", sliceLayoutPtn=%s, sliceShape=" slice_batch_shape_format, \
view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
slice_view_type::pattern_name(), static_cast<long long>(slice_view_type::batch(info)), \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} else if constexpr (slice_view_type::has_layout) { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_shape_format ", coord=" coord_format \
", sliceLayoutPtn=%s, sliceShape=" slice_shape_format, \
view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
slice_view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} else { \
TENSOR_API_DETAIL_SLICE_FAIL( \
"sourceLayoutPtn=%s, sourceShape=" source_shape_format ", coord=" coord_format \
", sliceShape=" slice_shape_format, \
view_type::pattern_name(), \
static_cast<long long>(get_debug_tuple_leaf<source_indices>(source_shape))..., \
static_cast<long long>(get_debug_tuple_leaf<coord_indices>(coord))..., \
static_cast<long long>(get_debug_tuple_leaf<slice_indices>(slice_shape))...); \
} \
} \
} while (0)
#define TENSOR_API_DETAIL_REPORT_SLICE_SAME_FORMAT(tuple_format, batch_tuple_format) \
TENSOR_API_DETAIL_REPORT_SLICE_WITH_FORMATS( \
tuple_format, batch_tuple_format, tuple_format, tuple_format, batch_tuple_format)
template <
slice_error_kind kind, typename LayoutType, typename CoordType, typename InfoType, typename SourceShapeType,
typename SliceShapeType>
__aicore__ inline void report_slice_unsupported_source_batch(
const tensor_api_assert_context& context, const LayoutType& layout, const CoordType&, const InfoType& info,
const SourceShapeType&, const SliceShapeType&)
{
using view_type = debug_layout_view<LayoutType>;
using slice_view_type = debug_slice_info_view<InfoType>;
if constexpr (slice_view_type::has_layout && slice_view_type::has_batch) {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=(%lld, <unsupported tuple combination>), "
"sourceShapeLeafCount=%u, coordLeafCount=%u, sliceLayoutPtn=%s, "
"sliceShape=(%lld, <unsupported tuple combination>), sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)),
static_cast<unsigned int>(nesting_depth_v<SourceShapeType> + 1),
static_cast<unsigned int>(nesting_depth_v<CoordType>), slice_view_type::pattern_name(),
static_cast<long long>(slice_view_type::batch(info)),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType> + 1));
} else if constexpr (slice_view_type::has_layout) {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=(%lld, <unsupported tuple combination>), "
"sourceShapeLeafCount=%u, coordLeafCount=%u, sliceLayoutPtn=%s, sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)),
static_cast<unsigned int>(nesting_depth_v<SourceShapeType> + 1),
static_cast<unsigned int>(nesting_depth_v<CoordType>), slice_view_type::pattern_name(),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType>));
} else {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=(%lld, <unsupported tuple combination>), "
"sourceShapeLeafCount=%u, coordLeafCount=%u, sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<long long>(view_type::batch(layout)),
static_cast<unsigned int>(nesting_depth_v<SourceShapeType> + 1),
static_cast<unsigned int>(nesting_depth_v<CoordType>),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType>));
}
}
template <
slice_error_kind kind, typename LayoutType, typename CoordType, typename InfoType, typename SourceShapeType,
typename SliceShapeType>
__aicore__ inline void report_slice_unsupported_no_source_batch(
const tensor_api_assert_context& context, const LayoutType&, const CoordType&, const InfoType& info,
const SourceShapeType&, const SliceShapeType&)
{
using view_type = debug_layout_view<LayoutType>;
using slice_view_type = debug_slice_info_view<InfoType>;
if constexpr (slice_view_type::has_layout && slice_view_type::has_batch) {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=<unsupported tuple combination>, sourceShapeLeafCount=%u, "
"coordLeafCount=%u, sliceLayoutPtn=%s, sliceShape=(%lld, <unsupported tuple combination>), "
"sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<unsigned int>(nesting_depth_v<SourceShapeType>),
static_cast<unsigned int>(nesting_depth_v<CoordType>), slice_view_type::pattern_name(),
static_cast<long long>(slice_view_type::batch(info)),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType> + 1));
} else if constexpr (slice_view_type::has_layout) {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=<unsupported tuple combination>, sourceShapeLeafCount=%u, "
"coordLeafCount=%u, sliceLayoutPtn=%s, sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<unsigned int>(nesting_depth_v<SourceShapeType>),
static_cast<unsigned int>(nesting_depth_v<CoordType>), slice_view_type::pattern_name(),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType>));
} else {
TENSOR_API_DETAIL_SLICE_FAIL(
"sourceLayoutPtn=%s, sourceShape=<unsupported tuple combination>, sourceShapeLeafCount=%u, "
"coordLeafCount=%u, sliceShapeLeafCount=%u",
view_type::pattern_name(), static_cast<unsigned int>(nesting_depth_v<SourceShapeType>),
static_cast<unsigned int>(nesting_depth_v<CoordType>),
static_cast<unsigned int>(nesting_depth_v<SliceShapeType>));
}
}
template <
slice_error_kind kind, typename LayoutType, typename CoordType, typename InfoType, typename SourceShapeType,
typename SliceShapeType>
__aicore__ inline void report_slice_unsupported(
const tensor_api_assert_context& context, const LayoutType& layout, const CoordType& coord, const InfoType& info,
const SourceShapeType& source_shape, const SliceShapeType& slice_shape)
{
using view_type = debug_layout_view<LayoutType>;
if constexpr (view_type::has_batch) {
report_slice_unsupported_source_batch<kind>(context, layout, coord, info, source_shape, slice_shape);
} else {
report_slice_unsupported_no_source_batch<kind>(context, layout, coord, info, source_shape, slice_shape);
}
}
}
}
#else
#define TENSOR_API_LOG_INTERNAL(format, ...)
#define TENSOR_API_REPORT_INTERNAL(reporter, ...)
#define TENSOR_API_DEBUG_ASSERT_AT(context, ...)
#define TENSOR_API_DEBUG_ASSERT(...)
#define TENSOR_API_DEBUG_CHECK(checker, ...)
#endif
#endif
#if defined(TENSOR_API_DEBUG_ASSERT_OWNS_INTERNAL_HEADER_ACCESS)
#undef ASCENDC_TENSOR_API_INCLUDE_COMPILER_INTERNAL_HEADERS
#undef TENSOR_API_DEBUG_ASSERT_OWNS_INTERNAL_HEADER_ACCESS
#endif