Merged
feat: support float8 e8m0 scale nn transdata #4577
jayshuAdd on Aug 11
feat: support float8 e8m0 scale nn transdata #4577
Merged
Merged fromjayshu/ops-mathfeat/transdata-scale-nnintocann/ops-mathmaster
Total: 4 files changed+301-65
| @@ -31,6 +31,7 @@ | |||
| 31 | - <term>Ascend 950PR/Ascend 950DT</term>: | 31 | - <term>Ascend 950PR/Ascend 950DT</term>: |
| 32 | - 完成ND[数据格式](../../../docs/zh/context/data_format.md)到指定C0大小的FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)的转换功能,C0是FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)最后一维的大小,C0由`additionalDtype`确定。 | 32 | - 完成ND[数据格式](../../../docs/zh/context/data_format.md)到指定C0大小的FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)的转换功能,C0是FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)最后一维的大小,C0由`additionalDtype`确定。 |
| 33 | - 完成指定C0大小的FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)到ND[数据格式](../../../docs/zh/context/data_format.md)的转换功能,其中支持的NZ格式包括:FRACTAL_NZ、FRACTAL_NZ_C0_2、FRACTAL_NZ_C0_4、FRACTAL_NZ_C0_16、FRACTAL_NZ_C0_32。 | 33 | - 完成指定C0大小的FRACTAL_NZ[数据格式](../../../docs/zh/context/data_format.md)到ND[数据格式](../../../docs/zh/context/data_format.md)的转换功能,其中支持的NZ格式包括:FRACTAL_NZ、FRACTAL_NZ_C0_2、FRACTAL_NZ_C0_4、FRACTAL_NZ_C0_16、FRACTAL_NZ_C0_32。 |
| 34 | + - 当srcTensor数据类型为FLOAT8_E8M0、srcTensor格式为ND/NCL/NCHW、dstFormat为FRACTAL_NZ时,支持MX scale转换为昇腾亲和存储shape。 | ||
| 34 | <!-- end id7 --> | 35 | <!-- end id7 --> |
| 35 | <!-- npu="A3,910b" id8 --> | 36 | <!-- npu="A3,910b" id8 --> |
| 36 | - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>: | 37 | - <term>Atlas A3 训练系列产品/Atlas A3 推理系列产品</term>、<term>Atlas A2 训练系列产品/Atlas A2 推理系列产品</term>: |
| @@ -409,6 +410,7 @@ aclnnStatus aclnnNpuFormatCast( | |||
| 409 | | FLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT16(1) | ACL_FORMAT_FRACTAL_NZ(29) | | 410 | | FLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT16(1) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 410 | | BFLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_BF16(27) | ACL_FORMAT_FRACTAL_NZ(29) | | 411 | | BFLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_BF16(27) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 411 | | FLOAT8_E4M3FN | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT8_E4M3FN(36) | ACL_FORMAT_FRACTAL_NZ(29) | | 412 | | FLOAT8_E4M3FN | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT8_E4M3FN(36) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 413 | + | FLOAT8_E8M0 | ACL_FORMAT_ND(2)/ACL_FORMAT_NCL(47)/ACL_FORMAT_NCHW(0) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT8_E8M0 | ACL_FORMAT_FRACTAL_NZ(29) | | ||
| 412 | | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT8_E4M3FN(36) | ACL_FORMAT_FRACTAL_NZ(29) | | 414 | | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT8_E4M3FN(36) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 413 | | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT4_E2M1(40) | ACL_FORMAT_FRACTAL_NZ(29) | | 415 | | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT4_E2M1(40) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 414 | | FLOAT4_E1M2 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT4_E1M2(41) | ACL_FORMAT_FRACTAL_NZ(29) | | 416 | | FLOAT4_E1M2 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | ACL_FLOAT4_E1M2(41) | ACL_FORMAT_FRACTAL_NZ(29) | |
| @@ -445,6 +447,7 @@ aclnnStatus aclnnNpuFormatCast( | |||
| 445 | | FLOAT16 | FLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | | 447 | | FLOAT16 | FLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 446 | | BFLOAT16 | BFLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | | 448 | | BFLOAT16 | BFLOAT16 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 447 | | FLOAT8_E4M3FN | FLOAT8_E4M3FN | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | | 449 | | FLOAT8_E4M3FN | FLOAT8_E4M3FN | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 450 | + | FLOAT8_E8M0 | FLOAT8_E8M0 | ACL_FORMAT_ND(2)/ACL_FORMAT_NCL(47)/ACL_FORMAT_NCHW(0) | ACL_FORMAT_FRACTAL_NZ(29) | | ||
| 448 | | FLOAT4_E2M1 | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ_C0_32(51) | | 451 | | FLOAT4_E2M1 | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ_C0_32(51) | |
| 449 | | FLOAT4_E2M1 | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | | 452 | | FLOAT4_E2M1 | FLOAT4_E2M1 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | |
| 450 | | FLOAT4_E1M2 | FLOAT4_E1M2 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | | 453 | | FLOAT4_E1M2 | FLOAT4_E1M2 | ACL_FORMAT_ND(2) | ACL_FORMAT_FRACTAL_NZ(29) | |
| @@ -481,6 +484,10 @@ aclnnStatus aclnnNpuFormatCast( | |||
| 481 | | ACL_FLOAT8_E4M3FN(36) | 32 | | 484 | | ACL_FLOAT8_E4M3FN(36) | 32 | |
| 482 | | ACL_HIFLOAT8(34) | 32 | | 485 | | ACL_HIFLOAT8(34) | 32 | |
| 483 | 486 | ||
| 487 | + - FLOAT8_E8M0特殊场景: | ||
| 488 | + - srcTensor数据类型为FLOAT8_E8M0,srcTensor格式为ND/NCL/NCHW,dstFormat为FRACTAL_NZ时,仅支持3维或4维scale输入。转换后的storage shape分别为`(ceil(N/16), ceil(K/64), 16, 2)`或`(g, ceil(N/16), ceil(K/64), 16, 2)`。 | ||
| 489 | + - FLOAT8_E8M0 scale转换为昇腾亲和存储shape的能力不支持图模式,仅支持单算子模式和aclnn直调场景。 | ||
| 490 | + | ||
| 484 | - 当前不支持的特殊场景: | 491 | - 当前不支持的特殊场景: |
| 485 | - srcTensor的数据类型和additionalDtype相同,srcTensor格式为ND且类型为FLOAT16或BFLOAT16时,若维度表示为[k, n],则k为1场景暂不支持。 | 492 | - srcTensor的数据类型和additionalDtype相同,srcTensor格式为ND且类型为FLOAT16或BFLOAT16时,若维度表示为[k, n],则k为1场景暂不支持。 |
| 486 | - 不支持调用当前接口转昇腾亲和[数据格式](../../../docs/zh/context/data_format.md)FRACTAL_NZ后,进行任何能修改张量的操作,如contiguous、pad、slice等; | 493 | - 不支持调用当前接口转昇腾亲和[数据格式](../../../docs/zh/context/data_format.md)FRACTAL_NZ后,进行任何能修改张量的操作,如contiguous、pad、slice等; |
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <set> | 13 | #include <set> |
| 14 | #include <string> | 14 | #include <string> |
| 15 | #include <utility> | 15 | #include <utility> |
| 16 | +#include <vector> | ||
| 16 | #include "securec.h" | 17 | #include "securec.h" |
| 17 | 18 | ||
| 18 | #include "graph/types.h" | 19 | #include "graph/types.h" |
| @@ -28,6 +29,7 @@ | |||
| 28 | 29 | ||
| 29 | #include "aclnn_kernels/common/op_error_check.h" | 30 | #include "aclnn_kernels/common/op_error_check.h" |
| 30 | #include "aclnn_kernels/contiguous.h" | 31 | #include "aclnn_kernels/contiguous.h" |
| 32 | +#include "aclnn_kernels/pad.h" | ||
| 31 | #include "aclnn_kernels/reshape.h" | 33 | #include "aclnn_kernels/reshape.h" |
| 32 | #include "aclnn_kernels/transdata.h" | 34 | #include "aclnn_kernels/transdata.h" |
| 33 | #include "aclnn_kernels/transpose.h" | 35 | #include "aclnn_kernels/transpose.h" |
| @@ -61,6 +63,7 @@ static constexpr size_t FRACTAL_NZ_C0_4B = 64; | |||
| 61 | static constexpr int64_t C0_SIZE = 16; | 63 | static constexpr int64_t C0_SIZE = 16; |
| 62 | static constexpr int64_t N0_SIZE = 16; | 64 | static constexpr int64_t N0_SIZE = 16; |
| 63 | static constexpr int64_t NUM_ONE = 1; | 65 | static constexpr int64_t NUM_ONE = 1; |
| 66 | +static constexpr int64_t NUM_TWO = 2; | ||
| 64 | static constexpr int64_t NUM_SIXTEEN = 16; | 67 | static constexpr int64_t NUM_SIXTEEN = 16; |
| 65 | static constexpr int NUM_FOUR = 4; | 68 | static constexpr int NUM_FOUR = 4; |
| 66 | static constexpr const char* ACLNN_NAME = "aclnnNpuFormatCast"; | 69 | static constexpr const char* ACLNN_NAME = "aclnnNpuFormatCast"; |
| @@ -92,12 +95,12 @@ const std::set<std::pair<op::Format, op::Format>> kTransdataForwardFormatPairs91 | |||
| 92 | static const std::initializer_list<DataType> ASCEND950_WEIGHT_DTYPE_SUPPORT_LIST = { | 95 | static const std::initializer_list<DataType> ASCEND950_WEIGHT_DTYPE_SUPPORT_LIST = { |
| 93 | DataType::DT_INT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, DataType::DT_BF16, | 96 | DataType::DT_INT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, DataType::DT_BF16, |
| 94 | DataType::DT_INT32, DataType::DT_FLOAT8_E4M3FN, DataType::DT_FLOAT4_E2M1, DataType::DT_HIFLOAT8, | 97 | DataType::DT_INT32, DataType::DT_FLOAT8_E4M3FN, DataType::DT_FLOAT4_E2M1, DataType::DT_HIFLOAT8, |
| 95 | - DataType::DT_UINT8, DataType::DT_FLOAT4_E1M2}; | 98 | + DataType::DT_UINT8, DataType::DT_FLOAT4_E1M2, DataType::DT_FLOAT8_E8M0}; |
| 96 | 99 | ||
| 97 | static const std::initializer_list<DataType> WEIGHT_DTYPE_SUPPORT_LIST = { | 100 | static const std::initializer_list<DataType> WEIGHT_DTYPE_SUPPORT_LIST = { |
| 98 | - DataType::DT_INT8, DataType::DT_UINT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, | 101 | + DataType::DT_INT8, DataType::DT_UINT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, |
| 99 | - DataType::DT_BF16, DataType::DT_INT32, DataType::DT_UINT32, DataType::DT_FLOAT8_E4M3FN, | 102 | + DataType::DT_BF16, DataType::DT_INT32, DataType::DT_UINT32, DataType::DT_FLOAT8_E4M3FN, |
| 100 | - DataType::DT_FLOAT4_E2M1, DataType::DT_HIFLOAT8, DataType::DT_FLOAT4_E1M2}; | 103 | + DataType::DT_FLOAT4_E2M1, DataType::DT_HIFLOAT8, DataType::DT_FLOAT4_E1M2, DataType::DT_FLOAT8_E8M0}; |
| 101 | 104 | ||
| 102 | static const std::initializer_list<DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { | 105 | static const std::initializer_list<DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { |
| 103 | DataType::DT_INT8, DataType::DT_UINT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, | 106 | DataType::DT_INT8, DataType::DT_UINT8, DataType::DT_FLOAT, DataType::DT_FLOAT16, |
| @@ -159,15 +162,6 @@ static bool CheckInputFormatSupportedToNz(const op::Format inputFormat) | |||
| 159 | INPUT_FORMAT_TO_NZ_SUPPORT_LIST.end(); | 162 | INPUT_FORMAT_TO_NZ_SUPPORT_LIST.end(); |
| 160 | } | 163 | } |
| 161 | 164 | ||
| 162 | -inline int64_t Ceil(int64_t x, int64_t y) | ||
| 163 | -{ | ||
| 164 | - if (y == 0) { | ||
| 165 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "The y is zero"); | ||
| 166 | - return INT64_MIN; | ||
| 167 | - } | ||
| 168 | - return ((x + y - 1) / y) * y; | ||
| 169 | -} | ||
| 170 | - | ||
| 171 | inline int64_t CeilDiv(int64_t x, int64_t y) | 165 | inline int64_t CeilDiv(int64_t x, int64_t y) |
| 172 | { | 166 | { |
| 173 | if (y == 0) { | 167 | if (y == 0) { |
| @@ -177,6 +171,84 @@ inline int64_t CeilDiv(int64_t x, int64_t y) | |||
| 177 | return (x + y - 1) / y; | 171 | return (x + y - 1) / y; |
| 178 | } | 172 | } |
| 179 | 173 | ||
| 174 | +static bool IsFloat8E8m0NnSrcFormat(op::Format srcFormat) | ||
| 175 | +{ | ||
| 176 | + return srcFormat == op::Format::FORMAT_ND || srcFormat == op::Format::FORMAT_NCL || | ||
| 177 | + srcFormat == op::Format::FORMAT_NCHW; | ||
| 178 | +} | ||
| 179 | + | ||
| 180 | +static bool IsFloat8E8m0NdToNn(DataType srcDtype, int additionalDtype, op::Format srcFormat, op::Format dstFormat) | ||
| 181 | +{ | ||
| 182 | + return srcDtype == ge::DT_FLOAT8_E8M0 && additionalDtype == ge::DT_FLOAT8_E8M0 && | ||
| 183 | + IsFloat8E8m0NnSrcFormat(srcFormat) && dstFormat == op::Format::FORMAT_FRACTAL_NZ; | ||
| 184 | +} | ||
| 185 | + | ||
| 186 | +static aclnnStatus CheckFloat8E8m0NnShape(const gert::Shape& viewShape) | ||
| 187 | +{ | ||
| 188 | + auto viewShapeDim = viewShape.GetDimNum(); | ||
| 189 | + OP_CHECK(viewShapeDim == DIMS_THREE || viewShapeDim == DIMS_FOUR, | ||
| 190 | + OP_LOGE_FOR_INVALID_SHAPEDIM_WITH_REASON( | ||
| 191 | + ACLNN_NAME, "srcTensor", std::to_string(viewShapeDim), | ||
| 192 | + "FLOAT8_E8M0 ND to Ascend affinity format only supports 3D or 4D scale shape"), | ||
| 193 | + return ACLNN_ERR_PARAM_INVALID); | ||
| 194 | + for (size_t i = 0; i < viewShapeDim; ++i) { | ||
| 195 | + OP_CHECK(viewShape.GetDim(i) > 0, | ||
| 196 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON(ACLNN_NAME, "srcTensor", op::ToString(viewShape).GetString(), | ||
| 197 | + "Dims of FLOAT8_E8M0 scale must be greater than 0"), | ||
| 198 | + return ACLNN_ERR_PARAM_INVALID); | ||
| 199 | + } | ||
| 200 | + OP_CHECK(viewShape.GetDim(viewShapeDim - NUM_ONE) == NUM_TWO, | ||
| 201 | + OP_LOGE_FOR_INVALID_SHAPE_WITH_REASON(ACLNN_NAME, "srcTensor", op::ToString(viewShape).GetString(), | ||
| 202 | + "The last dim of FLOAT8_E8M0 scale must be 2"), | ||
| 203 | + return ACLNN_ERR_PARAM_INVALID); | ||
| 204 | + return ACLNN_SUCCESS; | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +static bool ValidFloat8E8m0NnDstShape(const gert::Shape& srcViewShape, const gert::Shape& dstStorageShape) | ||
| 208 | +{ | ||
| 209 | + auto srcDimNum = srcViewShape.GetDimNum(); | ||
| 210 | + auto dstDimNum = dstStorageShape.GetDimNum(); | ||
| 211 | + OP_CHECK(dstDimNum == srcDimNum + NUM_ONE, | ||
| 212 | + OP_LOGE_FOR_INVALID_SHAPEDIMS_WITH_REASON( | ||
| 213 | + ACLNN_NAME, "srcTensor, dstTensor", std::to_string(srcDimNum) + ", " + std::to_string(dstDimNum), | ||
| 214 | + "The StorageShape dim of dstTensor must be srcTensor dim plus 1 for FLOAT8_E8M0 Ascend affinity " | ||
| 215 | + "format"), | ||
| 216 | + return false); | ||
| 217 | + | ||
| 218 | + for (uint64_t i = 0; i < srcDimNum - DIMS_THREE; ++i) { | ||
| 219 | + OP_CHECK( | ||
| 220 | + srcViewShape.GetDim(i) == dstStorageShape.GetDim(i), | ||
| 221 | + OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | ||
| 222 | + ACLNN_NAME, "srcTensor, dstTensor", | ||
| 223 | + std::string(op::ToString(srcViewShape).GetString()) + ", " + op::ToString(dstStorageShape).GetString(), | ||
| 224 | + "Prefix dims of FLOAT8_E8M0 Ascend affinity format must keep unchanged"), | ||
| 225 | + return false); | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + int64_t kScale = srcViewShape.GetDim(srcDimNum - DIMS_THREE); | ||
| 229 | + int64_t n = srcViewShape.GetDim(srcDimNum - DIMS_TWO); | ||
| 230 | + int64_t n1 = CeilDiv(n, NUM_SIXTEEN); | ||
| 231 | + uint64_t n1Axis = srcDimNum - DIMS_THREE; | ||
| 232 | + OP_CHECK(dstStorageShape.GetDim(n1Axis) == n1 && dstStorageShape.GetDim(n1Axis + NUM_ONE) == kScale && | ||
| 233 | + dstStorageShape.GetDim(n1Axis + DIMS_TWO) == NUM_SIXTEEN && | ||
| 234 | + dstStorageShape.GetDim(n1Axis + DIMS_THREE) == NUM_TWO, | ||
| 235 | + OP_LOGE_FOR_INVALID_SHAPES_WITH_REASON( | ||
| 236 | + ACLNN_NAME, "srcTensor, dstTensor", | ||
| 237 | + std::string(op::ToString(srcViewShape).GetString()) + ", " + op::ToString(dstStorageShape).GetString(), | ||
| 238 | + "FLOAT8_E8M0 Ascend affinity format storage shape must be (..., ceil(N/16), KScale, 16, 2)"), | ||
| 239 | + return false); | ||
| 240 | + return true; | ||
| 241 | +} | ||
| 242 | + | ||
| 243 | +inline int64_t Ceil(int64_t x, int64_t y) | ||
| 244 | +{ | ||
| 245 | + if (y == 0) { | ||
| 246 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "The y is zero"); | ||
| 247 | + return INT64_MIN; | ||
| 248 | + } | ||
| 249 | + return ((x + y - 1) / y) * y; | ||
| 250 | +} | ||
| 251 | + | ||
| 180 | static aclnnStatus ValidateNonQuantMatmulParams([[maybe_unused]] int32_t additionalDtype, const gert::Shape& viewShape, | 252 | static aclnnStatus ValidateNonQuantMatmulParams([[maybe_unused]] int32_t additionalDtype, const gert::Shape& viewShape, |
| 181 | size_t viewShapeDim, [[maybe_unused]] int32_t dstFormat) | 253 | size_t viewShapeDim, [[maybe_unused]] int32_t dstFormat) |
| 182 | { | 254 | { |
| @@ -304,6 +376,9 @@ static aclnnStatus Check95NdToNzCalculateSizeAndFormatInputs(const aclTensor* sr | |||
| 304 | auto srcDtype = srcTensor->GetDataType(); | 376 | auto srcDtype = srcTensor->GetDataType(); |
| 305 | auto viewShape = srcTensor->GetViewShape(); | 377 | auto viewShape = srcTensor->GetViewShape(); |
| 306 | auto viewShapeDim = viewShape.GetDimNum(); | 378 | auto viewShapeDim = viewShape.GetDimNum(); |
| 379 | + if (IsFloat8E8m0NdToNn(srcDtype, additionalDtype, srcFormat, static_cast<op::Format>(dstFormat))) { | ||
| 380 | + return CheckFloat8E8m0NnShape(viewShape); | ||
| 381 | + } | ||
| 307 | for (size_t i = 0; i < viewShapeDim; i++) { | 382 | for (size_t i = 0; i < viewShapeDim; i++) { |
| 308 | OP_CHECK( | 383 | OP_CHECK( |
| 309 | viewShape.GetDim(i) != 0, | 384 | viewShape.GetDim(i) != 0, |
| @@ -411,6 +486,16 @@ static aclnnStatus Check95NdToNzGetWorkSpaceSizeInputs(const aclTensor* srcTenso | |||
| 411 | op::Format dstFormat = dstTensor->GetStorageFormat(); | 486 | op::Format dstFormat = dstTensor->GetStorageFormat(); |
| 412 | auto storageShape = dstTensor->GetStorageShape(); | 487 | auto storageShape = dstTensor->GetStorageShape(); |
| 413 | auto storageShapeDim = storageShape.GetDimNum(); | 488 | auto storageShapeDim = storageShape.GetDimNum(); |
| 489 | + if (IsFloat8E8m0NdToNn(srcDtype, static_cast<int>(dstDtype), srcFormat, dstFormat)) { | ||
| 490 | + auto ret = CheckFloat8E8m0NnShape(srcViewShape); | ||
| 491 | + if (ret != ACLNN_SUCCESS) { | ||
| 492 | + return ret; | ||
| 493 | + } | ||
| 494 | + OP_CHECK(ValidFloat8E8m0NnDstShape(srcViewShape, storageShape), | ||
| 495 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "The shape of output Ascend affinity format tensor is invalid."), | ||
| 496 | + return ACLNN_ERR_PARAM_INVALID); | ||
| 497 | + return ACLNN_SUCCESS; | ||
| 498 | + } | ||
| 414 | if (!CheckFormatValid(srcDtype, dstDtype, srcFormat, dstFormat)) { | 499 | if (!CheckFormatValid(srcDtype, dstDtype, srcFormat, dstFormat)) { |
| 415 | return ACLNN_ERR_PARAM_INVALID; | 500 | return ACLNN_ERR_PARAM_INVALID; |
| 416 | } | 501 | } |
| @@ -664,6 +749,42 @@ aclnnStatus CalcNdToNz(const aclTensor* srcTensor, int additionalDtype, int64_t* | |||
| 664 | return ACLNN_SUCCESS; | 749 | return ACLNN_SUCCESS; |
| 665 | } | 750 | } |
| 666 | 751 | ||
| 752 | +aclnnStatus CalcFloat8E8m0NdToNn(const aclTensor* srcTensor, int64_t** dstShape, uint64_t* dstShapeSize, | ||
| 753 | + int* actualFormat) | ||
| 754 | +{ | ||
| 755 | + auto viewShape = srcTensor->GetViewShape(); | ||
| 756 | + auto viewShapeDim = viewShape.GetDimNum(); | ||
| 757 | + auto ret = CheckFloat8E8m0NnShape(viewShape); | ||
| 758 | + OP_CHECK(ret == ACLNN_SUCCESS, OP_LOGW("Failed to check FLOAT8_E8M0 Ascend affinity format shape"), return ret); | ||
| 759 | + | ||
| 760 | + int64_t kScale = viewShape.GetDim(viewShapeDim - DIMS_THREE); | ||
| 761 | + int64_t n = viewShape.GetDim(viewShapeDim - DIMS_TWO); | ||
| 762 | + int64_t n1 = CeilDiv(n, NUM_SIXTEEN); | ||
| 763 | + *dstShapeSize = static_cast<uint64_t>(viewShapeDim + NUM_ONE); | ||
| 764 | + try { | ||
| 765 | + *dstShape = new int64_t[*dstShapeSize](); | ||
| 766 | + } catch (std::bad_alloc& e) { | ||
| 767 | + OP_LOGE(ACLNN_ERR_RUNTIME_ERROR, "Failed to allocate memory for the Ascend affinity format"); | ||
| 768 | + return ACLNN_ERR_RUNTIME_ERROR; | ||
| 769 | + } | ||
| 770 | + | ||
| 771 | + for (uint64_t i = 0; i < *dstShapeSize; ++i) { | ||
| 772 | + if (i < viewShapeDim - DIMS_THREE) { | ||
| 773 | + (*dstShape)[i] = viewShape.GetDim(i); | ||
| 774 | + } else if (i == viewShapeDim - DIMS_THREE) { | ||
| 775 | + (*dstShape)[i] = n1; | ||
| 776 | + } else if (i == viewShapeDim - DIMS_TWO) { | ||
| 777 | + (*dstShape)[i] = kScale; | ||
| 778 | + } else if (i == viewShapeDim - NUM_ONE) { | ||
| 779 | + (*dstShape)[i] = NUM_SIXTEEN; | ||
| 780 | + } else { | ||
| 781 | + (*dstShape)[i] = NUM_TWO; | ||
| 782 | + } | ||
| 783 | + } | ||
| 784 | + *actualFormat = op::Format::FORMAT_FRACTAL_NZ; | ||
| 785 | + return ACLNN_SUCCESS; | ||
| 786 | +} | ||
| 787 | + | ||
| 667 | aclnnStatus CalcToNd(const aclTensor* srcTensor, [[maybe_unused]] int additionalDtype, int64_t** dstShape, | 788 | aclnnStatus CalcToNd(const aclTensor* srcTensor, [[maybe_unused]] int additionalDtype, int64_t** dstShape, |
| 668 | uint64_t* dstShapeSize, int* actualFormat) | 789 | uint64_t* dstShapeSize, int* actualFormat) |
| 669 | { | 790 | { |
| @@ -1016,6 +1137,56 @@ aclnnStatus CalcToNDHWC(const aclTensor* srcTensor, [[maybe_unused]] int additio | |||
| 1016 | return ACLNN_SUCCESS; | 1137 | return ACLNN_SUCCESS; |
| 1017 | } | 1138 | } |
| 1018 | 1139 | ||
| 1140 | +const aclTensor* TransFloat8E8m0NdToNn(const aclTensor* srcTensor, aclOpExecutor* executor) | ||
| 1141 | +{ | ||
| 1142 | + auto viewShape = srcTensor->GetViewShape(); | ||
| 1143 | + auto viewShapeDim = viewShape.GetDimNum(); | ||
| 1144 | + int64_t kScale = viewShape.GetDim(viewShapeDim - DIMS_THREE); | ||
| 1145 | + int64_t n = viewShape.GetDim(viewShapeDim - DIMS_TWO); | ||
| 1146 | + int64_t n1 = CeilDiv(n, NUM_SIXTEEN); | ||
| 1147 | + int64_t alignedN = n1 * NUM_SIXTEEN; | ||
| 1148 | + auto srcByteView = executor->CreateView(const_cast<aclTensor*>(srcTensor), viewShape, srcTensor->GetViewOffset()); | ||
| 1149 | + CHECK_RET(srcByteView != nullptr, nullptr); | ||
| 1150 | + srcByteView->SetDataType(op::DataType::DT_INT8); | ||
| 1151 | + const aclTensor* tensorToReshape = srcByteView; | ||
| 1152 | + if (alignedN != n) { | ||
| 1153 | + std::vector<int64_t> paddings(viewShapeDim * DIMS_TWO, 0); | ||
| 1154 | + size_t nAxis = viewShapeDim - DIMS_TWO; | ||
| 1155 | + paddings[nAxis * DIMS_TWO + NUM_ONE] = alignedN - n; | ||
| 1156 | + auto paddingsArray = executor->AllocIntArray(paddings.data(), paddings.size()); | ||
| 1157 | + auto paddingsTensor = executor->ConvertToTensor(paddingsArray, op::DataType::DT_INT64); | ||
| 1158 | + CHECK_RET(paddingsTensor != nullptr, nullptr); | ||
| 1159 | + tensorToReshape = l0op::Pad(srcByteView, paddingsTensor, executor); | ||
| 1160 | + CHECK_RET(tensorToReshape != nullptr, nullptr); | ||
| 1161 | + } | ||
| 1162 | + | ||
| 1163 | + std::vector<int64_t> reshapeShape; | ||
| 1164 | + reshapeShape.reserve(viewShapeDim + NUM_ONE); | ||
| 1165 | + for (size_t i = 0; i < viewShapeDim - DIMS_THREE; ++i) { | ||
| 1166 | + reshapeShape.emplace_back(viewShape.GetDim(i)); | ||
| 1167 | + } | ||
| 1168 | + reshapeShape.emplace_back(kScale); | ||
| 1169 | + reshapeShape.emplace_back(n1); | ||
| 1170 | + reshapeShape.emplace_back(NUM_SIXTEEN); | ||
| 1171 | + reshapeShape.emplace_back(NUM_TWO); | ||
| 1172 | + | ||
| 1173 | + auto reshapeArray = executor->AllocIntArray(reshapeShape.data(), reshapeShape.size()); | ||
| 1174 | + auto reshapeTensor = l0op::Reshape(tensorToReshape, reshapeArray, executor); | ||
| 1175 | + CHECK_RET(reshapeTensor != nullptr, nullptr); | ||
| 1176 | + | ||
| 1177 | + std::vector<int64_t> perm(reshapeShape.size()); | ||
| 1178 | + for (size_t i = 0; i < perm.size(); ++i) { | ||
| 1179 | + perm[i] = static_cast<int64_t>(i); | ||
| 1180 | + } | ||
| 1181 | + size_t kScaleAxis = viewShapeDim - DIMS_THREE; | ||
| 1182 | + size_t n1Axis = viewShapeDim - DIMS_TWO; | ||
| 1183 | + std::swap(perm[kScaleAxis], perm[n1Axis]); | ||
| 1184 | + auto permArray = executor->AllocIntArray(perm.data(), perm.size()); | ||
| 1185 | + auto transposeTensor = const_cast<aclTensor*>(l0op::Transpose(reshapeTensor, permArray, executor)); | ||
| 1186 | + CHECK_RET(transposeTensor != nullptr, nullptr); | ||
| 1187 | + return transposeTensor; | ||
| 1188 | +} | ||
| 1189 | + | ||
| 1019 | aclnnStatus aclnnNpuFormatCastCalculateSizeAndFormat(const aclTensor* srcTensor, const int dstFormat, | 1190 | aclnnStatus aclnnNpuFormatCastCalculateSizeAndFormat(const aclTensor* srcTensor, const int dstFormat, |
| 1020 | int additionalDtype, int64_t** dstShape, uint64_t* dstShapeSize, | 1191 | int additionalDtype, int64_t** dstShape, uint64_t* dstShapeSize, |
| 1021 | int* actualFormat) | 1192 | int* actualFormat) |
| @@ -1026,6 +1197,14 @@ aclnnStatus aclnnNpuFormatCastCalculateSizeAndFormat(const aclTensor* srcTensor, | |||
| 1026 | if (additionalDtype == -1) { | 1197 | if (additionalDtype == -1) { |
| 1027 | additionalDtype = static_cast<int>(srcTensor->GetDataType()); | 1198 | additionalDtype = static_cast<int>(srcTensor->GetDataType()); |
| 1028 | } | 1199 | } |
| 1200 | + if (IsFloat8E8m0NdToNn(srcTensor->GetDataType(), additionalDtype, srcFormat, static_cast<op::Format>(dstFormat))) { | ||
| 1201 | + OP_CHECK(IsRegBase(), | ||
| 1202 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "FLOAT8_E8M0 ND to Ascend affinity format only supports Ascend950."), | ||
| 1203 | + return ACLNN_ERR_PARAM_INVALID); | ||
| 1204 | + auto retNdToNn = Check95NdToNzCalculateSizeAndFormatInputs(srcTensor, dstFormat, additionalDtype); | ||
| 1205 | + OP_CHECK(retNdToNn == ACLNN_SUCCESS, OP_LOGW("Failed to check inputs"), return ACLNN_ERR_PARAM_INVALID); | ||
| 1206 | + return CalcFloat8E8m0NdToNn(srcTensor, dstShape, dstShapeSize, actualFormat); | ||
| 1207 | + } | ||
| 1029 | if (dstFormat == op::Format::FORMAT_FRACTAL_NZ && | 1208 | if (dstFormat == op::Format::FORMAT_FRACTAL_NZ && |
| 1030 | ((srcFormat == op::Format::FORMAT_ND || srcFormat == op::Format::FORMAT_NCL) || | 1209 | ((srcFormat == op::Format::FORMAT_ND || srcFormat == op::Format::FORMAT_NCL) || |
| 1031 | (additionalDtype == static_cast<int>(srcTensor->GetDataType()) && CheckInputFormatSupportedToNz(srcFormat)))) { | 1210 | (additionalDtype == static_cast<int>(srcTensor->GetDataType()) && CheckInputFormatSupportedToNz(srcFormat)))) { |
| @@ -1097,6 +1276,8 @@ aclnnStatus aclnnNpuFormatCastGetWorkspaceSize(const aclTensor* srcTensor, aclTe | |||
| 1097 | auto ret = CheckGetWorkSpaceSizeInputs(srcTensor, dstTensor); | 1276 | auto ret = CheckGetWorkSpaceSizeInputs(srcTensor, dstTensor); |
| 1098 | op::Format srcFormat = srcTensor->GetStorageFormat(); | 1277 | op::Format srcFormat = srcTensor->GetStorageFormat(); |
| 1099 | op::Format dstFormat = dstTensor->GetStorageFormat(); | 1278 | op::Format dstFormat = dstTensor->GetStorageFormat(); |
| 1279 | + bool isFloat8E8m0Nn = IsFloat8E8m0NdToNn(srcTensor->GetDataType(), static_cast<int>(dstTensor->GetDataType()), | ||
| 1280 | + srcFormat, dstFormat); | ||
| 1100 | // ASCEND950校验特殊场景 | 1281 | // ASCEND950校验特殊场景 |
| 1101 | if (IsRegBase()) { | 1282 | if (IsRegBase()) { |
| 1102 | if (dstFormat == op::Format::FORMAT_FRACTAL_NZ && | 1283 | if (dstFormat == op::Format::FORMAT_FRACTAL_NZ && |
| @@ -1118,9 +1299,20 @@ aclnnStatus aclnnNpuFormatCastGetWorkspaceSize(const aclTensor* srcTensor, aclTe | |||
| 1118 | if (IsRegBase()) { | 1299 | if (IsRegBase()) { |
| 1119 | formatTensor = const_cast<aclTensor*>(srcTensor); | 1300 | formatTensor = const_cast<aclTensor*>(srcTensor); |
| 1120 | // 适配srcFormat为NCL的场景 | 1301 | // 适配srcFormat为NCL的场景 |
| 1121 | - if ((IsQuantMatmulDtype(srcTensor->GetDataType(), dstTensor->GetDataType()) && | 1302 | + if (isFloat8E8m0Nn) { |
| 1122 | - dstFormat == op::Format::FORMAT_FRACTAL_NZ) || | 1303 | + formatTensor->SetViewFormat(op::Format::FORMAT_ND); |
| 1123 | - srcFormat == op::Format::FORMAT_NCL) { | 1304 | + formatTensor->SetOriginalFormat(op::Format::FORMAT_ND); |
| 1305 | + formatTensor->SetStorageFormat(op::Format::FORMAT_ND); | ||
| 1306 | + formatTensor->SetOriginalShape(srcTensor->GetViewShape()); | ||
| 1307 | + formatTensor->SetStorageShape(srcTensor->GetViewShape()); | ||
| 1308 | + | ||
| 1309 | + dstTensor->SetViewFormat(op::Format::FORMAT_ND); | ||
| 1310 | + dstTensor->SetViewShape(srcTensor->GetViewShape()); | ||
| 1311 | + dstTensor->SetOriginalFormat(op::Format::FORMAT_ND); | ||
| 1312 | + dstTensor->SetOriginalShape(srcTensor->GetOriginalShape()); | ||
| 1313 | + } else if ((IsQuantMatmulDtype(srcTensor->GetDataType(), dstTensor->GetDataType()) && | ||
| 1314 | + dstFormat == op::Format::FORMAT_FRACTAL_NZ) || | ||
| 1315 | + srcFormat == op::Format::FORMAT_NCL) { | ||
| 1124 | formatTensor->SetViewFormat(op::Format::FORMAT_ND); | 1316 | formatTensor->SetViewFormat(op::Format::FORMAT_ND); |
| 1125 | formatTensor->SetOriginalFormat(op::Format::FORMAT_ND); | 1317 | formatTensor->SetOriginalFormat(op::Format::FORMAT_ND); |
| 1126 | formatTensor->SetStorageFormat(op::Format::FORMAT_ND); | 1318 | formatTensor->SetStorageFormat(op::Format::FORMAT_ND); |
| @@ -1194,8 +1386,10 @@ aclnnStatus aclnnNpuFormatCastGetWorkspaceSize(const aclTensor* srcTensor, aclTe | |||
| 1194 | } | 1386 | } |
| 1195 | aclTensor* outTensor; | 1387 | aclTensor* outTensor; |
| 1196 | int64_t dstDimNum = dstTensor->GetStorageShape().GetDimNum(); | 1388 | int64_t dstDimNum = dstTensor->GetStorageShape().GetDimNum(); |
| 1197 | - if (dstTensor->GetStorageShape().GetDim(dstDimNum - NUM_ONE) == NUM_SIXTEEN && | 1389 | + if (isFloat8E8m0Nn) { |
| 1198 | - ge::GetSizeByDataType(srcTensor->GetDataType()) >= NUM_FOUR && !IsRegBase()) { | 1390 | + outTensor = const_cast<aclTensor*>(TransFloat8E8m0NdToNn(formatTensor, uniqueExecutor.get())); |
| 1391 | + } else if (dstTensor->GetStorageShape().GetDim(dstDimNum - NUM_ONE) == NUM_SIXTEEN && | ||
| 1392 | + ge::GetSizeByDataType(srcTensor->GetDataType()) >= NUM_FOUR && !IsRegBase()) { | ||
| 1199 | outTensor = const_cast<aclTensor*>( | 1393 | outTensor = const_cast<aclTensor*>( |
| 1200 | l0op::TransDataSpecial(formatTensor, dstTensor->GetStorageFormat(), 1, uniqueExecutor.get())); | 1394 | l0op::TransDataSpecial(formatTensor, dstTensor->GetStorageFormat(), 1, uniqueExecutor.get())); |
| 1201 | } else { | 1395 | } else { |
| @@ -1204,9 +1398,25 @@ aclnnStatus aclnnNpuFormatCastGetWorkspaceSize(const aclTensor* srcTensor, aclTe | |||
| 1204 | } | 1398 | } |
| 1205 | CHECK_RET(outTensor != nullptr, ACLNN_ERR_INNER_NULLPTR); | 1399 | CHECK_RET(outTensor != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 1206 | outTensor->SetViewFormat(dstTensor->GetViewFormat()); | 1400 | outTensor->SetViewFormat(dstTensor->GetViewFormat()); |
| 1401 | + outTensor->SetViewShape(dstTensor->GetViewShape()); | ||
| 1207 | outTensor->SetOriginalFormat(dstTensor->GetOriginalFormat()); | 1402 | outTensor->SetOriginalFormat(dstTensor->GetOriginalFormat()); |
| 1403 | + outTensor->SetOriginalShape(dstTensor->GetOriginalShape()); | ||
| 1208 | outTensor->SetStorageFormat(dstTensor->GetStorageFormat()); | 1404 | outTensor->SetStorageFormat(dstTensor->GetStorageFormat()); |
| 1209 | - auto viewCopyResult = l0op::ViewCopy(outTensor, dstTensor, uniqueExecutor.get()); | 1405 | + outTensor->SetStorageShape(dstTensor->GetStorageShape()); |
| 1406 | + aclTensor* dstCopyTensor = dstTensor; | ||
| 1407 | + if (isFloat8E8m0Nn) { | ||
| 1408 | + dstCopyTensor = uniqueExecutor.get()->CreateView(dstTensor, dstTensor->GetViewShape(), | ||
| 1409 | + dstTensor->GetViewOffset()); | ||
| 1410 | + CHECK_RET(dstCopyTensor != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 1411 | + dstCopyTensor->SetDataType(op::DataType::DT_INT8); | ||
| 1412 | + dstCopyTensor->SetViewFormat(dstTensor->GetViewFormat()); | ||
| 1413 | + dstCopyTensor->SetViewShape(dstTensor->GetViewShape()); | ||
| 1414 | + dstCopyTensor->SetOriginalFormat(dstTensor->GetOriginalFormat()); | ||
| 1415 | + dstCopyTensor->SetOriginalShape(dstTensor->GetOriginalShape()); | ||
| 1416 | + dstCopyTensor->SetStorageFormat(dstTensor->GetStorageFormat()); | ||
| 1417 | + dstCopyTensor->SetStorageShape(dstTensor->GetStorageShape()); | ||
| 1418 | + } | ||
| 1419 | + auto viewCopyResult = l0op::ViewCopy(outTensor, dstCopyTensor, uniqueExecutor.get()); | ||
| 1210 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | 1420 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 1211 | 1421 | ||
| 1212 | // 固定写法,获取计算过程中需要使用的workspace大小 | 1422 | // 固定写法,获取计算过程中需要使用的workspace大小 |
| @@ -23,15 +23,17 @@ extern "C" { | |||
| 23 | * @brief aclnnNpuFormatCast的第一段接口,用于获取计算所需workspace大小以及包含了算子计算流程的执行器。 | 23 | * @brief aclnnNpuFormatCast的第一段接口,用于获取计算所需workspace大小以及包含了算子计算流程的执行器。 |
| 24 | * @domain aclnn_ops_infer | 24 | * @domain aclnn_ops_infer |
| 25 | * @param [in] srcTensor: | 25 | * @param [in] srcTensor: |
| 26 | - * 输入的数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_2(52)、ACL_FORMAT_FRACTAL_NZ_C0_4(53)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。不支持非连续的Tensor, 支持的数据类型:FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT。 | 26 | + * 输入的数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_2(52)、ACL_FORMAT_FRACTAL_NZ_C0_4(53)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。不支持非连续的Tensor, |
| 27 | + * 支持的数据类型:FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT、FLOAT8_E8M0。其中FLOAT8_E8M0仅支持ND到FRACTAL_NZ的MX | ||
| 28 | + * scale昇腾亲和格式转换场景。 | ||
| 27 | * @param [in] | 29 | * @param [in] |
| 28 | * dstTensor:转换后的目标数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。数据类型支持FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT。 | 30 | * dstTensor:转换后的目标数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。数据类型支持FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT。 |
| 29 | * @param [in] workspaceSize:需要在Device侧申请的workspace的大小。 | 31 | * @param [in] workspaceSize:需要在Device侧申请的workspace的大小。 |
| 30 | * @param [in] executor:包含算子计算流程的op执行器。 | 32 | * @param [in] executor:包含算子计算流程的op执行器。 |
| 31 | * @return aclnnStatus: 返回状态码 | 33 | * @return aclnnStatus: 返回状态码 |
| 32 | */ | 34 | */ |
| 33 | -ACLNN_API aclnnStatus aclnnNpuFormatCastGetWorkspaceSize( | 35 | +ACLNN_API aclnnStatus aclnnNpuFormatCastGetWorkspaceSize(const aclTensor* srcTensor, aclTensor* dstTensor, |
| 34 | - const aclTensor* srcTensor, aclTensor* dstTensor, uint64_t* workspaceSize, aclOpExecutor** executor); | 36 | + uint64_t* workspaceSize, aclOpExecutor** executor); |
| 35 | 37 | ||
| 36 | /** | 38 | /** |
| 37 | * @brief aclnnNpuFormatCast的第二段接口,用于执行计算。 | 39 | * @brief aclnnNpuFormatCast的第二段接口,用于执行计算。 |
| @@ -42,16 +44,17 @@ ACLNN_API aclnnStatus aclnnNpuFormatCastGetWorkspaceSize( | |||
| 42 | * @return aclnnStatus: 返回状态码 | 44 | * @return aclnnStatus: 返回状态码 |
| 43 | */ | 45 | */ |
| 44 | 46 | ||
| 45 | -ACLNN_API aclnnStatus | 47 | +ACLNN_API aclnnStatus aclnnNpuFormatCast(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, |
| 46 | -aclnnNpuFormatCast(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream); | 48 | + aclrtStream stream); |
| 47 | 49 | ||
| 48 | /** | 50 | /** |
| 49 | * @brief 用于计算转换目标数据的shape和数据格式 | 51 | * @brief 用于计算转换目标数据的shape和数据格式 |
| 50 | - * @param [in] srcTensor: | 52 | + * @param [in] srcTensor: |
| 51 | - * 输入的数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_2(52)、ACL_FORMAT_FRACTAL_NZ_C0_4(53)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。支持的数据类型:FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT。 | 53 | + * 输入的数据,数据格式支持ND、ACL_FORMAT_FRACTAL_NZ(29)、ACL_FORMAT_FRACTAL_NZ_C0_2(52)、ACL_FORMAT_FRACTAL_NZ_C0_4(53)、ACL_FORMAT_FRACTAL_NZ_C0_16(50)、ACL_FORMAT_FRACTAL_NZ_C0_32(51)。支持的数据类型:FLOAT4_E2M1、INT8、UINT8、INT32、FLOAT16、BFLOAT16、FLOAT、FLOAT8_E8M0。其中FLOAT8_E8M0仅支持ND到FRACTAL_NZ的MX |
| 54 | + * scale昇腾亲和格式转换场景。 | ||
| 52 | * @param [in] dstFormat: 转换的目标数据格式。支持的数据格式:ND、ACL_FORMAT_FRACTAL_NZ(29)。 | 55 | * @param [in] dstFormat: 转换的目标数据格式。支持的数据格式:ND、ACL_FORMAT_FRACTAL_NZ(29)。 |
| 53 | * @param [in] additionalDtype: | 56 | * @param [in] additionalDtype: |
| 54 | - * 转换成NZ格式推断C0大小时,使用的数据类型的枚举值。支持的数据类型:ACL_FLOAT16(1)、ACL_BF16(27)、INT8(2)、ACL_FLOAT(0)。 | 57 | + * 转换成NZ格式推断C0大小时,使用的数据类型的枚举值。支持的数据类型:ACL_FLOAT16(1)、ACL_BF16(27)、INT8(2)、ACL_FLOAT(0)、ACL_FLOAT8_E8M0。 |
| 55 | * @param [in] dstShape: 指向目标数组Shape数组的指针,在非报错场景下指向的内存由调用者释放。 | 58 | * @param [in] dstShape: 指向目标数组Shape数组的指针,在非报错场景下指向的内存由调用者释放。 |
| 56 | * @param [in] dstShapeSize: 指向目标数据Shape数组的大小的指针。 | 59 | * @param [in] dstShapeSize: 指向目标数据Shape数组的大小的指针。 |
| 57 | * @param [in] actualFormat: | 60 | * @param [in] actualFormat: |
| @@ -59,12 +62,12 @@ aclnnNpuFormatCast(void* workspace, uint64_t workspaceSize, aclOpExecutor* execu | |||
| 59 | * @return aclnnStatus: 返回状态码 | 62 | * @return aclnnStatus: 返回状态码 |
| 60 | */ | 63 | */ |
| 61 | 64 | ||
| 62 | -ACLNN_API aclnnStatus aclnnNpuFormatCastCalculateSizeAndFormat( | 65 | +ACLNN_API aclnnStatus aclnnNpuFormatCastCalculateSizeAndFormat(const aclTensor* srcTensor, const int dstFormat, |
| 63 | - const aclTensor* srcTensor, const int dstFormat, int additionalDtype, int64_t** dstShape, | 66 | + int additionalDtype, int64_t** dstShape, |
| 64 | - uint64_t* dstShapeSize, int* actualFormat); | 67 | + uint64_t* dstShapeSize, int* actualFormat); |
| 65 | 68 | ||
| 66 | #ifdef __cplusplus | 69 | #ifdef __cplusplus |
| 67 | } | 70 | } |
| 68 | #endif | 71 | #endif |
| 69 | 72 | ||
| 70 | -#endif // OP_API_INC_NPU_FORMAT_CAST_H_ | 73 | +#endif // OP_API_INC_NPU_FORMAT_CAST_H_ |
| @@ -45,30 +45,16 @@ struct NpuFormatCastTestParam { | |||
| 45 | aclnnStatus expectRet; | 45 | aclnnStatus expectRet; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | -class l2_npu_format_cast_test_950 : public testing::TestWithParam<NpuFormatCastTestParam> | 48 | +class l2_npu_format_cast_test_950 : public testing::TestWithParam<NpuFormatCastTestParam> { |
| 49 | -{ | ||
| 50 | protected: | 49 | protected: |
| 51 | - static void SetUpTestCase() | 50 | + static void SetUpTestCase() { cout << "l2_npu_format_cast_test_950 SetUp" << endl; } |
| 52 | - { | 51 | + static void TearDownTestCase() { cout << "l2_npu_format_cast_test_950 S" << endl; } |
| 53 | - cout << "l2_npu_format_cast_test_950 SetUp" << endl; | ||
| 54 | - } | ||
| 55 | - static void TearDownTestCase() | ||
| 56 | - { | ||
| 57 | - cout << "l2_npu_format_cast_test_950 S" << endl; | ||
| 58 | - } | ||
| 59 | }; | 52 | }; |
| 60 | 53 | ||
| 61 | -class l2_npu_format_cast_test_910_93 : public testing::TestWithParam<NpuFormatCastTestParam> | 54 | +class l2_npu_format_cast_test_910_93 : public testing::TestWithParam<NpuFormatCastTestParam> { |
| 62 | -{ | ||
| 63 | protected: | 55 | protected: |
| 64 | - static void SetUpTestCase() | 56 | + static void SetUpTestCase() { cout << "l2_npu_format_cast_test_910_93 SetUp" << endl; } |
| 65 | - { | 57 | + static void TearDownTestCase() { cout << "l2_npu_format_cast_test_910_93 S" << endl; } |
| 66 | - cout << "l2_npu_format_cast_test_910_93 SetUp" << endl; | ||
| 67 | - } | ||
| 68 | - static void TearDownTestCase() | ||
| 69 | - { | ||
| 70 | - cout << "l2_npu_format_cast_test_910_93 S" << endl; | ||
| 71 | - } | ||
| 72 | }; | 58 | }; |
| 73 | 59 | ||
| 74 | static void TestOneParamCase(const NpuFormatCastTestParam& param) | 60 | static void TestOneParamCase(const NpuFormatCastTestParam& param) |
| @@ -81,9 +67,9 @@ static void TestOneParamCase(const NpuFormatCastTestParam& param) | |||
| 81 | strides[i] = param.srcTensor[i + 1] * strides[i + 1]; | 67 | strides[i] = param.srcTensor[i + 1] * strides[i + 1]; |
| 82 | } | 68 | } |
| 83 | 69 | ||
| 84 | - aclTensor* srctensor = aclCreateTensor( | 70 | + aclTensor* srctensor = aclCreateTensor(param.srcTensor.data(), param.srcTensor.size(), param.srcDtype, |
| 85 | - param.srcTensor.data(), param.srcTensor.size(), param.srcDtype, strides.data(), 0, param.srcFormat, | 71 | + strides.data(), 0, param.srcFormat, param.storageShape.data(), |
| 86 | - param.storageShape.data(), param.storageShape.size(), srcDeviceAddr); | 72 | + param.storageShape.size(), srcDeviceAddr); |
| 87 | 73 | ||
| 88 | const int AdditionalDtype = param.additionalDtype; | 74 | const int AdditionalDtype = param.additionalDtype; |
| 89 | int dstFormat = static_cast<int>(param.dstFormat); | 75 | int dstFormat = static_cast<int>(param.dstFormat); |
| @@ -92,18 +78,17 @@ static void TestOneParamCase(const NpuFormatCastTestParam& param) | |||
| 92 | int ActualFormat = 0; | 78 | int ActualFormat = 0; |
| 93 | 79 | ||
| 94 | // dstformat支持FRACTAL_NZ(用29表示)或ND(用2表示) | 80 | // dstformat支持FRACTAL_NZ(用29表示)或ND(用2表示) |
| 95 | - auto ret = aclnnNpuFormatCastCalculateSizeAndFormat( | 81 | + auto ret = aclnnNpuFormatCastCalculateSizeAndFormat(srctensor, dstFormat, AdditionalDtype, &DstShape, &DstShapeSize, |
| 96 | - srctensor, dstFormat, AdditionalDtype, &DstShape, &DstShapeSize, | 82 | + &ActualFormat); // 参数待修改 |
| 97 | - &ActualFormat); // 参数待修改 | ||
| 98 | 83 | ||
| 99 | if (ret != ACL_SUCCESS) { | 84 | if (ret != ACL_SUCCESS) { |
| 100 | LOG_PRINT("aclnnNpuFormatCastCalculateSizeAndFormat failed. ERROR: %d\n", ret); | 85 | LOG_PRINT("aclnnNpuFormatCastCalculateSizeAndFormat failed. ERROR: %d\n", ret); |
| 101 | EXPECT_EQ(ret, param.expectRet); | 86 | EXPECT_EQ(ret, param.expectRet); |
| 102 | return; | 87 | return; |
| 103 | } | 88 | } |
| 104 | - aclTensor* dsttensor = aclCreateTensor( | 89 | + aclTensor* dsttensor = aclCreateTensor(param.srcTensor.data(), param.srcTensor.size(), param.srcDtype, |
| 105 | - param.srcTensor.data(), param.srcTensor.size(), param.srcDtype, strides.data(), 0, | 90 | + strides.data(), 0, static_cast<aclFormat>(ActualFormat), DstShape, |
| 106 | - static_cast<aclFormat>(ActualFormat), DstShape, DstShapeSize, dstDeviceAddr); | 91 | + DstShapeSize, dstDeviceAddr); |
| 107 | 92 | ||
| 108 | uint64_t workspaceSize = 0U; | 93 | uint64_t workspaceSize = 0U; |
| 109 | aclOpExecutor* exe = nullptr; | 94 | aclOpExecutor* exe = nullptr; |
| @@ -262,6 +247,38 @@ static NpuFormatCastTestParam casesParamsAscend950[] = { | |||
| 262 | ACL_FORMAT_FRACTAL_NZ, | 247 | ACL_FORMAT_FRACTAL_NZ, |
| 263 | ACL_FLOAT8_E4M3FN, | 248 | ACL_FLOAT8_E4M3FN, |
| 264 | ACLNN_SUCCESS}, | 249 | ACLNN_SUCCESS}, |
| 250 | + {"ascend950_test_NpuformatCast_scale_float8_e8m0_ND_Nn_4D", | ||
| 251 | + {48, 24, 4096, 2}, | ||
| 252 | + {48, 24, 4096, 2}, | ||
| 253 | + ACL_FLOAT8_E8M0, | ||
| 254 | + ACL_FORMAT_ND, | ||
| 255 | + ACL_FORMAT_FRACTAL_NZ, | ||
| 256 | + ACL_FLOAT8_E8M0, | ||
| 257 | + ACLNN_SUCCESS}, | ||
| 258 | + {"ascend950_test_NpuformatCast_scale_float8_e8m0_ND_Nn_3D", | ||
| 259 | + {24, 4096, 2}, | ||
| 260 | + {24, 4096, 2}, | ||
| 261 | + ACL_FLOAT8_E8M0, | ||
| 262 | + ACL_FORMAT_ND, | ||
| 263 | + ACL_FORMAT_FRACTAL_NZ, | ||
| 264 | + ACL_FLOAT8_E8M0, | ||
| 265 | + ACLNN_SUCCESS}, | ||
| 266 | + {"ascend950_test_NpuformatCast_scale_float8_e8m0_ND_Nn_N_Not_Align", | ||
| 267 | + {48, 24, 4097, 2}, | ||
| 268 | + {48, 24, 4097, 2}, | ||
| 269 | + ACL_FLOAT8_E8M0, | ||
| 270 | + ACL_FORMAT_ND, | ||
| 271 | + ACL_FORMAT_FRACTAL_NZ, | ||
| 272 | + ACL_FLOAT8_E8M0, | ||
| 273 | + ACLNN_SUCCESS}, | ||
| 274 | + {"ascend950_test_NpuformatCast_scale_float8_e8m0_NCHW_Nn_N_Not_Align", | ||
| 275 | + {5, 1, 29, 2}, | ||
| 276 | + {5, 1, 29, 2}, | ||
| 277 | + ACL_FLOAT8_E8M0, | ||
| 278 | + ACL_FORMAT_NCHW, | ||
| 279 | + ACL_FORMAT_FRACTAL_NZ, | ||
| 280 | + ACL_FLOAT8_E8M0, | ||
| 281 | + ACLNN_SUCCESS}, | ||
| 265 | {"ascend950_test_NpuformatCast_NZ_ND_B4", | 282 | {"ascend950_test_NpuformatCast_NZ_ND_B4", |
| 266 | {64, 128}, | 283 | {64, 128}, |
| 267 | {2, 4, 16, 64}, | 284 | {2, 4, 16, 64}, |
| @@ -632,11 +649,10 @@ static NpuFormatCastTestParam casesParamsAscend910_93[] = { | |||
| 632 | ACLNN_ERR_PARAM_INVALID}, | 649 | ACLNN_ERR_PARAM_INVALID}, |
| 633 | }; | 650 | }; |
| 634 | 651 | ||
| 635 | -INSTANTIATE_TEST_SUITE_P( | 652 | +INSTANTIATE_TEST_SUITE_P(Ascend950_NpuFormatCast, l2_npu_format_cast_test_950, testing::ValuesIn(casesParamsAscend950)); |
| 636 | - Ascend950_NpuFormatCast, l2_npu_format_cast_test_950, testing::ValuesIn(casesParamsAscend950)); | ||
| 637 | 653 | ||
| 638 | -INSTANTIATE_TEST_SUITE_P( | 654 | +INSTANTIATE_TEST_SUITE_P(Ascend910_93_NpuFormatCast, l2_npu_format_cast_test_910_93, |
| 639 | - Ascend910_93_NpuFormatCast, l2_npu_format_cast_test_910_93, testing::ValuesIn(casesParamsAscend910_93)); | 655 | + testing::ValuesIn(casesParamsAscend910_93)); |
| 640 | 656 | ||
| 641 | static void ThreadFunc(const NpuFormatCastTestParam* params, size_t testcase_num, size_t thread_idx, size_t thread_num) | 657 | static void ThreadFunc(const NpuFormatCastTestParam* params, size_t testcase_num, size_t thread_idx, size_t thread_num) |
| 642 | { | 658 | { |
| @@ -665,4 +681,4 @@ TEST_F(l2_npu_format_cast_test_950, ascend950_multi_thread) | |||
| 665 | TEST_F(l2_npu_format_cast_test_910_93, ascend910_93_multi_thread) | 681 | TEST_F(l2_npu_format_cast_test_910_93, ascend910_93_multi_thread) |
| 666 | { | 682 | { |
| 667 | TestMultiThread(casesParamsAscend910_93, sizeof(casesParamsAscend910_93) / sizeof(NpuFormatCastTestParam), 3); | 683 | TestMultiThread(casesParamsAscend910_93, sizeof(casesParamsAscend910_93) / sizeof(NpuFormatCastTestParam), 3); |
| 668 | -} | 684 | +} |