已合并
fix: 删除reduce算子无用的CMAKE文件 #984
RuiWang_创建于 1月28日
fix: 删除reduce算子无用的CMAKE文件 #984
已合并
共 109 个文件变更+1800-7893
| @@ -524,7 +524,6 @@ macro(add_all_modules_sources) | |||
| 524 | if(OP_GRAPH_PROTO_HEADERS) | 524 | if(OP_GRAPH_PROTO_HEADERS) |
| 525 | target_sources(${GRAPH_PLUGIN_NAME}_proto_headers INTERFACE ${OP_GRAPH_PROTO_HEADERS}) | 525 | target_sources(${GRAPH_PLUGIN_NAME}_proto_headers INTERFACE ${OP_GRAPH_PROTO_HEADERS}) |
| 526 | endif() | 526 | endif() |
| 527 | - add_all_ut_sources(UT_TILING_DIR "${TILING_SOC_DIR}" OP_NAME ${OP_NAME}) | ||
| 528 | 527 | ||
| 529 | #添加plugin文件 | 528 | #添加plugin文件 |
| 530 | file(GLOB ONNX_PLUGIN_SRCS ${SOURCE_DIR}/framework/*_onnx_plugin.cpp) | 529 | file(GLOB ONNX_PLUGIN_SRCS ${SOURCE_DIR}/framework/*_onnx_plugin.cpp) |
| @@ -532,6 +531,9 @@ macro(add_all_modules_sources) | |||
| 532 | add_onnx_plugin_modules() | 531 | add_onnx_plugin_modules() |
| 533 | target_sources(${ONNX_PLUGIN_NAME}_obj PRIVATE ${ONNX_PLUGIN_SRCS}) | 532 | target_sources(${ONNX_PLUGIN_NAME}_obj PRIVATE ${ONNX_PLUGIN_SRCS}) |
| 534 | endif() | 533 | endif() |
| 534 | + | ||
| 535 | + # 添加所有的UT | ||
| 536 | + add_all_ut_sources(UT_TILING_DIR "${TILING_SOC_DIR}" OP_NAME ${OP_NAME}) | ||
| 535 | endmacro() | 537 | endmacro() |
| 536 | 538 | ||
| 537 | # usage: add_all_ut_sources() | 539 | # usage: add_all_ut_sources() |
| @@ -32,14 +32,15 @@ | |||
| 32 | using namespace op; | 32 | using namespace op; |
| 33 | using std::bitset; | 33 | using std::bitset; |
| 34 | 34 | ||
| 35 | -static const aclIntArray* getAllDims(const aclTensor* self, aclOpExecutor* executor) { | 35 | +static const aclIntArray* getAllDims(const aclTensor* self, aclOpExecutor* executor) |
| 36 | - auto input_shape = self->GetViewShape(); | 36 | +{ |
| 37 | - const size_t input_dim_num = input_shape.GetDimNum(); | 37 | + auto input_shape = self->GetViewShape(); |
| 38 | - std::vector<int64_t> dims(input_dim_num); | 38 | + const size_t input_dim_num = input_shape.GetDimNum(); |
| 39 | - for (size_t idx = 0; idx < input_dim_num; idx++) { | 39 | + std::vector<int64_t> dims(input_dim_num); |
| 40 | - dims[idx] = idx; | 40 | + for (size_t idx = 0; idx < input_dim_num; idx++) { |
| 41 | - } | 41 | + dims[idx] = idx; |
| 42 | - return executor->AllocIntArray(dims.data(), input_dim_num); | 42 | + } |
| 43 | + return executor->AllocIntArray(dims.data(), input_dim_num); | ||
| 43 | } | 44 | } |
| 44 | 45 | ||
| 45 | static const std::initializer_list<DataType> Ascend910_self_dtype_support_list = { | 46 | static const std::initializer_list<DataType> Ascend910_self_dtype_support_list = { |
| @@ -52,68 +53,72 @@ static const std::initializer_list<DataType> Ascend910B_self_dtype_support_list | |||
| 52 | op::DataType::DT_INT16, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_BOOL, | 53 | op::DataType::DT_INT16, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_BOOL, |
| 53 | op::DataType::DT_DOUBLE, op::DataType::DT_BF16}; | 54 | op::DataType::DT_DOUBLE, op::DataType::DT_BF16}; |
| 54 | 55 | ||
| 55 | -static const std::initializer_list<DataType>& GetSelfDtypeSupportList() { | 56 | +static const std::initializer_list<DataType>& GetSelfDtypeSupportList() |
| 56 | - if (GetCurrentPlatformInfo().GetSocVersion() == SocVersion::ASCEND910B || | 57 | +{ |
| 57 | - GetCurrentPlatformInfo().GetSocVersion() == SocVersion::ASCEND910_93 || | 58 | + if (GetCurrentPlatformInfo().GetSocVersion() == SocVersion::ASCEND910B || |
| 58 | - IsRegBase()) { | 59 | + GetCurrentPlatformInfo().GetSocVersion() == SocVersion::ASCEND910_93 || IsRegBase()) { |
| 59 | - return Ascend910B_self_dtype_support_list; | 60 | + return Ascend910B_self_dtype_support_list; |
| 60 | - } | 61 | + } |
| 61 | - return Ascend910_self_dtype_support_list; | 62 | + return Ascend910_self_dtype_support_list; |
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | static const std::initializer_list<DataType> out_dtype_support_list = {op::DataType::DT_UINT8, op::DataType::DT_BOOL}; | 65 | static const std::initializer_list<DataType> out_dtype_support_list = {op::DataType::DT_UINT8, op::DataType::DT_BOOL}; |
| 65 | 66 | ||
| 66 | -static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) { | 67 | +static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) |
| 67 | - if (dimNum <= 0) { | 68 | +{ |
| 68 | - dimNum = 1; | 69 | + if (dimNum <= 0) { |
| 69 | - } | 70 | + dimNum = 1; |
| 70 | - return dim >= 0 ? dim : dim + dimNum; | ||
| 71 | -} | ||
| 72 | - | ||
| 73 | -int64_t make_wrap_dim(int64_t dim, int64_t dim_post_expr) { | ||
| 74 | - // this will make range [-1, 0] | ||
| 75 | - if (dim_post_expr <= 0) { | ||
| 76 | - dim_post_expr = 1; | ||
| 77 | - } | ||
| 78 | - if (dim < 0) { | ||
| 79 | - dim += dim_post_expr; | ||
| 80 | - } | ||
| 81 | - return dim; | ||
| 82 | -} | ||
| 83 | - | ||
| 84 | -static bitset<DIM_BITS_LEN> make_dim_mask(const op::FVector<int64_t, op::MAX_DIM_NUM>& dims, int64_t ndim) { | ||
| 85 | - bitset<DIM_BITS_LEN> mask = bitset<DIM_BITS_LEN>(); | ||
| 86 | - if (dims.empty()) { | ||
| 87 | - mask.flip(); | ||
| 88 | - } else { | ||
| 89 | - for (int64_t dim : dims) { | ||
| 90 | - mask.set(make_wrap_dim(dim, ndim)); | ||
| 91 | } | 71 | } |
| 92 | - } | 72 | + return dim >= 0 ? dim : dim + dimNum; |
| 93 | - return mask; | 73 | +} |
| 74 | + | ||
| 75 | +int64_t make_wrap_dim(int64_t dim, int64_t dim_post_expr) | ||
| 76 | +{ | ||
| 77 | + // this will make range [-1, 0] | ||
| 78 | + if (dim_post_expr <= 0) { | ||
| 79 | + dim_post_expr = 1; | ||
| 80 | + } | ||
| 81 | + if (dim < 0) { | ||
| 82 | + dim += dim_post_expr; | ||
| 83 | + } | ||
| 84 | + return dim; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +static bitset<DIM_BITS_LEN> make_dim_mask(const op::FVector<int64_t, op::MAX_DIM_NUM>& dims, int64_t ndim) | ||
| 88 | +{ | ||
| 89 | + bitset<DIM_BITS_LEN> mask = bitset<DIM_BITS_LEN>(); | ||
| 90 | + if (dims.empty()) { | ||
| 91 | + mask.flip(); | ||
| 92 | + } else { | ||
| 93 | + for (int64_t dim : dims) { | ||
| 94 | + mask.set(make_wrap_dim(dim, ndim)); | ||
| 95 | + } | ||
| 96 | + } | ||
| 97 | + return mask; | ||
| 94 | } | 98 | } |
| 95 | 99 | ||
| 96 | static op::FVector<int64_t, op::MAX_DIM_NUM> reduce_ops_npu_output_size( | 100 | static op::FVector<int64_t, op::MAX_DIM_NUM> reduce_ops_npu_output_size( |
| 97 | - const aclTensor* self, const op::FVector<int64_t, op::MAX_DIM_NUM>& dim, bool keepdim) { | 101 | + const aclTensor* self, const op::FVector<int64_t, op::MAX_DIM_NUM>& dim, bool keepdim) |
| 98 | - auto self_shape = self->GetViewShape(); | 102 | +{ |
| 99 | - int64_t ndim = self->GetViewShape().GetDimNum(); | 103 | + auto self_shape = self->GetViewShape(); |
| 100 | - bitset<DIM_BITS_LEN> mask = make_dim_mask(dim, ndim); | 104 | + int64_t ndim = self->GetViewShape().GetDimNum(); |
| 101 | - op::FVector<int64_t, op::MAX_DIM_NUM> shape; | 105 | + bitset<DIM_BITS_LEN> mask = make_dim_mask(dim, ndim); |
| 102 | - for (size_t i = 0; i < self_shape.GetDimNum(); i++) { | 106 | + op::FVector<int64_t, op::MAX_DIM_NUM> shape; |
| 103 | - shape.push_back(self_shape.GetDim(i)); | 107 | + for (size_t i = 0; i < self_shape.GetDimNum(); i++) { |
| 104 | - } | 108 | + shape.push_back(self_shape.GetDim(i)); |
| 105 | - | ||
| 106 | - for (int idx = shape.size() - 1; idx >= 0; idx--) { | ||
| 107 | - if (mask[idx]) { | ||
| 108 | - if (keepdim) { | ||
| 109 | - shape[idx] = 1; | ||
| 110 | - } else { | ||
| 111 | - shape.erase(shape.begin() + idx); | ||
| 112 | - } | ||
| 113 | } | 109 | } |
| 114 | - } | ||
| 115 | 110 | ||
| 116 | - return shape; | 111 | + for (int idx = shape.size() - 1; idx >= 0; idx--) { |
| 112 | + if (mask[idx]) { | ||
| 113 | + if (keepdim) { | ||
| 114 | + shape[idx] = 1; | ||
| 115 | + } else { | ||
| 116 | + shape.erase(shape.begin() + idx); | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + return shape; | ||
| 117 | } | 122 | } |
| 118 | 123 | ||
| 119 | /** | 124 | /** |
| @@ -124,57 +129,64 @@ static op::FVector<int64_t, op::MAX_DIM_NUM> reduce_ops_npu_output_size( | |||
| 124 | * @param keepdim 输出维度是否与输入维度保持一致 | 129 | * @param keepdim 输出维度是否与输入维度保持一致 |
| 125 | * @return 输出tensor的shape | 130 | * @return 输出tensor的shape |
| 126 | */ | 131 | */ |
| 127 | -static op::Shape output_shape(const aclTensor* self, const op::FVector<int64_t, op::MAX_DIM_NUM>& dim, bool keepdim) { | 132 | +static op::Shape output_shape(const aclTensor* self, const op::FVector<int64_t, op::MAX_DIM_NUM>& dim, bool keepdim) |
| 128 | - op::Shape outShape; | 133 | +{ |
| 129 | - auto dims = reduce_ops_npu_output_size(self, dim, keepdim); | 134 | + op::Shape outShape; |
| 130 | - outShape.SetDimNum(dims.size()); | 135 | + auto dims = reduce_ops_npu_output_size(self, dim, keepdim); |
| 131 | - for (size_t i = 0; i < dims.size(); i++) { | 136 | + outShape.SetDimNum(dims.size()); |
| 132 | - outShape.SetDim(i, dims.at(i)); | 137 | + for (size_t i = 0; i < dims.size(); i++) { |
| 133 | - } | 138 | + outShape.SetDim(i, dims.at(i)); |
| 134 | - return outShape; | 139 | + } |
| 140 | + return outShape; | ||
| 135 | } | 141 | } |
| 136 | 142 | ||
| 137 | -static bool CheckNotNull(const aclTensor* self, const aclIntArray* dim, const aclTensor* out) { | 143 | +static bool CheckNotNull(const aclTensor* self, const aclIntArray* dim, const aclTensor* out) |
| 138 | - OP_CHECK_NULL(self, return false); | 144 | +{ |
| 139 | - OP_CHECK_NULL(dim, return false); | 145 | + OP_CHECK_NULL(self, return false); |
| 140 | - OP_CHECK_NULL(out, return false); | 146 | + OP_CHECK_NULL(dim, return false); |
| 141 | - return true; | 147 | + OP_CHECK_NULL(out, return false); |
| 142 | -} | ||
| 143 | - | ||
| 144 | -static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) { | ||
| 145 | - // 检查self的数据类型是否在支持列表内 | ||
| 146 | - OP_CHECK_DTYPE_NOT_SUPPORT(self, GetSelfDtypeSupportList(), return false); | ||
| 147 | - | ||
| 148 | - // 检查out的数据类型是否在支持列表内 | ||
| 149 | - OP_CHECK_DTYPE_NOT_SUPPORT(out, out_dtype_support_list, return false); | ||
| 150 | - return true; | ||
| 151 | -} | ||
| 152 | - | ||
| 153 | -static bool CheckFormat(const aclTensor* self) { | ||
| 154 | - if (op::IsPrivateFormat(self->GetStorageFormat())) { | ||
| 155 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Format only support ND、NCHW、NHWC、HWCN、NDHWC、NCDHW, self [%s]", | ||
| 156 | - ToString(self->GetStorageFormat()).GetString()); | ||
| 157 | - return false; | ||
| 158 | - } | ||
| 159 | - | ||
| 160 | - return true; | ||
| 161 | -} | ||
| 162 | - | ||
| 163 | -static bool CheckShape(const aclTensor* self, const aclTensor* out, const aclIntArray* dim, bool keepdim) { | ||
| 164 | - OP_CHECK_MAX_DIM(self, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 165 | - OP_CHECK_MAX_DIM(out, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 166 | - | ||
| 167 | - op::FVector<int64_t, op::MAX_DIM_NUM> dims; | ||
| 168 | - for (size_t idx = 0; idx < dim->Size(); idx++) { | ||
| 169 | - dims.emplace_back((*dim)[idx]); | ||
| 170 | - } | ||
| 171 | - auto outShape = output_shape(self, dims, keepdim); | ||
| 172 | - if (outShape == out->GetViewShape()) { | ||
| 173 | return true; | 148 | return true; |
| 174 | - } | 149 | +} |
| 175 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expect out shape [%s], but got: [%s].", op::ToString(outShape).GetString(), | 150 | + |
| 176 | - op::ToString(out->GetViewShape()).GetString()); | 151 | +static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) |
| 177 | - return false; | 152 | +{ |
| 153 | + // 检查self的数据类型是否在支持列表内 | ||
| 154 | + OP_CHECK_DTYPE_NOT_SUPPORT(self, GetSelfDtypeSupportList(), return false); | ||
| 155 | + | ||
| 156 | + // 检查out的数据类型是否在支持列表内 | ||
| 157 | + OP_CHECK_DTYPE_NOT_SUPPORT(out, out_dtype_support_list, return false); | ||
| 158 | + return true; | ||
| 159 | +} | ||
| 160 | + | ||
| 161 | +static bool CheckFormat(const aclTensor* self) | ||
| 162 | +{ | ||
| 163 | + if (op::IsPrivateFormat(self->GetStorageFormat())) { | ||
| 164 | + OP_LOGE( | ||
| 165 | + ACLNN_ERR_PARAM_INVALID, "Format only support ND、NCHW、NHWC、HWCN、NDHWC、NCDHW, self [%s]", | ||
| 166 | + ToString(self->GetStorageFormat()).GetString()); | ||
| 167 | + return false; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + return true; | ||
| 171 | +} | ||
| 172 | + | ||
| 173 | +static bool CheckShape(const aclTensor* self, const aclTensor* out, const aclIntArray* dim, bool keepdim) | ||
| 174 | +{ | ||
| 175 | + OP_CHECK_MAX_DIM(self, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 176 | + OP_CHECK_MAX_DIM(out, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 177 | + | ||
| 178 | + op::FVector<int64_t, op::MAX_DIM_NUM> dims; | ||
| 179 | + for (size_t idx = 0; idx < dim->Size(); idx++) { | ||
| 180 | + dims.emplace_back((*dim)[idx]); | ||
| 181 | + } | ||
| 182 | + auto outShape = output_shape(self, dims, keepdim); | ||
| 183 | + if (outShape == out->GetViewShape()) { | ||
| 184 | + return true; | ||
| 185 | + } | ||
| 186 | + OP_LOGE( | ||
| 187 | + ACLNN_ERR_PARAM_INVALID, "Expect out shape [%s], but got: [%s].", op::ToString(outShape).GetString(), | ||
| 188 | + op::ToString(out->GetViewShape()).GetString()); | ||
| 189 | + return false; | ||
| 178 | } | 190 | } |
| 179 | 191 | ||
| 180 | /** | 192 | /** |
| @@ -184,119 +196,126 @@ static bool CheckShape(const aclTensor* self, const aclTensor* out, const aclInt | |||
| 184 | * @param dim | 196 | * @param dim |
| 185 | * @return | 197 | * @return |
| 186 | */ | 198 | */ |
| 187 | -static bool CheckDim(const aclTensor* self, const aclIntArray* dim) { | 199 | +static bool CheckDim(const aclTensor* self, const aclIntArray* dim) |
| 188 | - auto input_shape = self->GetViewShape(); | 200 | +{ |
| 189 | - int64_t input_dim_num = input_shape.GetDimNum(); | 201 | + auto input_shape = self->GetViewShape(); |
| 190 | - if (input_dim_num == 0) { | 202 | + int64_t input_dim_num = input_shape.GetDimNum(); |
| 191 | - input_dim_num = 1; | 203 | + if (input_dim_num == 0) { |
| 192 | - } | 204 | + input_dim_num = 1; |
| 193 | - bitset<DIM_BITS_LEN> dimMask = bitset<DIM_BITS_LEN>(); | ||
| 194 | - for (size_t idx = 0; idx < dim->Size(); idx++) { | ||
| 195 | - if ((*dim)[idx] < -(input_dim_num) || (*dim)[idx] >= input_dim_num) { | ||
| 196 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dimension out of range (expected to be in range of [-%ld, %ld], but got %ld)", | ||
| 197 | - input_dim_num, input_dim_num - 1, (*dim)[idx]); | ||
| 198 | - return false; | ||
| 199 | } | 205 | } |
| 200 | - uint64_t index = GetPosDim((*dim)[idx], input_dim_num); | 206 | + bitset<DIM_BITS_LEN> dimMask = bitset<DIM_BITS_LEN>(); |
| 201 | - if (dimMask[index]) { | 207 | + for (size_t idx = 0; idx < dim->Size(); idx++) { |
| 202 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | 208 | + if ((*dim)[idx] < -(input_dim_num) || (*dim)[idx] >= input_dim_num) { |
| 203 | - return false; | 209 | + OP_LOGE( |
| 210 | + ACLNN_ERR_PARAM_INVALID, "Dimension out of range (expected to be in range of [-%ld, %ld], but got %ld)", | ||
| 211 | + input_dim_num, input_dim_num - 1, (*dim)[idx]); | ||
| 212 | + return false; | ||
| 213 | + } | ||
| 214 | + uint64_t index = GetPosDim((*dim)[idx], input_dim_num); | ||
| 215 | + if (dimMask[index]) { | ||
| 216 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | ||
| 217 | + return false; | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + dimMask.set(index); | ||
| 204 | } | 221 | } |
| 205 | 222 | ||
| 206 | - dimMask.set(index); | 223 | + return true; |
| 207 | - } | ||
| 208 | - | ||
| 209 | - return true; | ||
| 210 | } | 224 | } |
| 211 | 225 | ||
| 212 | -static aclnnStatus CheckParams(const aclTensor* self, const aclIntArray* dim, bool keepdim, const aclTensor* out) { | 226 | +static aclnnStatus CheckParams(const aclTensor* self, const aclIntArray* dim, bool keepdim, const aclTensor* out) |
| 213 | - // 1. 检查参数是否为空指针 | 227 | +{ |
| 214 | - CHECK_RET(CheckNotNull(self, dim, out), ACLNN_ERR_PARAM_NULLPTR); | 228 | + // 1. 检查参数是否为空指针 |
| 229 | + CHECK_RET(CheckNotNull(self, dim, out), ACLNN_ERR_PARAM_NULLPTR); | ||
| 215 | 230 | ||
| 216 | - // 2. 检查输入的数据类型是否在API支持的数据类型范围之内,需要根据api定义校验 | 231 | + // 2. 检查输入的数据类型是否在API支持的数据类型范围之内,需要根据api定义校验 |
| 217 | - CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); | 232 | + CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); |
| 218 | 233 | ||
| 219 | - // 3. 检查数据格式是否支持 | 234 | + // 3. 检查数据格式是否支持 |
| 220 | - CHECK_RET(CheckFormat(self), ACLNN_ERR_PARAM_INVALID); | 235 | + CHECK_RET(CheckFormat(self), ACLNN_ERR_PARAM_INVALID); |
| 221 | 236 | ||
| 222 | - // 5. 检查dim参数是否在范围内 | 237 | + // 5. 检查dim参数是否在范围内 |
| 223 | - CHECK_RET(CheckDim(self, dim), ACLNN_ERR_PARAM_INVALID); | 238 | + CHECK_RET(CheckDim(self, dim), ACLNN_ERR_PARAM_INVALID); |
| 224 | 239 | ||
| 225 | - // 6. 检查shape是否满足约束 | 240 | + // 6. 检查shape是否满足约束 |
| 226 | - CHECK_RET(CheckShape(self, out, dim, keepdim), ACLNN_ERR_PARAM_INVALID); | 241 | + CHECK_RET(CheckShape(self, out, dim, keepdim), ACLNN_ERR_PARAM_INVALID); |
| 227 | - return ACLNN_SUCCESS; | 242 | + return ACLNN_SUCCESS; |
| 228 | } | 243 | } |
| 229 | 244 | ||
| 230 | -static const aclTensor* GetTensorWithValueTrue(aclTensor* out, aclOpExecutor* executor) { | 245 | +static const aclTensor* GetTensorWithValueTrue(aclTensor* out, aclOpExecutor* executor) |
| 231 | - if (out->IsEmpty()) { | 246 | +{ |
| 232 | - return out; | 247 | + if (out->IsEmpty()) { |
| 233 | - } | 248 | + return out; |
| 234 | - aclScalar* scalar = executor->AllocScalar(1); | 249 | + } |
| 235 | - auto valueTensor = executor->ConvertToTensor(scalar, out->GetDataType()); | 250 | + aclScalar* scalar = executor->AllocScalar(1); |
| 236 | - op::FVector<int64_t, MAX_DIM_NUM> outputDims = op::ToShapeVector(out->GetViewShape()); | 251 | + auto valueTensor = executor->ConvertToTensor(scalar, out->GetDataType()); |
| 237 | - aclIntArray* dimArray = executor->AllocIntArray(outputDims.data(), outputDims.size()); | 252 | + op::FVector<int64_t, MAX_DIM_NUM> outputDims = op::ToShapeVector(out->GetViewShape()); |
| 238 | - auto dimTensor = executor->ConvertToTensor(dimArray, op::DataType::DT_INT64); | 253 | + aclIntArray* dimArray = executor->AllocIntArray(outputDims.data(), outputDims.size()); |
| 239 | - auto falseTensor = l0op::Fill(dimTensor, valueTensor, dimArray, executor); | 254 | + auto dimTensor = executor->ConvertToTensor(dimArray, op::DataType::DT_INT64); |
| 240 | - if (falseTensor == nullptr) { | 255 | + auto falseTensor = l0op::Fill(dimTensor, valueTensor, dimArray, executor); |
| 241 | - return nullptr; | 256 | + if (falseTensor == nullptr) { |
| 242 | - } | 257 | + return nullptr; |
| 243 | - auto viewCopyResult = l0op::ViewCopy(falseTensor, out, executor); | 258 | + } |
| 244 | - return viewCopyResult; | 259 | + auto viewCopyResult = l0op::ViewCopy(falseTensor, out, executor); |
| 260 | + return viewCopyResult; | ||
| 245 | } | 261 | } |
| 246 | 262 | ||
| 247 | -aclnnStatus aclnnAllGetWorkspaceSize(const aclTensor* self, const aclIntArray* dim, bool keepdim, aclTensor* out, | 263 | +aclnnStatus aclnnAllGetWorkspaceSize( |
| 248 | - uint64_t* workspaceSize, aclOpExecutor** executor) { | 264 | + const aclTensor* self, const aclIntArray* dim, bool keepdim, aclTensor* out, uint64_t* workspaceSize, |
| 249 | - L2_DFX_PHASE_1(aclnnAll, DFX_IN(self, dim, keepdim), DFX_OUT(out)); | 265 | + aclOpExecutor** executor) |
| 266 | +{ | ||
| 267 | + L2_DFX_PHASE_1(aclnnAll, DFX_IN(self, dim, keepdim), DFX_OUT(out)); | ||
| 250 | 268 | ||
| 251 | - // 固定写法,参数检查 | 269 | + // 固定写法,参数检查 |
| 252 | - auto ret = CheckParams(self, dim, keepdim, out); | 270 | + auto ret = CheckParams(self, dim, keepdim, out); |
| 253 | - CHECK_RET(ret == ACLNN_SUCCESS, ret); | 271 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); |
| 254 | 272 | ||
| 255 | - // 固定写法,创建OpExecutor | 273 | + // 固定写法,创建OpExecutor |
| 256 | - auto uniqueExecutor = CREATE_EXECUTOR(); | 274 | + auto uniqueExecutor = CREATE_EXECUTOR(); |
| 257 | - CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | 275 | + CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); |
| 258 | 276 | ||
| 259 | - // 空dim处理 | 277 | + // 空dim处理 |
| 260 | - if (dim->Size() == 0) { | 278 | + if (dim->Size() == 0) { |
| 261 | - dim = getAllDims(self, uniqueExecutor.get()); | 279 | + dim = getAllDims(self, uniqueExecutor.get()); |
| 262 | - CHECK_RET(dim != nullptr, ACLNN_ERR_INNER_NULLPTR); | 280 | + CHECK_RET(dim != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 263 | - } | 281 | + } |
| 264 | - // 空Tensor处理 | 282 | + // 空Tensor处理 |
| 265 | - if (self->IsEmpty()) { | 283 | + if (self->IsEmpty()) { |
| 266 | - auto trueTensor = GetTensorWithValueTrue(out, uniqueExecutor.get()); | 284 | + auto trueTensor = GetTensorWithValueTrue(out, uniqueExecutor.get()); |
| 267 | - CHECK_RET(trueTensor != nullptr, ACLNN_ERR_INNER_NULLPTR); | 285 | + CHECK_RET(trueTensor != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 286 | + *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 287 | + uniqueExecutor.ReleaseTo(executor); | ||
| 288 | + return ACLNN_SUCCESS; | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + // self如果非连续,需要转连续 | ||
| 292 | + auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 293 | + CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 294 | + | ||
| 295 | + // 将输入self的数据类型转换成隐式数据类型,根据具体算子语义按需调用 | ||
| 296 | + auto selfCasted = l0op::Cast(selfContiguous, DataType::DT_BOOL, uniqueExecutor.get()); | ||
| 297 | + CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 298 | + | ||
| 299 | + // 调用l0算子All进行计算 | ||
| 300 | + auto allResult = l0op::ReduceAll(selfCasted, dim, keepdim, uniqueExecutor.get()); | ||
| 301 | + CHECK_RET(allResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 302 | + | ||
| 303 | + auto allResultCasted = l0op::Cast(allResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 304 | + CHECK_RET(allResultCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 305 | + | ||
| 306 | + // 如果出参out是非连续Tensor,需要把计算完的连续Tensor转非连续 | ||
| 307 | + auto viewCopyResult = l0op::ViewCopy(allResultCasted, out, uniqueExecutor.get()); | ||
| 308 | + CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 309 | + | ||
| 310 | + // 固定写法,获取计算过程中需要使用的workspace大小 | ||
| 268 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | 311 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); |
| 269 | uniqueExecutor.ReleaseTo(executor); | 312 | uniqueExecutor.ReleaseTo(executor); |
| 270 | return ACLNN_SUCCESS; | 313 | return ACLNN_SUCCESS; |
| 271 | - } | ||
| 272 | - | ||
| 273 | - // self如果非连续,需要转连续 | ||
| 274 | - auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 275 | - CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 276 | - | ||
| 277 | - // 将输入self的数据类型转换成隐式数据类型,根据具体算子语义按需调用 | ||
| 278 | - auto selfCasted = l0op::Cast(selfContiguous, DataType::DT_BOOL, uniqueExecutor.get()); | ||
| 279 | - CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 280 | - | ||
| 281 | - // 调用l0算子All进行计算 | ||
| 282 | - auto allResult = l0op::ReduceAll(selfCasted, dim, keepdim, uniqueExecutor.get()); | ||
| 283 | - CHECK_RET(allResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 284 | - | ||
| 285 | - auto allResultCasted = l0op::Cast(allResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 286 | - CHECK_RET(allResultCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 287 | - | ||
| 288 | - // 如果出参out是非连续Tensor,需要把计算完的连续Tensor转非连续 | ||
| 289 | - auto viewCopyResult = l0op::ViewCopy(allResultCasted, out, uniqueExecutor.get()); | ||
| 290 | - CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 291 | - | ||
| 292 | - // 固定写法,获取计算过程中需要使用的workspace大小 | ||
| 293 | - *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 294 | - uniqueExecutor.ReleaseTo(executor); | ||
| 295 | - return ACLNN_SUCCESS; | ||
| 296 | } | 314 | } |
| 297 | 315 | ||
| 298 | -aclnnStatus aclnnAll(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream) { | 316 | +aclnnStatus aclnnAll(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream) |
| 299 | - L2_DFX_PHASE_2(aclnnAll); | 317 | +{ |
| 300 | - // 固定写法,调用框架能力,完成计算 | 318 | + L2_DFX_PHASE_2(aclnnAll); |
| 301 | - return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | 319 | + // 固定写法,调用框架能力,完成计算 |
| 320 | + return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | ||
| 302 | } | 321 | } |
| @@ -46,8 +46,9 @@ extern "C" { | |||
| 46 | * @param [out] executor: 返回op执行器,包含算子计算流程。 | 46 | * @param [out] executor: 返回op执行器,包含算子计算流程。 |
| 47 | * @return aclnnStatus: 返回状态码。 | 47 | * @return aclnnStatus: 返回状态码。 |
| 48 | */ | 48 | */ |
| 49 | -ACLNN_API aclnnStatus aclnnAllGetWorkspaceSize(const aclTensor* self, const aclIntArray* dim, bool keepdim, | 49 | +ACLNN_API aclnnStatus aclnnAllGetWorkspaceSize( |
| 50 | - aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); | 50 | + const aclTensor* self, const aclIntArray* dim, bool keepdim, aclTensor* out, uint64_t* workspaceSize, |
| 51 | + aclOpExecutor** executor); | ||
| 51 | 52 | ||
| 52 | /** | 53 | /** |
| 53 | * @brief aclnnAll的第二段接口,用于执行计算。 | 54 | * @brief aclnnAll的第二段接口,用于执行计算。 |
| @@ -57,11 +58,11 @@ ACLNN_API aclnnStatus aclnnAllGetWorkspaceSize(const aclTensor* self, const aclI | |||
| 57 | * @param [in] stream: acl stream流。 | 58 | * @param [in] stream: acl stream流。 |
| 58 | * @return aclnnStatus: 返回状态码。 | 59 | * @return aclnnStatus: 返回状态码。 |
| 59 | */ | 60 | */ |
| 60 | -ACLNN_API aclnnStatus aclnnAll(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, | 61 | +ACLNN_API aclnnStatus |
| 61 | - const aclrtStream stream); | 62 | +aclnnAll(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream); |
| 62 | 63 | ||
| 63 | 64 | ||
| 64 | } | 65 | } |
| 65 | 66 | ||
| 66 | 67 | ||
| 67 | -#endif // OP_API_INC_LEVEL2_ACLNN_ALL_H_ | 68 | +#endif // OP_API_INC_LEVEL2_ACLNN_ALL_H_ |
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | namespace l0op { | 16 | namespace l0op { |
| 17 | -const aclTensor *ReduceAll(const aclTensor *self, const aclIntArray *dim, bool keepdim, aclOpExecutor *executor); | 17 | +const aclTensor* ReduceAll(const aclTensor* self, const aclIntArray* dim, bool keepdim, aclOpExecutor* executor); |
| 18 | -} // namespace l0op | 18 | +} // namespace l0op |
| 19 | 19 | ||
| 20 | -#endif // OP_API_INC_LEVEL0_REDUCE_All_H_ | 20 | +#endif // OP_API_INC_LEVEL0_REDUCE_All_H_ |
| @@ -1,12 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 4 | -# This file is a part of the CANN Open Software. | ||
| 5 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 8 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | -# ---------------------------------------------------------------------------- | ||
| 11 | - | ||
| 12 | -add_modules_sources(OPTYPE reduce_all ACLNNTYPE aclnn_exclude) | ||
| @@ -1,21 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file reduce_all_tiling.h | ||
| 13 | - * \brief tiling for reduce all | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| @@ -13,38 +13,31 @@ | |||
| 13 | * \brief aicore info for reduceAll op | 13 | * \brief aicore info for reduceAll op |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | - | 16 | + |
| 17 | namespace ops { | 17 | namespace ops { |
| 18 | static const std::vector<ge::DataType> dataType = {ge::DT_BOOL, ge::DT_BOOL}; | 18 | static const std::vector<ge::DataType> dataType = {ge::DT_BOOL, ge::DT_BOOL}; |
| 19 | - | 19 | + |
| 20 | static const std::vector<ge::Format> format = {ge::FORMAT_ND, ge::FORMAT_ND}; | 20 | static const std::vector<ge::Format> format = {ge::FORMAT_ND, ge::FORMAT_ND}; |
| 21 | - | 21 | + |
| 22 | static const std::vector<ge::DataType> axesDataType = {ge::DT_INT32, ge::DT_INT64}; | 22 | static const std::vector<ge::DataType> axesDataType = {ge::DT_INT32, ge::DT_INT64}; |
| 23 | - | 23 | + |
| 24 | class ReduceAll : public OpDef { | 24 | class ReduceAll : public OpDef { |
| 25 | - public: | 25 | +public: |
| 26 | - explicit ReduceAll(const char* name) : OpDef(name) { | 26 | + explicit ReduceAll(const char* name) : OpDef(name) |
| 27 | - this->Input("x") | 27 | + { |
| 28 | - .ParamType(REQUIRED) | 28 | + this->Input("x").ParamType(REQUIRED).DataType(dataType).Format(format).UnknownShapeFormat(format); |
| 29 | - .DataType(dataType) | 29 | + |
| 30 | - .Format(format) | ||
| 31 | - .UnknownShapeFormat(format); | ||
| 32 | - | ||
| 33 | this->Input("axes") | 30 | this->Input("axes") |
| 34 | .ParamType(REQUIRED) | 31 | .ParamType(REQUIRED) |
| 35 | .ValueDepend(OPTIONAL) | 32 | .ValueDepend(OPTIONAL) |
| 36 | .DataType(axesDataType) | 33 | .DataType(axesDataType) |
| 37 | .Format(format) | 34 | .Format(format) |
| 38 | .UnknownShapeFormat(format); | 35 | .UnknownShapeFormat(format); |
| 39 | - | 36 | + |
| 40 | - this->Output("y") | 37 | + this->Output("y").ParamType(REQUIRED).DataType(dataType).Format(format).UnknownShapeFormat(format); |
| 41 | - .ParamType(REQUIRED) | 38 | + |
| 42 | - .DataType(dataType) | ||
| 43 | - .Format(format) | ||
| 44 | - .UnknownShapeFormat(format); | ||
| 45 | - | ||
| 46 | this->Attr("keep_dims").AttrType(OPTIONAL).Bool(false); | 39 | this->Attr("keep_dims").AttrType(OPTIONAL).Bool(false); |
| 47 | - | 40 | + |
| 48 | OpAICoreConfig aicoreConfig; | 41 | OpAICoreConfig aicoreConfig; |
| 49 | aicoreConfig.DynamicCompileStaticFlag(true) | 42 | aicoreConfig.DynamicCompileStaticFlag(true) |
| 50 | .DynamicRankSupportFlag(true) | 43 | .DynamicRankSupportFlag(true) |
| @@ -53,6 +46,6 @@ class ReduceAll : public OpDef { | |||
| 53 | this->AICore().AddConfig("ascend950", aicoreConfig); | 46 | this->AICore().AddConfig("ascend950", aicoreConfig); |
| 54 | } | 47 | } |
| 55 | }; | 48 | }; |
| 56 | - | 49 | + |
| 57 | OP_ADD(ReduceAll); | 50 | OP_ADD(ReduceAll); |
| 58 | -} // namespace ops | 51 | +} // namespace ops |
| @@ -12,52 +12,14 @@ | |||
| 12 | * \file reduce_infer.cc | 12 | * \file reduce_infer.cc |
| 13 | * \brief | 13 | * \brief |
| 14 | */ | 14 | */ |
| 15 | - | ||
| 16 | 15 | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | 16 | ||
| 21 | 17 | ||
| 22 | -using namespace ge; | ||
| 23 | -using namespace Ops::Base; | ||
| 24 | namespace ops { | 18 | namespace ops { |
| 25 | -static ge::graphStatus InferShape4ReduceAll(gert::InferShapeContext* context) { | 19 | +static ge::graphStatus InferShape4ReduceAll(gert::InferShapeContext* context) |
| 26 | - auto in_shape = context->GetInputShape(0); | 20 | +{ |
| 27 | - OP_CHECK_NULL_WITH_CONTEXT(context, in_shape); | 21 | + return Ops::Base::InferShape4Reduce(context); |
| 28 | - auto axes_tensor = context->GetInputTensor(1); | ||
| 29 | - OP_CHECK_NULL_WITH_CONTEXT(context, axes_tensor); | ||
| 30 | - auto out_shape = context->GetOutputShape(0); | ||
| 31 | - OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); | ||
| 32 | - auto attrs = context->GetAttrs(); | ||
| 33 | - OP_CHECK_NULL_WITH_CONTEXT(context, attrs); | ||
| 34 | - | ||
| 35 | - const bool* keep_dims = attrs->GetAttrPointer<bool>(0); | ||
| 36 | - OP_CHECK_NULL_WITH_CONTEXT(context, keep_dims); | ||
| 37 | - | ||
| 38 | - auto axes_size = static_cast<int32_t>(axes_tensor->GetShapeSize()); | ||
| 39 | - | ||
| 40 | - OP_CHECK_IF(axes_size < 0, | ||
| 41 | - OP_LOGE(context->GetNodeName(), "axes num cannot be less than 0!"), | ||
| 42 | - return ge::GRAPH_FAILED); | ||
| 43 | - | ||
| 44 | - if (axes_size == 0) { | ||
| 45 | - *out_shape = *in_shape; | ||
| 46 | - OP_LOGD(context->GetNodeName(), "axes is empty tensor, will ignore infer, set output shape = input shape"); | ||
| 47 | - return ge::GRAPH_SUCCESS; | ||
| 48 | - } | ||
| 49 | - | ||
| 50 | - auto dtype = axes_tensor->GetDataType(); | ||
| 51 | - OP_CHECK_IF(dtype != ge::DT_INT32 && dtype != ge::DT_INT64, | ||
| 52 | - OP_LOGE( | ||
| 53 | - context->GetNodeName(), "axes datatype %s must in (int32, int64)", ToString(dtype).c_str()), | ||
| 54 | - return ge::GRAPH_FAILED); | ||
| 55 | - if (dtype == ge::DT_INT32) { | ||
| 56 | - return ReduceDims<int32_t>(in_shape, axes_tensor, axes_size, *keep_dims, out_shape); | ||
| 57 | - } | ||
| 58 | - return ReduceDims<int64_t>(in_shape, axes_tensor, axes_size, *keep_dims, out_shape); | ||
| 59 | } | 22 | } |
| 60 | 23 | ||
| 61 | - | ||
| 62 | IMPL_OP_INFERSHAPE(ReduceAll).InferShape(InferShape4ReduceAll).InputsDataDependency({1}); | 24 | IMPL_OP_INFERSHAPE(ReduceAll).InferShape(InferShape4ReduceAll).InputsDataDependency({1}); |
| 63 | -} | 25 | +} // namespace ops |
| @@ -1,17 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 4 | -# This file is a part of the CANN Open Software. | ||
| 5 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 8 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | -# ---------------------------------------------------------------------------- | ||
| 11 | - | ||
| 12 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | - add_subdirectory(${SUB_DIR}) | ||
| 16 | - endif() | ||
| 17 | -endforeach() | ||
| @@ -1,17 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 4 | -# This file is a part of the CANN Open Software. | ||
| 5 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 8 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | -# ---------------------------------------------------------------------------- | ||
| 11 | - | ||
| 12 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | - add_subdirectory(${SUB_DIR}) | ||
| 16 | - endif() | ||
| 17 | -endforeach() | ||
| @@ -1,20 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 4 | -# This file is a part of the CANN Open Software. | ||
| 5 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 8 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | -# ---------------------------------------------------------------------------- | ||
| 11 | - | ||
| 12 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 13 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | - add_subdirectory(${SUB_DIR}) | ||
| 16 | - endif() | ||
| 17 | -endforeach() | ||
| 18 | - | ||
| 19 | -if(OP_API_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 20 | -endif() | ||
| @@ -1,12 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 3 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 4 | -# This file is a part of the CANN Open Software. | ||
| 5 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 6 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 7 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 8 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 9 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 10 | -# ---------------------------------------------------------------------------- | ||
| 11 | - | ||
| 12 | -add_modules_sources() | ||
| @@ -1,21 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file reduce_any_tiling.h | ||
| 13 | - * \brief tiling for reduce any | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | - | ||
| @@ -8,51 +8,15 @@ | |||
| 8 | * See LICENSE in the root of the software repository for the full text of the License. | 8 | * See LICENSE in the root of the software repository for the full text of the License. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | - | ||
| 12 | 11 | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | 12 | ||
| 17 | -using namespace ge; | 13 | + |
| 18 | -using namespace Ops::Base; | ||
| 19 | namespace ops { | 14 | namespace ops { |
| 20 | -static ge::graphStatus InferShape4ReduceAny(gert::InferShapeContext* context) { | 15 | +static ge::graphStatus InferShape4ReduceAny(gert::InferShapeContext* context) |
| 21 | - auto in_shape = context->GetInputShape(0); | 16 | +{ |
| 22 | - OP_CHECK_NULL_WITH_CONTEXT(context, in_shape); | 17 | + return Ops::Base::InferShape4Reduce(context); |
| 23 | - auto axes_tensor = context->GetInputTensor(1); | ||
| 24 | - OP_CHECK_NULL_WITH_CONTEXT(context, axes_tensor); | ||
| 25 | - auto out_shape = context->GetOutputShape(0); | ||
| 26 | - OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); | ||
| 27 | - auto attrs = context->GetAttrs(); | ||
| 28 | - OP_CHECK_NULL_WITH_CONTEXT(context, attrs); | ||
| 29 | - | ||
| 30 | - const bool* keep_dims = attrs->GetAttrPointer<bool>(0); | ||
| 31 | - OP_CHECK_NULL_WITH_CONTEXT(context, keep_dims); | ||
| 32 | - | ||
| 33 | - auto axes_size = static_cast<int32_t>(axes_tensor->GetShapeSize()); | ||
| 34 | - | ||
| 35 | - OP_CHECK_IF(axes_size < 0, | ||
| 36 | - OP_LOGE(context->GetNodeName(), "axes num cannot be less than 0!"), | ||
| 37 | - return ge::GRAPH_FAILED); | ||
| 38 | - | ||
| 39 | - if (axes_size == 0) { | ||
| 40 | - *out_shape = *in_shape; | ||
| 41 | - OP_LOGD(context->GetNodeName(), "axes is empty tensor, will ignore infer, set output shape = input shape"); | ||
| 42 | - return ge::GRAPH_SUCCESS; | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - auto dtype = axes_tensor->GetDataType(); | ||
| 46 | - OP_CHECK_IF(dtype != ge::DT_INT32 && dtype != ge::DT_INT64, | ||
| 47 | - OP_LOGE( | ||
| 48 | - context->GetNodeName(), "axes datatype %s must in (int32, int64)", ToString(dtype).c_str()), | ||
| 49 | - return ge::GRAPH_FAILED); | ||
| 50 | - if (dtype == ge::DT_INT32) { | ||
| 51 | - return ReduceDims<int32_t>(in_shape, axes_tensor, axes_size, *keep_dims, out_shape); | ||
| 52 | - } | ||
| 53 | - return ReduceDims<int64_t>(in_shape, axes_tensor, axes_size, *keep_dims, out_shape); | ||
| 54 | } | 18 | } |
| 55 | 19 | ||
| 56 | IMPL_OP_INFERSHAPE(ReduceAny).InferShape(InferShape4ReduceAny).InputsDataDependency({1}); | 20 | IMPL_OP_INFERSHAPE(ReduceAny).InferShape(InferShape4ReduceAny).InputsDataDependency({1}); |
| 57 | 21 | ||
| 58 | -} | 22 | +} // namespace ops |
| @@ -24,7 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | namespace ReduceAny { | 26 | namespace ReduceAny { |
| 27 | -using namespace AscendC; | ||
| 28 | using namespace Ops::Base; | 27 | using namespace Ops::Base; |
| 29 | using OutDtype = uint8_t; | 28 | using OutDtype = uint8_t; |
| 30 | 29 | ||
| @@ -1,16 +0,0 @@ | |||
| 1 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This file is a part of the CANN Open Software. | ||
| 4 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 7 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of | ||
| 8 | -# the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| @@ -1,16 +0,0 @@ | |||
| 1 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This file is a part of the CANN Open Software. | ||
| 4 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 7 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of | ||
| 8 | -# the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| @@ -1,17 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| 17 | - | ||
| @@ -1,12 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -if(PASS_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 12 | -endif() | ||
| @@ -1,19 +0,0 @@ | |||
| 1 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This file is a part of the CANN Open Software. | ||
| 4 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 7 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of | ||
| 8 | -# the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| 17 | - | ||
| 18 | -if(OP_API_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 19 | -endif() | ||
| @@ -1,10 +0,0 @@ | |||
| 1 | -# This program is free software, you can redistribute it and/or modify it. | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This file is a part of the CANN Open Software. | ||
| 4 | -# Licensed under CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING | ||
| 7 | -# BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. See LICENSE in the root of | ||
| 8 | -# the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| @@ -1,322 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | - | ||
| 12 | - | ||
| 13 | - | ||
| 14 | - | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| 20 | - | ||
| 21 | -using namespace std; | ||
| 22 | - | ||
| 23 | -class l2_any_all_test : public testing::Test { | ||
| 24 | - protected: | ||
| 25 | - static void SetUpTestCase() { cout << "any_all_test SetUp" << endl; } | ||
| 26 | - | ||
| 27 | - static void TearDownTestCase() { cout << "any_all_test TearDown" << endl; } | ||
| 28 | -}; | ||
| 29 | - | ||
| 30 | -// TEST_F(l2_any_all_test, case_bool) { | ||
| 31 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 32 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 33 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 34 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 35 | - | ||
| 36 | -// uint64_t workspace_size = 0; | ||
| 37 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 38 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 39 | - | ||
| 40 | -// ut.TestPrecision(); | ||
| 41 | -// } | ||
| 42 | - | ||
| 43 | -// TEST_F(l2_any_all_test, case_f16) { | ||
| 44 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_FLOAT16, ACL_FORMAT_ND); | ||
| 45 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 46 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 47 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 48 | - | ||
| 49 | -// uint64_t workspace_size = 0; | ||
| 50 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 51 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 52 | - | ||
| 53 | -// ut.TestPrecision(); | ||
| 54 | -// } | ||
| 55 | - | ||
| 56 | -// TEST_F(l2_any_all_test, ascend910B2_case_bf16) { | ||
| 57 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_BF16, ACL_FORMAT_ND); | ||
| 58 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 59 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 60 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 61 | - | ||
| 62 | -// uint64_t workspace_size = 0; | ||
| 63 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 64 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 65 | - | ||
| 66 | -// ut.TestPrecision(); | ||
| 67 | -// } | ||
| 68 | - | ||
| 69 | -// TEST_F(l2_any_all_test, case_f32) { | ||
| 70 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_FLOAT, ACL_FORMAT_ND); | ||
| 71 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 72 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 73 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 74 | - | ||
| 75 | -// uint64_t workspace_size = 0; | ||
| 76 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 77 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 78 | - | ||
| 79 | -// ut.TestPrecision(); | ||
| 80 | -// } | ||
| 81 | - | ||
| 82 | -// TEST_F(l2_any_all_test, case_int8) { | ||
| 83 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_INT8, ACL_FORMAT_ND); | ||
| 84 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 85 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 86 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 87 | - | ||
| 88 | -// uint64_t workspace_size = 0; | ||
| 89 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 90 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 91 | - | ||
| 92 | -// ut.TestPrecision(); | ||
| 93 | -// } | ||
| 94 | - | ||
| 95 | -TEST_F(l2_any_all_test, case_uint8) { | ||
| 96 | - auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 97 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 98 | - auto out_tensor_desc = TensorDesc({1}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 99 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 100 | - | ||
| 101 | - uint64_t workspace_size = 0; | ||
| 102 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 103 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 104 | - | ||
| 105 | - ut.TestPrecision(); | ||
| 106 | -} | ||
| 107 | - | ||
| 108 | -TEST_F(l2_any_all_test, case_int16) { | ||
| 109 | - auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_INT16, ACL_FORMAT_ND); | ||
| 110 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 111 | - auto out_tensor_desc = TensorDesc({1}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 112 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 113 | - | ||
| 114 | - uint64_t workspace_size = 0; | ||
| 115 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 116 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 117 | - | ||
| 118 | - ut.TestPrecision(); | ||
| 119 | -} | ||
| 120 | - | ||
| 121 | -// TEST_F(l2_any_all_test, case_int32) { | ||
| 122 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_INT32, ACL_FORMAT_ND); | ||
| 123 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 124 | -// auto out_tensor_desc = TensorDesc({1}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 125 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 126 | - | ||
| 127 | -// uint64_t workspace_size = 0; | ||
| 128 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 129 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 130 | - | ||
| 131 | -// ut.TestPrecision(); | ||
| 132 | -// } | ||
| 133 | - | ||
| 134 | -// TEST_F(l2_any_all_test, case_int64) { | ||
| 135 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_INT64, ACL_FORMAT_ND); | ||
| 136 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 137 | -// auto out_tensor_desc = TensorDesc({1}, ACL_UINT8, ACL_FORMAT_ND); | ||
| 138 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 139 | - | ||
| 140 | -// uint64_t workspace_size = 0; | ||
| 141 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 142 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 143 | - | ||
| 144 | -// ut.TestPrecision(); | ||
| 145 | -// } | ||
| 146 | - | ||
| 147 | -TEST_F(l2_any_all_test, case_empty) { | ||
| 148 | - auto tensor_desc = TensorDesc({2, 0, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 149 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 150 | - auto out_tensor_desc = TensorDesc({1, 1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 151 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 152 | - | ||
| 153 | - uint64_t workspace_size = 0; | ||
| 154 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 155 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 156 | - | ||
| 157 | - ut.TestPrecision(); | ||
| 158 | -} | ||
| 159 | - | ||
| 160 | -TEST_F(l2_any_all_test, case_empty_out) { | ||
| 161 | - auto tensor_desc = TensorDesc({2, 0, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 162 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0}); | ||
| 163 | - auto out_tensor_desc = TensorDesc({0, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 164 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 165 | - | ||
| 166 | - uint64_t workspace_size = 0; | ||
| 167 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 168 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 169 | - | ||
| 170 | - ut.TestPrecision(); | ||
| 171 | -} | ||
| 172 | - | ||
| 173 | -TEST_F(l2_any_all_test, case_unsupportdtype) { | ||
| 174 | - auto tensor_desc = TensorDesc({2, 2, 4, 5}, ACL_INT16, ACL_FORMAT_ND); | ||
| 175 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 176 | - auto out_tensor_desc = TensorDesc({1, 1}, ACL_INT16, ACL_FORMAT_ND); | ||
| 177 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 178 | - | ||
| 179 | - uint64_t workspace_size = 0; | ||
| 180 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 181 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 182 | -} | ||
| 183 | - | ||
| 184 | -TEST_F(l2_any_all_test, case_unsupportdshape) { | ||
| 185 | - auto tensor_desc = TensorDesc({2, 2, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 186 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 187 | - auto out_tensor_desc = TensorDesc({1, 2}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 188 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 189 | - | ||
| 190 | - uint64_t workspace_size = 0; | ||
| 191 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 192 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 193 | -} | ||
| 194 | - | ||
| 195 | -TEST_F(l2_any_all_test, case_null) { | ||
| 196 | - auto tensor_desc = TensorDesc({2, 2, 4, 5}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 197 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 198 | - auto out_tensor_desc = TensorDesc({1, 2}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 199 | - auto ut1 = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(nullptr)); | ||
| 200 | - | ||
| 201 | - uint64_t workspace_size = 0; | ||
| 202 | - aclnnStatus aclRet1 = ut1.TestGetWorkspaceSize(&workspace_size); | ||
| 203 | - EXPECT_EQ(aclRet1, ACLNN_ERR_PARAM_NULLPTR); | ||
| 204 | - | ||
| 205 | - auto ut2 = OP_API_UT(aclnnAny, INPUT(nullptr, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 206 | - | ||
| 207 | - aclnnStatus aclRet2 = ut2.TestGetWorkspaceSize(&workspace_size); | ||
| 208 | - EXPECT_EQ(aclRet2, ACLNN_ERR_PARAM_NULLPTR); | ||
| 209 | -} | ||
| 210 | - | ||
| 211 | -TEST_F(l2_any_all_test, case_uncontinue) { | ||
| 212 | - auto tensor_desc = TensorDesc({4, 5}, ACL_BOOL, ACL_FORMAT_NCHW, {1, 4}, 0, {5, 4}); | ||
| 213 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1}); | ||
| 214 | - auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 215 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 216 | - | ||
| 217 | - uint64_t workspace_size = 0; | ||
| 218 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 219 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 220 | -} | ||
| 221 | - | ||
| 222 | -// TEST_F(l2_any_all_test, case_NCHW) { | ||
| 223 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_BOOL, ACL_FORMAT_NCHW); | ||
| 224 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 225 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 226 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 227 | - | ||
| 228 | -// uint64_t workspace_size = 0; | ||
| 229 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 230 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 231 | - | ||
| 232 | -// ut.TestPrecision(); | ||
| 233 | -// } | ||
| 234 | - | ||
| 235 | -// TEST_F(l2_any_all_test, case_NHWC) { | ||
| 236 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_BOOL, ACL_FORMAT_NHWC); | ||
| 237 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 238 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 239 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 240 | - | ||
| 241 | -// uint64_t workspace_size = 0; | ||
| 242 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 243 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 244 | - | ||
| 245 | -// ut.TestPrecision(); | ||
| 246 | -// } | ||
| 247 | - | ||
| 248 | -// TEST_F(l2_any_all_test, case_HWCN) { | ||
| 249 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5}, ACL_BOOL, ACL_FORMAT_HWCN); | ||
| 250 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 251 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 252 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 253 | - | ||
| 254 | -// uint64_t workspace_size = 0; | ||
| 255 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 256 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 257 | - | ||
| 258 | -// ut.TestPrecision(); | ||
| 259 | -// } | ||
| 260 | - | ||
| 261 | -// TEST_F(l2_any_all_test, case_NDHWC) { | ||
| 262 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5, 6}, ACL_BOOL, ACL_FORMAT_NDHWC); | ||
| 263 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3, 4}); | ||
| 264 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 265 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 266 | - | ||
| 267 | -// uint64_t workspace_size = 0; | ||
| 268 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 269 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 270 | - | ||
| 271 | -// ut.TestPrecision(); | ||
| 272 | -// } | ||
| 273 | - | ||
| 274 | -// TEST_F(l2_any_all_test, case_NCDHW) { | ||
| 275 | -// auto tensor_desc = TensorDesc({2, 3, 4, 5, 6}, ACL_BOOL, ACL_FORMAT_NCDHW); | ||
| 276 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3, 4}); | ||
| 277 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 278 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 279 | - | ||
| 280 | -// uint64_t workspace_size = 0; | ||
| 281 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 282 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 283 | - | ||
| 284 | -// ut.TestPrecision(); | ||
| 285 | -// } | ||
| 286 | - | ||
| 287 | -// TEST_F(l2_any_all_test, case_dim_0) { | ||
| 288 | -// auto tensor_desc = TensorDesc({}, ACL_BOOL, ACL_FORMAT_NCDHW); | ||
| 289 | -// auto dim_desc = IntArrayDesc(vector<int64_t>{0}); | ||
| 290 | -// auto out_tensor_desc = TensorDesc({1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 291 | -// auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 292 | - | ||
| 293 | -// uint64_t workspace_size = 0; | ||
| 294 | -// aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 295 | -// EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 296 | - | ||
| 297 | -// ut.TestPrecision(); | ||
| 298 | -// } | ||
| 299 | - | ||
| 300 | -// 空dim | ||
| 301 | -TEST_F(l2_any_all_test, case_empty_dimt) { | ||
| 302 | - auto tensor_desc = TensorDesc({2, 0, 3}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 303 | - auto out_tensor_desc = TensorDesc({}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 304 | - auto dim_desc = IntArrayDesc(vector<int64_t>{}); | ||
| 305 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 306 | - | ||
| 307 | - // SAMPLE: only test GetWorkspaceSize | ||
| 308 | - uint64_t workspace_size = 0; | ||
| 309 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 310 | - EXPECT_EQ(aclRet, ACL_SUCCESS); | ||
| 311 | -} | ||
| 312 | - | ||
| 313 | -TEST_F(l2_any_all_test, case_unsupportdim) { | ||
| 314 | - auto tensor_desc = TensorDesc({1, 2, 3, 4, 5, 6, 7, 8, 9}, ACL_INT16, ACL_FORMAT_ND); | ||
| 315 | - auto dim_desc = IntArrayDesc(vector<int64_t>{0, 1, 2, 3}); | ||
| 316 | - auto out_tensor_desc = TensorDesc({1, 1}, ACL_BOOL, ACL_FORMAT_ND); | ||
| 317 | - auto ut = OP_API_UT(aclnnAny, INPUT(tensor_desc, dim_desc, false), OUTPUT(out_tensor_desc)); | ||
| 318 | - | ||
| 319 | - uint64_t workspace_size = 0; | ||
| 320 | - aclnnStatus aclRet = ut.TestGetWorkspaceSize(&workspace_size); | ||
| 321 | - EXPECT_EQ(aclRet, ACLNN_ERR_PARAM_INVALID); | ||
| 322 | -} | ||
| @@ -38,211 +38,223 @@ constexpr size_t MAX_DIM_LEN = 8; | |||
| 38 | 38 | ||
| 39 | // 算子支持的所有dtype | 39 | // 算子支持的所有dtype |
| 40 | static const std::initializer_list<op::DataType> ASCEND910_DTYPE_SUPPORT_LIST = { | 40 | static const std::initializer_list<op::DataType> ASCEND910_DTYPE_SUPPORT_LIST = { |
| 41 | - op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT32, // AiCore | 41 | + op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT32, // AiCore |
| 42 | - op::DataType::DT_INT64, op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_DOUBLE, // AiCpu | 42 | + op::DataType::DT_INT64, op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_DOUBLE, // AiCpu |
| 43 | - op::DataType::DT_BOOL}; // AiCore(cast to float) | 43 | + op::DataType::DT_BOOL}; // AiCore(cast to float) |
| 44 | 44 | ||
| 45 | static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { | 45 | static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { |
| 46 | - op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT32, // AiCore | 46 | + op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT32, // AiCore |
| 47 | - op::DataType::DT_INT64, op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_DOUBLE, // AiCpu | 47 | + op::DataType::DT_INT64, op::DataType::DT_INT16, op::DataType::DT_INT8, op::DataType::DT_DOUBLE, // AiCpu |
| 48 | - op::DataType::DT_BOOL, op::DataType::DT_BF16}; | 48 | + op::DataType::DT_BOOL, op::DataType::DT_BF16}; |
| 49 | 49 | ||
| 50 | -static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) { | 50 | +static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) |
| 51 | - if (dimNum <= 0) { | 51 | +{ |
| 52 | - dimNum = 1; | 52 | + if (dimNum <= 0) { |
| 53 | - } | 53 | + dimNum = 1; |
| 54 | - return dim >= 0 ? dim : dim + dimNum; | ||
| 55 | -} | ||
| 56 | - | ||
| 57 | -static inline const aclIntArray* GetAllDims(const aclTensor* self, aclOpExecutor* executor) { | ||
| 58 | - auto inputShape = self->GetViewShape(); | ||
| 59 | - size_t inputDimNum = inputShape.GetDimNum(); | ||
| 60 | - FVector<int64_t> dims; | ||
| 61 | - for (size_t idx = 0; idx < inputDimNum; idx++) { | ||
| 62 | - dims.emplace_back(idx); | ||
| 63 | - } | ||
| 64 | - return executor->AllocIntArray(dims.data(), dims.size()); | ||
| 65 | -} | ||
| 66 | - | ||
| 67 | -static void AmaxInferShape(const op::Shape& selfShape, const aclIntArray* dim, bool keepDim, op::Shape& reduceShape) { | ||
| 68 | - bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 69 | - if (dim->Size() == 0) { | ||
| 70 | - dimMask.flip(); | ||
| 71 | - } | ||
| 72 | - for (size_t i = 0; i < dim->Size(); i++) { | ||
| 73 | - int64_t index = GetPosDim(dim->operator[](i), selfShape.GetDimNum()); | ||
| 74 | - // 前序已检查, 此处如果dim不会重复 | ||
| 75 | - dimMask.set(index); | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - for (size_t i = 0; i < selfShape.GetDimNum(); i++) { | ||
| 79 | - if (!dimMask[i]) { | ||
| 80 | - reduceShape.AppendDim(selfShape.GetDim(i)); | ||
| 81 | - } else if (keepDim) { | ||
| 82 | - reduceShape.AppendDim(1); | ||
| 83 | } | 54 | } |
| 84 | - } | 55 | + return dim >= 0 ? dim : dim + dimNum; |
| 85 | } | 56 | } |
| 86 | 57 | ||
| 87 | -static inline bool CheckNotNull(const aclTensor* self, const aclIntArray* dim, const aclTensor* out) { | 58 | +static inline const aclIntArray* GetAllDims(const aclTensor* self, aclOpExecutor* executor) |
| 88 | - // dim也需要判空,需要获取dim中元素和个数 | 59 | +{ |
| 89 | - OP_CHECK_NULL(self, return false); | 60 | + auto inputShape = self->GetViewShape(); |
| 90 | - OP_CHECK_NULL(dim, return false); | 61 | + size_t inputDimNum = inputShape.GetDimNum(); |
| 91 | - OP_CHECK_NULL(out, return false); | 62 | + FVector<int64_t> dims; |
| 92 | - return true; | 63 | + for (size_t idx = 0; idx < inputDimNum; idx++) { |
| 93 | -} | 64 | + dims.emplace_back(idx); |
| 94 | - | ||
| 95 | -static inline const std::initializer_list<op::DataType>& GetDtypeSupportList() { | ||
| 96 | - if ((GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && | ||
| 97 | - GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || | ||
| 98 | - IsRegBase()) { | ||
| 99 | - return ASCEND910B_DTYPE_SUPPORT_LIST; | ||
| 100 | - } else { | ||
| 101 | - return ASCEND910_DTYPE_SUPPORT_LIST; | ||
| 102 | - } | ||
| 103 | -} | ||
| 104 | - | ||
| 105 | -static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) { | ||
| 106 | - auto supportList = GetDtypeSupportList(); | ||
| 107 | - // 检查self与out的数据类型是否一致 | ||
| 108 | - OP_CHECK_DTYPE_NOT_MATCH(out, self->GetDataType(), return false); | ||
| 109 | - // 检查self的数据类型是否支持, out与self一致,不需要额外检查 | ||
| 110 | - OP_CHECK_DTYPE_NOT_SUPPORT(self, supportList, return false); | ||
| 111 | - | ||
| 112 | - return true; | ||
| 113 | -} | ||
| 114 | - | ||
| 115 | -static bool CheckDimValid(const aclTensor* self, const aclIntArray* dim) { | ||
| 116 | - auto selfViewShape = self->GetViewShape(); | ||
| 117 | - auto selfDimNum = static_cast<int64_t>(selfViewShape.GetDimNum()); | ||
| 118 | - bool isScalar = false; | ||
| 119 | - // self为标量时,dim range [-1, 0] | ||
| 120 | - if (selfDimNum <= 0) { | ||
| 121 | - selfDimNum = 1; | ||
| 122 | - isScalar = true; | ||
| 123 | - } | ||
| 124 | - // dim为负时需要转正校验 | ||
| 125 | - bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 126 | - | ||
| 127 | - for (size_t i = 0; i < dim->Size(); i++) { | ||
| 128 | - if (dim->operator[](i) >= selfDimNum || dim->operator[](i) < (-selfDimNum)) { | ||
| 129 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Provided dim %ld must be in the range of [%ld, %ld].", | ||
| 130 | - dim->operator[](i), -selfDimNum, selfDimNum - 1); | ||
| 131 | - return false; | ||
| 132 | } | 65 | } |
| 133 | - uint64_t index = GetPosDim(dim->operator[](i), selfDimNum); | 66 | + return executor->AllocIntArray(dims.data(), dims.size()); |
| 134 | - // 非标量reduce的dim不能为0 | 67 | +} |
| 135 | - if (!isScalar && selfViewShape.GetDim(index) == 0) { | 68 | + |
| 136 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expected reducution dim %lu to have non-zero size.", index); | 69 | +static void AmaxInferShape(const op::Shape& selfShape, const aclIntArray* dim, bool keepDim, op::Shape& reduceShape) |
| 137 | - return false; | 70 | +{ |
| 71 | + bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 72 | + if (dim->Size() == 0) { | ||
| 73 | + dimMask.flip(); | ||
| 138 | } | 74 | } |
| 139 | - // dim重复 | 75 | + for (size_t i = 0; i < dim->Size(); i++) { |
| 140 | - if (dimMask[index]) { | 76 | + int64_t index = GetPosDim(dim->operator[](i), selfShape.GetDimNum()); |
| 141 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | 77 | + // 前序已检查, 此处如果dim不会重复 |
| 142 | - return false; | 78 | + dimMask.set(index); |
| 143 | } | 79 | } |
| 144 | 80 | ||
| 145 | - dimMask.set(index); | 81 | + for (size_t i = 0; i < selfShape.GetDimNum(); i++) { |
| 146 | - } | 82 | + if (!dimMask[i]) { |
| 147 | - | 83 | + reduceShape.AppendDim(selfShape.GetDim(i)); |
| 148 | - return true; | 84 | + } else if (keepDim) { |
| 85 | + reduceShape.AppendDim(1); | ||
| 86 | + } | ||
| 87 | + } | ||
| 149 | } | 88 | } |
| 150 | 89 | ||
| 151 | -static bool CheckShape(const aclTensor* self, const aclIntArray* dim, const bool keepDim, const aclTensor* out) { | 90 | +static inline bool CheckNotNull(const aclTensor* self, const aclIntArray* dim, const aclTensor* out) |
| 152 | - OP_CHECK_MAX_DIM(self, MAX_DIM_LEN, return false); | 91 | +{ |
| 153 | - OP_CHECK_MAX_DIM(out, MAX_DIM_LEN, return false); | 92 | + // dim也需要判空,需要获取dim中元素和个数 |
| 154 | - op::Shape reduceShape; | 93 | + OP_CHECK_NULL(self, return false); |
| 155 | - AmaxInferShape(self->GetViewShape(), dim, keepDim, reduceShape); | 94 | + OP_CHECK_NULL(dim, return false); |
| 156 | - | 95 | + OP_CHECK_NULL(out, return false); |
| 157 | - // out的shape必须满足Infer shape | 96 | + return true; |
| 158 | - OP_CHECK_SHAPE_NOT_EQUAL_WITH_EXPECTED_SIZE(out, reduceShape, return false); | ||
| 159 | - return true; | ||
| 160 | } | 97 | } |
| 161 | 98 | ||
| 162 | -static aclnnStatus CheckParams(const aclTensor* self, const aclIntArray* dim, const bool keepDim, | 99 | +static inline const std::initializer_list<op::DataType>& GetDtypeSupportList() |
| 163 | - const aclTensor* out) { | 100 | +{ |
| 164 | - // 1. 检查参数是否为空指针 | 101 | + if ((GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && |
| 165 | - CHECK_RET(CheckNotNull(self, dim, out), ACLNN_ERR_PARAM_NULLPTR); | 102 | + GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || |
| 166 | - | 103 | + IsRegBase()) { |
| 167 | - // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 | 104 | + return ASCEND910B_DTYPE_SUPPORT_LIST; |
| 168 | - CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); | 105 | + } else { |
| 169 | - | 106 | + return ASCEND910_DTYPE_SUPPORT_LIST; |
| 170 | - // 3. 检查reduce的轴是否超出self维度范围或者重复 | 107 | + } |
| 171 | - CHECK_RET(CheckDimValid(self, dim), ACLNN_ERR_PARAM_INVALID); | ||
| 172 | - | ||
| 173 | - // 4. 检查out的shape是否满足reduce推导 | ||
| 174 | - CHECK_RET(CheckShape(self, dim, keepDim, out), ACLNN_ERR_PARAM_INVALID); | ||
| 175 | - return ACLNN_SUCCESS; | ||
| 176 | } | 108 | } |
| 177 | 109 | ||
| 178 | -aclnnStatus aclnnAmaxGetWorkspaceSize(const aclTensor* self, const aclIntArray* dim, bool keepDim, aclTensor* out, | 110 | +static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) |
| 179 | - uint64_t* workspaceSize, aclOpExecutor** executor) { | 111 | +{ |
| 180 | - L2_DFX_PHASE_1(aclnnAmax, DFX_IN(self, dim, keepDim), DFX_OUT(out)); | 112 | + auto supportList = GetDtypeSupportList(); |
| 181 | - // 创建OpExecutor | 113 | + // 检查self与out的数据类型是否一致 |
| 182 | - auto uniqueExecutor = CREATE_EXECUTOR(); | 114 | + OP_CHECK_DTYPE_NOT_MATCH(out, self->GetDataType(), return false); |
| 183 | - CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | 115 | + // 检查self的数据类型是否支持, out与self一致,不需要额外检查 |
| 116 | + OP_CHECK_DTYPE_NOT_SUPPORT(self, supportList, return false); | ||
| 184 | 117 | ||
| 185 | - // 参数检查 | 118 | + return true; |
| 186 | - auto ret = CheckParams(self, dim, keepDim, out); | 119 | +} |
| 187 | - CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 188 | 120 | ||
| 189 | - // 算子的空tensor处理 | 121 | +static bool CheckDimValid(const aclTensor* self, const aclIntArray* dim) |
| 190 | - if (self->IsEmpty()) { | 122 | +{ |
| 191 | - *workspaceSize = 0; | 123 | + auto selfViewShape = self->GetViewShape(); |
| 192 | - uniqueExecutor.ReleaseTo(executor); | 124 | + auto selfDimNum = static_cast<int64_t>(selfViewShape.GetDimNum()); |
| 125 | + bool isScalar = false; | ||
| 126 | + // self为标量时,dim range [-1, 0] | ||
| 127 | + if (selfDimNum <= 0) { | ||
| 128 | + selfDimNum = 1; | ||
| 129 | + isScalar = true; | ||
| 130 | + } | ||
| 131 | + // dim为负时需要转正校验 | ||
| 132 | + bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 133 | + | ||
| 134 | + for (size_t i = 0; i < dim->Size(); i++) { | ||
| 135 | + if (dim->operator[](i) >= selfDimNum || dim->operator[](i) < (-selfDimNum)) { | ||
| 136 | + OP_LOGE( | ||
| 137 | + ACLNN_ERR_PARAM_INVALID, "Provided dim %ld must be in the range of [%ld, %ld].", dim->operator[](i), | ||
| 138 | + -selfDimNum, selfDimNum - 1); | ||
| 139 | + return false; | ||
| 140 | + } | ||
| 141 | + uint64_t index = GetPosDim(dim->operator[](i), selfDimNum); | ||
| 142 | + // 非标量reduce的dim不能为0 | ||
| 143 | + if (!isScalar && selfViewShape.GetDim(index) == 0) { | ||
| 144 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expected reducution dim %lu to have non-zero size.", index); | ||
| 145 | + return false; | ||
| 146 | + } | ||
| 147 | + // dim重复 | ||
| 148 | + if (dimMask[index]) { | ||
| 149 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | ||
| 150 | + return false; | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + dimMask.set(index); | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + return true; | ||
| 157 | +} | ||
| 158 | + | ||
| 159 | +static bool CheckShape(const aclTensor* self, const aclIntArray* dim, const bool keepDim, const aclTensor* out) | ||
| 160 | +{ | ||
| 161 | + OP_CHECK_MAX_DIM(self, MAX_DIM_LEN, return false); | ||
| 162 | + OP_CHECK_MAX_DIM(out, MAX_DIM_LEN, return false); | ||
| 163 | + op::Shape reduceShape; | ||
| 164 | + AmaxInferShape(self->GetViewShape(), dim, keepDim, reduceShape); | ||
| 165 | + | ||
| 166 | + // out的shape必须满足Infer shape | ||
| 167 | + OP_CHECK_SHAPE_NOT_EQUAL_WITH_EXPECTED_SIZE(out, reduceShape, return false); | ||
| 168 | + return true; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +static aclnnStatus CheckParams(const aclTensor* self, const aclIntArray* dim, const bool keepDim, const aclTensor* out) | ||
| 172 | +{ | ||
| 173 | + // 1. 检查参数是否为空指针 | ||
| 174 | + CHECK_RET(CheckNotNull(self, dim, out), ACLNN_ERR_PARAM_NULLPTR); | ||
| 175 | + | ||
| 176 | + // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 | ||
| 177 | + CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); | ||
| 178 | + | ||
| 179 | + // 3. 检查reduce的轴是否超出self维度范围或者重复 | ||
| 180 | + CHECK_RET(CheckDimValid(self, dim), ACLNN_ERR_PARAM_INVALID); | ||
| 181 | + | ||
| 182 | + // 4. 检查out的shape是否满足reduce推导 | ||
| 183 | + CHECK_RET(CheckShape(self, dim, keepDim, out), ACLNN_ERR_PARAM_INVALID); | ||
| 193 | return ACLNN_SUCCESS; | 184 | return ACLNN_SUCCESS; |
| 194 | - } | 185 | +} |
| 195 | 186 | ||
| 196 | - // 当输入tensor是0维时,直接将输入tensor作为输出返回 | 187 | +aclnnStatus aclnnAmaxGetWorkspaceSize( |
| 197 | - if (self->GetViewShape().GetDimNum() == 0) { | 188 | + const aclTensor* self, const aclIntArray* dim, bool keepDim, aclTensor* out, uint64_t* workspaceSize, |
| 198 | - auto viewCopyResult = l0op::ViewCopy(self, out, uniqueExecutor.get()); | 189 | + aclOpExecutor** executor) |
| 190 | +{ | ||
| 191 | + L2_DFX_PHASE_1(aclnnAmax, DFX_IN(self, dim, keepDim), DFX_OUT(out)); | ||
| 192 | + // 创建OpExecutor | ||
| 193 | + auto uniqueExecutor = CREATE_EXECUTOR(); | ||
| 194 | + CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | ||
| 195 | + | ||
| 196 | + // 参数检查 | ||
| 197 | + auto ret = CheckParams(self, dim, keepDim, out); | ||
| 198 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 199 | + | ||
| 200 | + // 算子的空tensor处理 | ||
| 201 | + if (self->IsEmpty()) { | ||
| 202 | + *workspaceSize = 0; | ||
| 203 | + uniqueExecutor.ReleaseTo(executor); | ||
| 204 | + return ACLNN_SUCCESS; | ||
| 205 | + } | ||
| 206 | + | ||
| 207 | + // 当输入tensor是0维时,直接将输入tensor作为输出返回 | ||
| 208 | + if (self->GetViewShape().GetDimNum() == 0) { | ||
| 209 | + auto viewCopyResult = l0op::ViewCopy(self, out, uniqueExecutor.get()); | ||
| 210 | + CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 211 | + *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 212 | + uniqueExecutor.ReleaseTo(executor); | ||
| 213 | + return ACLNN_SUCCESS; | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | + // 空dim处理 | ||
| 217 | + if (dim->Size() == 0) { | ||
| 218 | + dim = GetAllDims(self, uniqueExecutor.get()); | ||
| 219 | + CHECK_RET(dim != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 220 | + } | ||
| 221 | + | ||
| 222 | + // 将输入self转换成连续的tensor | ||
| 223 | + auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 224 | + CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 225 | + | ||
| 226 | + // 将输入self的数据类型转换成目标数据类型, bool 转为float, 其余保持原类型 | ||
| 227 | + op::DataType selfCastType = | ||
| 228 | + (self->GetDataType() == op::DataType::DT_BOOL) ? op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 229 | + | ||
| 230 | + auto selfCasted = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 231 | + CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 232 | + | ||
| 233 | + // 调用max算子kernel | ||
| 234 | + auto maxResult = l0op::ReduceMax(selfCasted, dim, keepDim, true, uniqueExecutor.get()); | ||
| 235 | + CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 236 | + | ||
| 237 | + // 将max算子的输出转换成目标数据类型, | ||
| 238 | + auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 239 | + CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 240 | + | ||
| 241 | + // 将计算结果拷贝到输出out上,out可能是非连续的tensor | ||
| 242 | + auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 199 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | 243 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 244 | + | ||
| 245 | + // 获取计算过程中需要使用的workspace大小 | ||
| 200 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | 246 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); |
| 247 | + // 需要把 uniqueExecutor持有executor转移给executor | ||
| 201 | uniqueExecutor.ReleaseTo(executor); | 248 | uniqueExecutor.ReleaseTo(executor); |
| 249 | + | ||
| 202 | return ACLNN_SUCCESS; | 250 | return ACLNN_SUCCESS; |
| 203 | - } | ||
| 204 | - | ||
| 205 | - // 空dim处理 | ||
| 206 | - if (dim->Size() == 0) { | ||
| 207 | - dim = GetAllDims(self, uniqueExecutor.get()); | ||
| 208 | - CHECK_RET(dim != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 209 | - } | ||
| 210 | - | ||
| 211 | - // 将输入self转换成连续的tensor | ||
| 212 | - auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 213 | - CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 214 | - | ||
| 215 | - // 将输入self的数据类型转换成目标数据类型, bool 转为float, 其余保持原类型 | ||
| 216 | - op::DataType selfCastType = | ||
| 217 | - (self->GetDataType() == op::DataType::DT_BOOL) ? op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 218 | - | ||
| 219 | - auto selfCasted = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 220 | - CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 221 | - | ||
| 222 | - // 调用max算子kernel | ||
| 223 | - auto maxResult = l0op::ReduceMax(selfCasted, dim, keepDim, true, uniqueExecutor.get()); | ||
| 224 | - CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 225 | - | ||
| 226 | - // 将max算子的输出转换成目标数据类型, | ||
| 227 | - auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 228 | - CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 229 | - | ||
| 230 | - // 将计算结果拷贝到输出out上,out可能是非连续的tensor | ||
| 231 | - auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 232 | - CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 233 | - | ||
| 234 | - // 获取计算过程中需要使用的workspace大小 | ||
| 235 | - *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 236 | - // 需要把 uniqueExecutor持有executor转移给executor | ||
| 237 | - uniqueExecutor.ReleaseTo(executor); | ||
| 238 | - | ||
| 239 | - return ACLNN_SUCCESS; | ||
| 240 | } | 251 | } |
| 241 | 252 | ||
| 242 | -aclnnStatus aclnnAmax(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) { | 253 | +aclnnStatus aclnnAmax(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) |
| 243 | - L2_DFX_PHASE_2(aclnnAmax); | 254 | +{ |
| 244 | - // 固定写法,调用框架能力,完成计算 | 255 | + L2_DFX_PHASE_2(aclnnAmax); |
| 245 | - return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | 256 | + // 固定写法,调用框架能力,完成计算 |
| 257 | + return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | ||
| 246 | } | 258 | } |
| 247 | 259 | ||
| 248 | 260 | ||
| @@ -34,8 +34,9 @@ extern "C" { | |||
| 34 | * @param [out] executor: 返回op执行器,包含算子计算流程。 | 34 | * @param [out] executor: 返回op执行器,包含算子计算流程。 |
| 35 | * @return aclnnStatus: 返回状态码。 | 35 | * @return aclnnStatus: 返回状态码。 |
| 36 | */ | 36 | */ |
| 37 | -ACLNN_API aclnnStatus aclnnAmaxGetWorkspaceSize(const aclTensor* self, const aclIntArray* dim, bool keepDim, | 37 | +ACLNN_API aclnnStatus aclnnAmaxGetWorkspaceSize( |
| 38 | - aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); | 38 | + const aclTensor* self, const aclIntArray* dim, bool keepDim, aclTensor* out, uint64_t* workspaceSize, |
| 39 | + aclOpExecutor** executor); | ||
| 39 | 40 | ||
| 40 | /** | 41 | /** |
| 41 | * @brief aclnnAmax的第二段接口,用于执行计算。 | 42 | * @brief aclnnAmax的第二段接口,用于执行计算。 |
| @@ -55,4 +56,4 @@ ACLNN_API aclnnStatus aclnnAmax(void* workspace, uint64_t workspaceSize, aclOpEx | |||
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | 58 | ||
| 58 | -#endif // OP_API_INC_AMAX_H_ | 59 | +#endif // OP_API_INC_AMAX_H_ |
| @@ -34,20 +34,20 @@ static const uint64_t GLOBAL_MAX_POOL_MAX_DIMS_NUMS = 8; | |||
| 34 | static const uint64_t DIM_NUMBER_TWO = 2; | 34 | static const uint64_t DIM_NUMBER_TWO = 2; |
| 35 | 35 | ||
| 36 | // 根据API定义,需要列出所能支持的所有dtype | 36 | // 根据API定义,需要列出所能支持的所有dtype |
| 37 | -static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST = { op::DataType::DT_FLOAT, | 37 | +static const std::initializer_list<op::DataType> DTYPE_SUPPORT_LIST = { |
| 38 | - op::DataType::DT_FLOAT16, op::DataType::DT_DOUBLE }; | 38 | + op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_DOUBLE}; |
| 39 | 39 | ||
| 40 | -static const std::initializer_list<op::Format> FORMAT_SUPPORT_LIST = { op::Format::FORMAT_ND, op::Format::FORMAT_NCHW, | 40 | +static const std::initializer_list<op::Format> FORMAT_SUPPORT_LIST = { |
| 41 | - op::Format::FORMAT_NCDHW }; | 41 | + op::Format::FORMAT_ND, op::Format::FORMAT_NCHW, op::Format::FORMAT_NCDHW}; |
| 42 | 42 | ||
| 43 | -static bool CheckNotNull(const aclTensor *self, const aclTensor *out) | 43 | +static bool CheckNotNull(const aclTensor* self, const aclTensor* out) |
| 44 | { | 44 | { |
| 45 | OP_CHECK_NULL(self, return false); | 45 | OP_CHECK_NULL(self, return false); |
| 46 | OP_CHECK_NULL(out, return false); | 46 | OP_CHECK_NULL(out, return false); |
| 47 | return true; | 47 | return true; |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | -static bool CheckDtypeValid(const aclTensor *self, const aclTensor *out) | 50 | +static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) |
| 51 | { | 51 | { |
| 52 | // 检查self的数据类型是否在支持列表内 | 52 | // 检查self的数据类型是否在支持列表内 |
| 53 | OP_CHECK_DTYPE_NOT_SUPPORT(self, DTYPE_SUPPORT_LIST, return false); | 53 | OP_CHECK_DTYPE_NOT_SUPPORT(self, DTYPE_SUPPORT_LIST, return false); |
| @@ -61,7 +61,7 @@ static bool CheckDtypeValid(const aclTensor *self, const aclTensor *out) | |||
| 61 | return true; | 61 | return true; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | -static bool CheckFormatValid(const aclTensor *self, const aclTensor *out) | 64 | +static bool CheckFormatValid(const aclTensor* self, const aclTensor* out) |
| 65 | { | 65 | { |
| 66 | op::Format selfFormat = self->GetStorageFormat(); | 66 | op::Format selfFormat = self->GetStorageFormat(); |
| 67 | op::Format outFormat = out->GetStorageFormat(); | 67 | op::Format outFormat = out->GetStorageFormat(); |
| @@ -77,7 +77,7 @@ static bool CheckFormatValid(const aclTensor *self, const aclTensor *out) | |||
| 77 | return formatValid; | 77 | return formatValid; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | -static bool CheckShape(const aclTensor *self, const aclTensor *out) | 80 | +static bool CheckShape(const aclTensor* self, const aclTensor* out) |
| 81 | { | 81 | { |
| 82 | OP_CHECK_MIN_DIM(self, GLOBAL_MAX_POOL_MIN_DIMS_NUMS, return false); | 82 | OP_CHECK_MIN_DIM(self, GLOBAL_MAX_POOL_MIN_DIMS_NUMS, return false); |
| 83 | OP_CHECK_MAX_DIM(self, GLOBAL_MAX_POOL_MAX_DIMS_NUMS, return false); | 83 | OP_CHECK_MAX_DIM(self, GLOBAL_MAX_POOL_MAX_DIMS_NUMS, return false); |
| @@ -85,7 +85,7 @@ static bool CheckShape(const aclTensor *self, const aclTensor *out) | |||
| 85 | 85 | ||
| 86 | auto selfShape = self->GetViewShape(); | 86 | auto selfShape = self->GetViewShape(); |
| 87 | op::Shape outShape; | 87 | op::Shape outShape; |
| 88 | - if(selfShape.GetDimNum() < DIM_NUMBER_TWO) { | 88 | + if (selfShape.GetDimNum() < DIM_NUMBER_TWO) { |
| 89 | return false; | 89 | return false; |
| 90 | } | 90 | } |
| 91 | outShape.AppendDim(selfShape.GetDim(0)); | 91 | outShape.AppendDim(selfShape.GetDim(0)); |
| @@ -97,7 +97,7 @@ static bool CheckShape(const aclTensor *self, const aclTensor *out) | |||
| 97 | return true; | 97 | return true; |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | -static aclnnStatus CheckParams(const aclTensor *self, const aclTensor *out) | 100 | +static aclnnStatus CheckParams(const aclTensor* self, const aclTensor* out) |
| 101 | { | 101 | { |
| 102 | // 1. 检查参数是否为空指针 | 102 | // 1. 检查参数是否为空指针 |
| 103 | CHECK_RET(CheckNotNull(self, out), ACLNN_ERR_PARAM_NULLPTR); | 103 | CHECK_RET(CheckNotNull(self, out), ACLNN_ERR_PARAM_NULLPTR); |
| @@ -114,8 +114,8 @@ static aclnnStatus CheckParams(const aclTensor *self, const aclTensor *out) | |||
| 114 | return ACLNN_SUCCESS; | 114 | return ACLNN_SUCCESS; |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | -aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor *self, aclTensor *out, uint64_t *workspaceSize, | 117 | +aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize( |
| 118 | - aclOpExecutor **executor) | 118 | + const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor) |
| 119 | { | 119 | { |
| 120 | L2_DFX_PHASE_1(aclnnGlobalMaxPool, DFX_IN(self), DFX_OUT(out)); | 120 | L2_DFX_PHASE_1(aclnnGlobalMaxPool, DFX_IN(self), DFX_OUT(out)); |
| 121 | 121 | ||
| @@ -137,7 +137,7 @@ aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor *self, aclTensor | |||
| 137 | for (int64_t i = 2; i < dimNum; i++) { | 137 | for (int64_t i = 2; i < dimNum; i++) { |
| 138 | dimVector.push_back(i); | 138 | dimVector.push_back(i); |
| 139 | } | 139 | } |
| 140 | - const aclIntArray *dim = aclCreateIntArray(dimVector.data(), dimNum - 2); | 140 | + const aclIntArray* dim = aclCreateIntArray(dimVector.data(), dimNum - 2); |
| 141 | 141 | ||
| 142 | // 调用max算子kernel | 142 | // 调用max算子kernel |
| 143 | auto maxOpOut = l0op::ReduceMax(selfContiguous, dim, true, true, uniqueExecutor.get()); | 143 | auto maxOpOut = l0op::ReduceMax(selfContiguous, dim, true, true, uniqueExecutor.get()); |
| @@ -153,8 +153,8 @@ aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor *self, aclTensor | |||
| 153 | return ACLNN_SUCCESS; | 153 | return ACLNN_SUCCESS; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | -aclnnStatus aclnnGlobalMaxPool(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, | 156 | +aclnnStatus aclnnGlobalMaxPool( |
| 157 | - const aclrtStream stream) | 157 | + void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream) |
| 158 | { | 158 | { |
| 159 | L2_DFX_PHASE_2(aclnnGlobalMaxPool); | 159 | L2_DFX_PHASE_2(aclnnGlobalMaxPool); |
| 160 | // 固定写法,调用框架能力,完成计算 | 160 | // 固定写法,调用框架能力,完成计算 |
| @@ -32,8 +32,8 @@ extern "C" { | |||
| 32 | * @param [out] executor: 返回op执行器,包含算子计算流程。 | 32 | * @param [out] executor: 返回op执行器,包含算子计算流程。 |
| 33 | * @return aclnnStatus: 返回状态码。 | 33 | * @return aclnnStatus: 返回状态码。 |
| 34 | */ | 34 | */ |
| 35 | -ACLNN_API aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, | 35 | +ACLNN_API aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize( |
| 36 | - aclOpExecutor** executor); | 36 | + const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); |
| 37 | 37 | ||
| 38 | /** | 38 | /** |
| 39 | * @brief aclnnGlobalMaxPool的第二段接口,用于执行计算。 | 39 | * @brief aclnnGlobalMaxPool的第二段接口,用于执行计算。 |
| @@ -46,11 +46,11 @@ ACLNN_API aclnnStatus aclnnGlobalMaxPoolGetWorkspaceSize(const aclTensor* self, | |||
| 46 | * @param [in] executor: op执行器,包含了算子计算流程。 | 46 | * @param [in] executor: op执行器,包含了算子计算流程。 |
| 47 | * @return aclnnStatus: 返回状态码。 | 47 | * @return aclnnStatus: 返回状态码。 |
| 48 | */ | 48 | */ |
| 49 | -ACLNN_API aclnnStatus aclnnGlobalMaxPool(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, | 49 | +ACLNN_API aclnnStatus |
| 50 | - const aclrtStream stream); | 50 | +aclnnGlobalMaxPool(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, const aclrtStream stream); |
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | -#endif // OP_API_INC_GLOBAL_MAX_POOL_H_ | 56 | +#endif // OP_API_INC_GLOBAL_MAX_POOL_H_ |
| @@ -38,115 +38,122 @@ static const std::initializer_list<DataType> DTYPE_SUPPORT_910_LIST = { | |||
| 38 | op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL}; | 38 | op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL}; |
| 39 | 39 | ||
| 40 | static const std::initializer_list<DataType> DTYPE_SUPPORT_GE910B_LIST = { | 40 | static const std::initializer_list<DataType> DTYPE_SUPPORT_GE910B_LIST = { |
| 41 | - op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, | 41 | + op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT8, |
| 42 | - op::DataType::DT_INT8, op::DataType::DT_INT16, op::DataType::DT_INT32, | 42 | + op::DataType::DT_INT16, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_DOUBLE, |
| 43 | - op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL, | 43 | + op::DataType::DT_BOOL, op::DataType::DT_BF16}; |
| 44 | - op::DataType::DT_BF16}; | ||
| 45 | 44 | ||
| 46 | -static bool CheckNotNull(const aclTensor *self, const aclTensor *out) { | 45 | +static bool CheckNotNull(const aclTensor* self, const aclTensor* out) |
| 47 | - OP_CHECK_NULL(self, return false); | 46 | +{ |
| 48 | - OP_CHECK_NULL(out, return false); | 47 | + OP_CHECK_NULL(self, return false); |
| 49 | - return true; | 48 | + OP_CHECK_NULL(out, return false); |
| 49 | + return true; | ||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | // 判断芯片类型是否大于等于910B | 52 | // 判断芯片类型是否大于等于910B |
| 53 | -static inline bool CheckSocVersionGe910B(void) { | 53 | +static inline bool CheckSocVersionGe910B(void) |
| 54 | - return (GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && | 54 | +{ |
| 55 | - GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || | 55 | + return (GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && |
| 56 | - IsRegBase(); | 56 | + GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || |
| 57 | + IsRegBase(); | ||
| 57 | } | 58 | } |
| 58 | 59 | ||
| 59 | -static bool CheckDtypeValid(const aclTensor *self, const aclTensor *out) { | 60 | +static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) |
| 60 | - // 获取芯片类型,判断是1971还是1980 | 61 | +{ |
| 61 | - bool is910BSocVersion = CheckSocVersionGe910B(); | 62 | + // 获取芯片类型,判断是1971还是1980 |
| 62 | - const std::initializer_list<DataType> CURRENT_DTYPE_SUPPORT_LIST = | 63 | + bool is910BSocVersion = CheckSocVersionGe910B(); |
| 63 | - is910BSocVersion ? DTYPE_SUPPORT_GE910B_LIST : DTYPE_SUPPORT_910_LIST; | 64 | + const std::initializer_list<DataType> CURRENT_DTYPE_SUPPORT_LIST = |
| 65 | + is910BSocVersion ? DTYPE_SUPPORT_GE910B_LIST : DTYPE_SUPPORT_910_LIST; | ||
| 64 | 66 | ||
| 65 | - OP_CHECK_DTYPE_NOT_SUPPORT(self, CURRENT_DTYPE_SUPPORT_LIST, return false); | 67 | + OP_CHECK_DTYPE_NOT_SUPPORT(self, CURRENT_DTYPE_SUPPORT_LIST, return false); |
| 66 | - OP_CHECK_DTYPE_NOT_SUPPORT(out, CURRENT_DTYPE_SUPPORT_LIST, return false); | 68 | + OP_CHECK_DTYPE_NOT_SUPPORT(out, CURRENT_DTYPE_SUPPORT_LIST, return false); |
| 67 | - return true; | 69 | + return true; |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | -static bool CheckShape(const aclTensor *self, const aclTensor *out) { | 72 | +static bool CheckShape(const aclTensor* self, const aclTensor* out) |
| 71 | - OP_CHECK_MAX_DIM(self, MAX_DIM, return false); | 73 | +{ |
| 72 | - OP_CHECK_MAX_DIM(out, MAX_DIM, return false); | 74 | + OP_CHECK_MAX_DIM(self, MAX_DIM, return false); |
| 73 | - return true; | 75 | + OP_CHECK_MAX_DIM(out, MAX_DIM, return false); |
| 76 | + return true; | ||
| 74 | } | 77 | } |
| 75 | 78 | ||
| 76 | -static aclnnStatus CheckParams(const aclTensor *self, const aclTensor *out) { | 79 | +static aclnnStatus CheckParams(const aclTensor* self, const aclTensor* out) |
| 77 | - // 1. 检查参数是否为空指针 | 80 | +{ |
| 78 | - CHECK_RET(CheckNotNull(self, out), ACLNN_ERR_PARAM_NULLPTR); | 81 | + // 1. 检查参数是否为空指针 |
| 82 | + CHECK_RET(CheckNotNull(self, out), ACLNN_ERR_PARAM_NULLPTR); | ||
| 79 | 83 | ||
| 80 | - // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 | 84 | + // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 |
| 81 | - CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); | 85 | + CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); |
| 82 | 86 | ||
| 83 | - // 3. 检查shape是否满足约束 | 87 | + // 3. 检查shape是否满足约束 |
| 84 | - CHECK_RET(CheckShape(self, out), ACLNN_ERR_PARAM_INVALID); | 88 | + CHECK_RET(CheckShape(self, out), ACLNN_ERR_PARAM_INVALID); |
| 85 | 89 | ||
| 86 | - return ACLNN_SUCCESS; | 90 | + return ACLNN_SUCCESS; |
| 87 | } | 91 | } |
| 88 | 92 | ||
| 89 | -aclIntArray *GetMaxDimListForTensor(const aclTensor *self, aclOpExecutor *executor) { | 93 | +aclIntArray* GetMaxDimListForTensor(const aclTensor* self, aclOpExecutor* executor) |
| 90 | - uint64_t dimNum = self->GetViewShape().GetDimNum(); | 94 | +{ |
| 91 | - int64_t dimList[dimNum]; | 95 | + uint64_t dimNum = self->GetViewShape().GetDimNum(); |
| 92 | - for (size_t i = 0; i < dimNum; i++) { | 96 | + int64_t dimList[dimNum]; |
| 93 | - dimList[i] = i; | 97 | + for (size_t i = 0; i < dimNum; i++) { |
| 94 | - } | 98 | + dimList[i] = i; |
| 95 | - aclIntArray *dim = executor->AllocIntArray(dimList, dimNum); | 99 | + } |
| 96 | - return dim; | 100 | + aclIntArray* dim = executor->AllocIntArray(dimList, dimNum); |
| 101 | + return dim; | ||
| 97 | } | 102 | } |
| 98 | 103 | ||
| 99 | -aclnnStatus aclnnMaxGetWorkspaceSize(const aclTensor *self, aclTensor *out, uint64_t *workspaceSize, | 104 | +aclnnStatus aclnnMaxGetWorkspaceSize( |
| 100 | - aclOpExecutor **executor) { | 105 | + const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor) |
| 101 | - L2_DFX_PHASE_1(aclnnMax, DFX_IN(self), DFX_OUT(out)); | 106 | +{ |
| 107 | + L2_DFX_PHASE_1(aclnnMax, DFX_IN(self), DFX_OUT(out)); | ||
| 102 | 108 | ||
| 103 | - // 参数检查 | 109 | + // 参数检查 |
| 104 | - auto ret = CheckParams(self, out); | 110 | + auto ret = CheckParams(self, out); |
| 105 | - CHECK_RET(ret == ACLNN_SUCCESS, ret); | 111 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); |
| 106 | 112 | ||
| 107 | - // 创建OpExecutor | 113 | + // 创建OpExecutor |
| 108 | - auto uniqueExecutor = CREATE_EXECUTOR(); | 114 | + auto uniqueExecutor = CREATE_EXECUTOR(); |
| 109 | - CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | 115 | + CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); |
| 110 | 116 | ||
| 111 | - auto dim = GetMaxDimListForTensor(self, uniqueExecutor.get()); | 117 | + auto dim = GetMaxDimListForTensor(self, uniqueExecutor.get()); |
| 112 | 118 | ||
| 113 | - // 空Tensor处理 | 119 | + // 空Tensor处理 |
| 114 | - if (self->IsEmpty() || out->IsEmpty()) { | 120 | + if (self->IsEmpty() || out->IsEmpty()) { |
| 115 | - *workspaceSize = 0; | 121 | + *workspaceSize = 0; |
| 122 | + uniqueExecutor.ReleaseTo(executor); | ||
| 123 | + return ACLNN_SUCCESS; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + // self如果非连续,需要转连续 | ||
| 127 | + auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 128 | + CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 129 | + | ||
| 130 | + DataType selfCastType = | ||
| 131 | + (self->GetDataType() == op::DataType::DT_BOOL) ? op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 132 | + auto selfCast = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 133 | + CHECK_RET(selfCast != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 134 | + | ||
| 135 | + // 调用l0算子Max进行计算 | ||
| 136 | + auto maxResult = l0op::ReduceMax(selfCast, dim, false, true, uniqueExecutor.get()); | ||
| 137 | + CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 138 | + CHECK_RET(CheckShapeAndScalarSame(maxResult, out), ACLNN_ERR_PARAM_INVALID); | ||
| 139 | + | ||
| 140 | + auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 141 | + CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 142 | + | ||
| 143 | + // 如果出参out是非连续Tensor,需要把计算完的连续Tensor转非连续 | ||
| 144 | + auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 145 | + CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 146 | + | ||
| 147 | + // 获取计算过程中需要使用的workspace大小 | ||
| 148 | + *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 116 | uniqueExecutor.ReleaseTo(executor); | 149 | uniqueExecutor.ReleaseTo(executor); |
| 117 | return ACLNN_SUCCESS; | 150 | return ACLNN_SUCCESS; |
| 118 | - } | ||
| 119 | - | ||
| 120 | - // self如果非连续,需要转连续 | ||
| 121 | - auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 122 | - CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 123 | - | ||
| 124 | - DataType selfCastType = (self->GetDataType() == op::DataType::DT_BOOL) ? | ||
| 125 | - op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 126 | - auto selfCast = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 127 | - CHECK_RET(selfCast != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 128 | - | ||
| 129 | - // 调用l0算子Max进行计算 | ||
| 130 | - auto maxResult = l0op::ReduceMax(selfCast, dim, false, true, uniqueExecutor.get()); | ||
| 131 | - CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 132 | - CHECK_RET(CheckShapeAndScalarSame(maxResult, out), ACLNN_ERR_PARAM_INVALID); | ||
| 133 | - | ||
| 134 | - auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 135 | - CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 136 | - | ||
| 137 | - // 如果出参out是非连续Tensor,需要把计算完的连续Tensor转非连续 | ||
| 138 | - auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 139 | - CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 140 | - | ||
| 141 | - // 获取计算过程中需要使用的workspace大小 | ||
| 142 | - *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 143 | - uniqueExecutor.ReleaseTo(executor); | ||
| 144 | - return ACLNN_SUCCESS; | ||
| 145 | } | 151 | } |
| 146 | 152 | ||
| 147 | -aclnnStatus aclnnMax(void *workspace, uint64_t workspaceSize, aclOpExecutor *executor, aclrtStream stream) { | 153 | +aclnnStatus aclnnMax(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) |
| 148 | - L2_DFX_PHASE_2(aclnnMax); | 154 | +{ |
| 149 | - return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | 155 | + L2_DFX_PHASE_2(aclnnMax); |
| 156 | + return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | ||
| 150 | } | 157 | } |
| 151 | 158 | ||
| 152 | 159 | ||
| @@ -26,8 +26,8 @@ extern "C" { | |||
| 26 | * @param [out] executor: 返回op执行器,包含算子计算流程。 | 26 | * @param [out] executor: 返回op执行器,包含算子计算流程。 |
| 27 | * @return aclnnStatus: 返回状态码。 | 27 | * @return aclnnStatus: 返回状态码。 |
| 28 | */ | 28 | */ |
| 29 | -ACLNN_API aclnnStatus aclnnMaxGetWorkspaceSize(const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, | 29 | +ACLNN_API aclnnStatus |
| 30 | - aclOpExecutor** executor); | 30 | +aclnnMaxGetWorkspaceSize(const aclTensor* self, aclTensor* out, uint64_t* workspaceSize, aclOpExecutor** executor); |
| 31 | 31 | ||
| 32 | /** | 32 | /** |
| 33 | * @brief aclnnMax的第二段接口,用于执行计算。 | 33 | * @brief aclnnMax的第二段接口,用于执行计算。 |
| @@ -43,4 +43,4 @@ ACLNN_API aclnnStatus aclnnMax(void* workspace, uint64_t workspaceSize, aclOpExe | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | -#endif // OP_API_INC_MAX_H_ | 46 | +#endif // OP_API_INC_MAX_H_ |
| @@ -43,225 +43,239 @@ static const std::initializer_list<op::DataType> ASCEND910_DTYPE_SUPPORT_LIST = | |||
| 43 | op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL}; | 43 | op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL}; |
| 44 | 44 | ||
| 45 | static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { | 45 | static const std::initializer_list<op::DataType> ASCEND910B_DTYPE_SUPPORT_LIST = { |
| 46 | - op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, | 46 | + op::DataType::DT_FLOAT, op::DataType::DT_FLOAT16, op::DataType::DT_UINT8, op::DataType::DT_INT8, |
| 47 | - op::DataType::DT_INT8, op::DataType::DT_INT16, op::DataType::DT_INT32, | 47 | + op::DataType::DT_INT16, op::DataType::DT_INT32, op::DataType::DT_INT64, op::DataType::DT_DOUBLE, |
| 48 | - op::DataType::DT_INT64, op::DataType::DT_DOUBLE, op::DataType::DT_BOOL, | 48 | + op::DataType::DT_BOOL, op::DataType::DT_BF16}; |
| 49 | - op::DataType::DT_BF16}; | ||
| 50 | 49 | ||
| 51 | -static inline bool CheckNotNull(const aclTensor* self, const aclIntArray* dims, const aclTensor* out) { | 50 | +static inline bool CheckNotNull(const aclTensor* self, const aclIntArray* dims, const aclTensor* out) |
| 52 | - OP_CHECK_NULL(self, return false); | 51 | +{ |
| 53 | - OP_CHECK_NULL(dims, return false); | 52 | + OP_CHECK_NULL(self, return false); |
| 54 | - OP_CHECK_NULL(out, return false); | 53 | + OP_CHECK_NULL(dims, return false); |
| 55 | - return true; | 54 | + OP_CHECK_NULL(out, return false); |
| 55 | + return true; | ||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | -static inline const std::initializer_list<op::DataType>& GetDtypeSupportList() { | 58 | +static inline const std::initializer_list<op::DataType>& GetDtypeSupportList() |
| 59 | - if ((GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && | 59 | +{ |
| 60 | - GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || | 60 | + if ((GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && |
| 61 | - IsRegBase()) { | 61 | + GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || |
| 62 | - return ASCEND910B_DTYPE_SUPPORT_LIST; | 62 | + IsRegBase()) { |
| 63 | - } else { | 63 | + return ASCEND910B_DTYPE_SUPPORT_LIST; |
| 64 | - return ASCEND910_DTYPE_SUPPORT_LIST; | ||
| 65 | - } | ||
| 66 | -} | ||
| 67 | - | ||
| 68 | -static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) { | ||
| 69 | - auto supportList = GetDtypeSupportList(); | ||
| 70 | - // 检查self与out的数据类型是否一致 | ||
| 71 | - OP_CHECK_DTYPE_NOT_MATCH(out, self->GetDataType(), return false); | ||
| 72 | - // 检查self的数据类型是否支持, out与self一致,不需要额外检查 | ||
| 73 | - OP_CHECK_DTYPE_NOT_SUPPORT(self, supportList, return false); | ||
| 74 | - return true; | ||
| 75 | -} | ||
| 76 | - | ||
| 77 | -static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) { | ||
| 78 | - if (dimNum <= 0) { | ||
| 79 | - dimNum = 1; | ||
| 80 | - } | ||
| 81 | - return dim >= 0 ? dim : dim + dimNum; | ||
| 82 | -} | ||
| 83 | - | ||
| 84 | -static inline const aclIntArray* GetAllDims(const aclTensor* self, const bool noopWithEmptyDims, | ||
| 85 | - aclOpExecutor* executor) { | ||
| 86 | - auto inputShape = self->GetViewShape(); | ||
| 87 | - size_t inputDimNum = inputShape.GetDimNum(); | ||
| 88 | - FVector<int64_t> dims; | ||
| 89 | - if (!noopWithEmptyDims) { | ||
| 90 | - for (size_t idx = 0; idx < inputDimNum; idx++) { | ||
| 91 | - dims.emplace_back(idx); | ||
| 92 | - } | ||
| 93 | - } | ||
| 94 | - return executor->AllocIntArray(dims.data(), dims.size()); | ||
| 95 | -} | ||
| 96 | - | ||
| 97 | -static void reduce_maxInferShape(const op::Shape& selfShape, const aclIntArray* dims, bool keepDims, | ||
| 98 | - const bool noopWithEmptyDims, op::Shape& reduceShape) { | ||
| 99 | - bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 100 | - | ||
| 101 | - if (dims->Size() == 0) { | ||
| 102 | - if (noopWithEmptyDims) { | ||
| 103 | - for (size_t i = 0; i < selfShape.GetDimNum(); ++i) { | ||
| 104 | - reduceShape.AppendDim(selfShape.GetDim(i)); | ||
| 105 | - } | ||
| 106 | - return; | ||
| 107 | } else { | 64 | } else { |
| 108 | - if (keepDims) { | 65 | + return ASCEND910_DTYPE_SUPPORT_LIST; |
| 109 | - for (size_t i = 0; i < selfShape.GetDimNum(); i++) { | 66 | + } |
| 110 | - reduceShape.AppendDim(1); | 67 | +} |
| 68 | + | ||
| 69 | +static bool CheckDtypeValid(const aclTensor* self, const aclTensor* out) | ||
| 70 | +{ | ||
| 71 | + auto supportList = GetDtypeSupportList(); | ||
| 72 | + // 检查self与out的数据类型是否一致 | ||
| 73 | + OP_CHECK_DTYPE_NOT_MATCH(out, self->GetDataType(), return false); | ||
| 74 | + // 检查self的数据类型是否支持, out与self一致,不需要额外检查 | ||
| 75 | + OP_CHECK_DTYPE_NOT_SUPPORT(self, supportList, return false); | ||
| 76 | + return true; | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +static inline uint64_t GetPosDim(int64_t dim, int64_t dimNum) | ||
| 80 | +{ | ||
| 81 | + if (dimNum <= 0) { | ||
| 82 | + dimNum = 1; | ||
| 83 | + } | ||
| 84 | + return dim >= 0 ? dim : dim + dimNum; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +static inline const aclIntArray* GetAllDims( | ||
| 88 | + const aclTensor* self, const bool noopWithEmptyDims, aclOpExecutor* executor) | ||
| 89 | +{ | ||
| 90 | + auto inputShape = self->GetViewShape(); | ||
| 91 | + size_t inputDimNum = inputShape.GetDimNum(); | ||
| 92 | + FVector<int64_t> dims; | ||
| 93 | + if (!noopWithEmptyDims) { | ||
| 94 | + for (size_t idx = 0; idx < inputDimNum; idx++) { | ||
| 95 | + dims.emplace_back(idx); | ||
| 111 | } | 96 | } |
| 112 | - } | ||
| 113 | - return; | ||
| 114 | } | 97 | } |
| 115 | - } | 98 | + return executor->AllocIntArray(dims.data(), dims.size()); |
| 116 | - | ||
| 117 | - for (size_t i = 0; i < dims->Size(); i++) { | ||
| 118 | - int64_t index = GetPosDim(dims->operator[](i), selfShape.GetDimNum()); | ||
| 119 | - // 前序已检查, 此处如果dim不会重复 | ||
| 120 | - dimMask.set(index); | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - for (size_t i = 0; i < selfShape.GetDimNum(); i++) { | ||
| 124 | - if (!dimMask[i]) { | ||
| 125 | - reduceShape.AppendDim(selfShape.GetDim(i)); | ||
| 126 | - } else if (keepDims) { | ||
| 127 | - reduceShape.AppendDim(1); | ||
| 128 | - } | ||
| 129 | - } | ||
| 130 | } | 99 | } |
| 131 | 100 | ||
| 132 | -static bool CheckDimValid(const aclTensor* self, const aclIntArray* dims) { | 101 | +static void reduce_maxInferShape( |
| 133 | - auto selfViewShape = self->GetViewShape(); | 102 | + const op::Shape& selfShape, const aclIntArray* dims, bool keepDims, const bool noopWithEmptyDims, |
| 134 | - auto selfDimNum = static_cast<int64_t>(selfViewShape.GetDimNum()); | 103 | + op::Shape& reduceShape) |
| 135 | - bool isScalar = false; | 104 | +{ |
| 136 | - // self为标量时,dim range [-1, 0] | 105 | + bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); |
| 137 | - if (selfDimNum <= 0) { | ||
| 138 | - selfDimNum = 1; | ||
| 139 | - isScalar = true; | ||
| 140 | - } | ||
| 141 | - // dim为负时需要转正校验 | ||
| 142 | - bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 143 | 106 | ||
| 144 | - for (size_t i = 0; i < dims->Size(); i++) { | 107 | + if (dims->Size() == 0) { |
| 145 | - if (dims->operator[](i) >= selfDimNum || dims->operator[](i) < (-selfDimNum)) { | 108 | + if (noopWithEmptyDims) { |
| 146 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Provided dims %ld must be in the range of [%ld, %ld].", | 109 | + for (size_t i = 0; i < selfShape.GetDimNum(); ++i) { |
| 147 | - dims->operator[](i), -selfDimNum, selfDimNum - 1); | 110 | + reduceShape.AppendDim(selfShape.GetDim(i)); |
| 148 | - return false; | 111 | + } |
| 149 | - } | 112 | + return; |
| 150 | - uint64_t index = GetPosDim(dims->operator[](i), selfDimNum); | 113 | + } else { |
| 151 | - // 非标量reduce的dims不能为0 | 114 | + if (keepDims) { |
| 152 | - if (!isScalar && selfViewShape.GetDim(index) == 0) { | 115 | + for (size_t i = 0; i < selfShape.GetDimNum(); i++) { |
| 153 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expected reducution dims %lu to have non-zero size.", index); | 116 | + reduceShape.AppendDim(1); |
| 154 | - return false; | 117 | + } |
| 155 | - } | 118 | + } |
| 156 | - // dims重复 | 119 | + return; |
| 157 | - if (dimMask[index]) { | 120 | + } |
| 158 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | ||
| 159 | - return false; | ||
| 160 | } | 121 | } |
| 161 | 122 | ||
| 162 | - dimMask.set(index); | 123 | + for (size_t i = 0; i < dims->Size(); i++) { |
| 163 | - } | 124 | + int64_t index = GetPosDim(dims->operator[](i), selfShape.GetDimNum()); |
| 125 | + // 前序已检查, 此处如果dim不会重复 | ||
| 126 | + dimMask.set(index); | ||
| 127 | + } | ||
| 164 | 128 | ||
| 165 | - return true; | 129 | + for (size_t i = 0; i < selfShape.GetDimNum(); i++) { |
| 130 | + if (!dimMask[i]) { | ||
| 131 | + reduceShape.AppendDim(selfShape.GetDim(i)); | ||
| 132 | + } else if (keepDims) { | ||
| 133 | + reduceShape.AppendDim(1); | ||
| 134 | + } | ||
| 135 | + } | ||
| 166 | } | 136 | } |
| 167 | 137 | ||
| 168 | -static bool CheckShape(const aclTensor* self, const aclIntArray* dims, const bool keepDims, | 138 | +static bool CheckDimValid(const aclTensor* self, const aclIntArray* dims) |
| 169 | - const bool noopWithEmptyDims, const aclTensor* out) { | 139 | +{ |
| 170 | - OP_CHECK_MAX_DIM(self, MAX_SUPPORT_DIMS_NUMS, return false); | 140 | + auto selfViewShape = self->GetViewShape(); |
| 171 | - OP_CHECK_MAX_DIM(out, MAX_SUPPORT_DIMS_NUMS, return false); | 141 | + auto selfDimNum = static_cast<int64_t>(selfViewShape.GetDimNum()); |
| 172 | - op::Shape reduceShape; | 142 | + bool isScalar = false; |
| 173 | - reduce_maxInferShape(self->GetViewShape(), dims, keepDims, noopWithEmptyDims, reduceShape); | 143 | + // self为标量时,dim range [-1, 0] |
| 144 | + if (selfDimNum <= 0) { | ||
| 145 | + selfDimNum = 1; | ||
| 146 | + isScalar = true; | ||
| 147 | + } | ||
| 148 | + // dim为负时需要转正校验 | ||
| 149 | + bitset<MAX_MASK_LEN> dimMask = bitset<MAX_MASK_LEN>(); | ||
| 174 | 150 | ||
| 175 | - // out的shape必须满足Infer shape | 151 | + for (size_t i = 0; i < dims->Size(); i++) { |
| 176 | - OP_CHECK_SHAPE_NOT_EQUAL_WITH_EXPECTED_SIZE(out, reduceShape, return false); | 152 | + if (dims->operator[](i) >= selfDimNum || dims->operator[](i) < (-selfDimNum)) { |
| 177 | - return true; | 153 | + OP_LOGE( |
| 154 | + ACLNN_ERR_PARAM_INVALID, "Provided dims %ld must be in the range of [%ld, %ld].", dims->operator[](i), | ||
| 155 | + -selfDimNum, selfDimNum - 1); | ||
| 156 | + return false; | ||
| 157 | + } | ||
| 158 | + uint64_t index = GetPosDim(dims->operator[](i), selfDimNum); | ||
| 159 | + // 非标量reduce的dims不能为0 | ||
| 160 | + if (!isScalar && selfViewShape.GetDim(index) == 0) { | ||
| 161 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Expected reducution dims %lu to have non-zero size.", index); | ||
| 162 | + return false; | ||
| 163 | + } | ||
| 164 | + // dims重复 | ||
| 165 | + if (dimMask[index]) { | ||
| 166 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "Dim %lu appears multiple times in the list of dims.", index); | ||
| 167 | + return false; | ||
| 168 | + } | ||
| 169 | + | ||
| 170 | + dimMask.set(index); | ||
| 171 | + } | ||
| 172 | + | ||
| 173 | + return true; | ||
| 178 | } | 174 | } |
| 179 | 175 | ||
| 180 | -static aclnnStatus CheckParams(const aclTensor* self, const aclIntArray* dims, const bool keepDims, | 176 | +static bool CheckShape( |
| 181 | - const bool noopWithEmptyDims, const aclTensor* out) { | 177 | + const aclTensor* self, const aclIntArray* dims, const bool keepDims, const bool noopWithEmptyDims, |
| 182 | - // 1. 检查参数是否为空指针 | 178 | + const aclTensor* out) |
| 183 | - CHECK_RET(CheckNotNull(self, dims, out), ACLNN_ERR_PARAM_NULLPTR); | 179 | +{ |
| 180 | + OP_CHECK_MAX_DIM(self, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 181 | + OP_CHECK_MAX_DIM(out, MAX_SUPPORT_DIMS_NUMS, return false); | ||
| 182 | + op::Shape reduceShape; | ||
| 183 | + reduce_maxInferShape(self->GetViewShape(), dims, keepDims, noopWithEmptyDims, reduceShape); | ||
| 184 | 184 | ||
| 185 | - // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 | 185 | + // out的shape必须满足Infer shape |
| 186 | - CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); | 186 | + OP_CHECK_SHAPE_NOT_EQUAL_WITH_EXPECTED_SIZE(out, reduceShape, return false); |
| 187 | - | 187 | + return true; |
| 188 | - // 3. 检查reduce的轴是否超出self维度范围或者重复 | ||
| 189 | - CHECK_RET(CheckDimValid(self, dims), ACLNN_ERR_PARAM_INVALID); | ||
| 190 | - | ||
| 191 | - // 4. 检查out的shape是否满足reduce推导 | ||
| 192 | - CHECK_RET(CheckShape(self, dims, keepDims, noopWithEmptyDims, out), ACLNN_ERR_PARAM_INVALID); | ||
| 193 | - return ACLNN_SUCCESS; | ||
| 194 | } | 188 | } |
| 195 | 189 | ||
| 196 | -aclnnStatus aclnnMaxV2GetWorkspaceSize(const aclTensor* self, const aclIntArray* dims, const bool keepDims, | 190 | +static aclnnStatus CheckParams( |
| 197 | - bool noopWithEmptyDims, aclTensor* out, uint64_t* workspaceSize, | 191 | + const aclTensor* self, const aclIntArray* dims, const bool keepDims, const bool noopWithEmptyDims, |
| 198 | - aclOpExecutor** executor) { | 192 | + const aclTensor* out) |
| 199 | - L2_DFX_PHASE_1(aclnnMaxV2, DFX_IN(self, dims, keepDims, noopWithEmptyDims), DFX_OUT(out)); | 193 | +{ |
| 200 | - // 创建OpExecutor | 194 | + // 1. 检查参数是否为空指针 |
| 201 | - auto uniqueExecutor = CREATE_EXECUTOR(); | 195 | + CHECK_RET(CheckNotNull(self, dims, out), ACLNN_ERR_PARAM_NULLPTR); |
| 202 | - CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | ||
| 203 | 196 | ||
| 204 | - // 参数检查 | 197 | + // 2. 检查输入的数据类型是否在API支持的数据类型范围之内 |
| 205 | - auto ret = CheckParams(self, dims, keepDims, noopWithEmptyDims, out); | 198 | + CHECK_RET(CheckDtypeValid(self, out), ACLNN_ERR_PARAM_INVALID); |
| 206 | - CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 207 | 199 | ||
| 208 | - // 算子的空tensor处理 | 200 | + // 3. 检查reduce的轴是否超出self维度范围或者重复 |
| 209 | - if (self->IsEmpty()) { | 201 | + CHECK_RET(CheckDimValid(self, dims), ACLNN_ERR_PARAM_INVALID); |
| 210 | - *workspaceSize = 0; | 202 | + |
| 211 | - uniqueExecutor.ReleaseTo(executor); | 203 | + // 4. 检查out的shape是否满足reduce推导 |
| 204 | + CHECK_RET(CheckShape(self, dims, keepDims, noopWithEmptyDims, out), ACLNN_ERR_PARAM_INVALID); | ||
| 212 | return ACLNN_SUCCESS; | 205 | return ACLNN_SUCCESS; |
| 213 | - } | 206 | +} |
| 214 | 207 | ||
| 215 | - // 当输入tensor是0维时,直接将输入tensor作为输出返回 | 208 | +aclnnStatus aclnnMaxV2GetWorkspaceSize( |
| 216 | - if (self->GetViewShape().GetDimNum() == 0) { | 209 | + const aclTensor* self, const aclIntArray* dims, const bool keepDims, bool noopWithEmptyDims, aclTensor* out, |
| 217 | - auto viewCopyResult = l0op::ViewCopy(self, out, uniqueExecutor.get()); | 210 | + uint64_t* workspaceSize, aclOpExecutor** executor) |
| 211 | +{ | ||
| 212 | + L2_DFX_PHASE_1(aclnnMaxV2, DFX_IN(self, dims, keepDims, noopWithEmptyDims), DFX_OUT(out)); | ||
| 213 | + // 创建OpExecutor | ||
| 214 | + auto uniqueExecutor = CREATE_EXECUTOR(); | ||
| 215 | + CHECK_RET(uniqueExecutor.get() != nullptr, ACLNN_ERR_INNER_CREATE_EXECUTOR); | ||
| 216 | + | ||
| 217 | + // 参数检查 | ||
| 218 | + auto ret = CheckParams(self, dims, keepDims, noopWithEmptyDims, out); | ||
| 219 | + CHECK_RET(ret == ACLNN_SUCCESS, ret); | ||
| 220 | + | ||
| 221 | + // 算子的空tensor处理 | ||
| 222 | + if (self->IsEmpty()) { | ||
| 223 | + *workspaceSize = 0; | ||
| 224 | + uniqueExecutor.ReleaseTo(executor); | ||
| 225 | + return ACLNN_SUCCESS; | ||
| 226 | + } | ||
| 227 | + | ||
| 228 | + // 当输入tensor是0维时,直接将输入tensor作为输出返回 | ||
| 229 | + if (self->GetViewShape().GetDimNum() == 0) { | ||
| 230 | + auto viewCopyResult = l0op::ViewCopy(self, out, uniqueExecutor.get()); | ||
| 231 | + CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 232 | + *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 233 | + uniqueExecutor.ReleaseTo(executor); | ||
| 234 | + return ACLNN_SUCCESS; | ||
| 235 | + } | ||
| 236 | + | ||
| 237 | + // 空dims处理 | ||
| 238 | + if (dims->Size() == 0) { | ||
| 239 | + dims = GetAllDims(self, noopWithEmptyDims, uniqueExecutor.get()); | ||
| 240 | + CHECK_RET(dims != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + // 将输入self转换成连续的tensor | ||
| 244 | + auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 245 | + CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 246 | + | ||
| 247 | + // 将输入self的数据类型转换成目标数据类型, bool 转为float, 其余保持原类型 | ||
| 248 | + op::DataType selfCastType = | ||
| 249 | + (self->GetDataType() == op::DataType::DT_BOOL) ? op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 250 | + | ||
| 251 | + auto selfCasted = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 252 | + CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 253 | + | ||
| 254 | + // 调用max算子kernel | ||
| 255 | + auto maxResult = l0op::ReduceMax(selfCasted, dims, keepDims, noopWithEmptyDims, uniqueExecutor.get()); | ||
| 256 | + CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 257 | + | ||
| 258 | + // 将max算子的输出转换成目标数据类型, | ||
| 259 | + auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 260 | + CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 261 | + | ||
| 262 | + // 将计算结果拷贝到输出out上,out可能是非连续的tensor | ||
| 263 | + auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 218 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | 264 | CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); |
| 265 | + | ||
| 266 | + // 获取计算过程中需要使用的workspace大小 | ||
| 219 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | 267 | *workspaceSize = uniqueExecutor->GetWorkspaceSize(); |
| 268 | + // 需要把 uniqueExecutor持有executor转移给executor | ||
| 220 | uniqueExecutor.ReleaseTo(executor); | 269 | uniqueExecutor.ReleaseTo(executor); |
| 270 | + | ||
| 221 | return ACLNN_SUCCESS; | 271 | return ACLNN_SUCCESS; |
| 222 | - } | ||
| 223 | - | ||
| 224 | - // 空dims处理 | ||
| 225 | - if (dims->Size() == 0) { | ||
| 226 | - dims = GetAllDims(self, noopWithEmptyDims, uniqueExecutor.get()); | ||
| 227 | - CHECK_RET(dims != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 228 | - } | ||
| 229 | - | ||
| 230 | - // 将输入self转换成连续的tensor | ||
| 231 | - auto selfContiguous = l0op::Contiguous(self, uniqueExecutor.get()); | ||
| 232 | - CHECK_RET(selfContiguous != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 233 | - | ||
| 234 | - // 将输入self的数据类型转换成目标数据类型, bool 转为float, 其余保持原类型 | ||
| 235 | - op::DataType selfCastType = | ||
| 236 | - (self->GetDataType() == op::DataType::DT_BOOL) ? op::DataType::DT_FLOAT : self->GetDataType(); | ||
| 237 | - | ||
| 238 | - auto selfCasted = l0op::Cast(selfContiguous, selfCastType, uniqueExecutor.get()); | ||
| 239 | - CHECK_RET(selfCasted != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 240 | - | ||
| 241 | - // 调用max算子kernel | ||
| 242 | - auto maxResult = l0op::ReduceMax(selfCasted, dims, keepDims, noopWithEmptyDims, uniqueExecutor.get()); | ||
| 243 | - CHECK_RET(maxResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 244 | - | ||
| 245 | - // 将max算子的输出转换成目标数据类型, | ||
| 246 | - auto castMaxOut = l0op::Cast(maxResult, out->GetDataType(), uniqueExecutor.get()); | ||
| 247 | - CHECK_RET(castMaxOut != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 248 | - | ||
| 249 | - // 将计算结果拷贝到输出out上,out可能是非连续的tensor | ||
| 250 | - auto viewCopyResult = l0op::ViewCopy(castMaxOut, out, uniqueExecutor.get()); | ||
| 251 | - CHECK_RET(viewCopyResult != nullptr, ACLNN_ERR_INNER_NULLPTR); | ||
| 252 | - | ||
| 253 | - // 获取计算过程中需要使用的workspace大小 | ||
| 254 | - *workspaceSize = uniqueExecutor->GetWorkspaceSize(); | ||
| 255 | - // 需要把 uniqueExecutor持有executor转移给executor | ||
| 256 | - uniqueExecutor.ReleaseTo(executor); | ||
| 257 | - | ||
| 258 | - return ACLNN_SUCCESS; | ||
| 259 | } | 272 | } |
| 260 | 273 | ||
| 261 | -aclnnStatus aclnnMaxV2(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) { | 274 | +aclnnStatus aclnnMaxV2(void* workspace, uint64_t workspaceSize, aclOpExecutor* executor, aclrtStream stream) |
| 262 | - L2_DFX_PHASE_2(aclnnMaxV2); | 275 | +{ |
| 263 | - // 固定写法,调用框架能力,完成计算 | 276 | + L2_DFX_PHASE_2(aclnnMaxV2); |
| 264 | - return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | 277 | + // 固定写法,调用框架能力,完成计算 |
| 278 | + return CommonOpExecutorRun(workspace, workspaceSize, executor, stream); | ||
| 265 | } | 279 | } |
| 266 | 280 | ||
| 267 | 281 | ||
| @@ -32,9 +32,9 @@ extern "C" { | |||
| 32 | * @param [out] executor: 返回op执行器,包含算子计算流程。 | 32 | * @param [out] executor: 返回op执行器,包含算子计算流程。 |
| 33 | * @return aclnnStatus: 返回状态码。 | 33 | * @return aclnnStatus: 返回状态码。 |
| 34 | */ | 34 | */ |
| 35 | -ACLNN_API aclnnStatus aclnnMaxV2GetWorkspaceSize(const aclTensor* self, const aclIntArray* dims, bool keepDims, | 35 | +ACLNN_API aclnnStatus aclnnMaxV2GetWorkspaceSize( |
| 36 | - bool noopWithEmptyDims, aclTensor* out, uint64_t* workspaceSize, | 36 | + const aclTensor* self, const aclIntArray* dims, bool keepDims, bool noopWithEmptyDims, aclTensor* out, |
| 37 | - aclOpExecutor** executor); | 37 | + uint64_t* workspaceSize, aclOpExecutor** executor); |
| 38 | 38 | ||
| 39 | /** | 39 | /** |
| 40 | * @brief aclnnMaxV2的第二段接口,用于执行计算。 | 40 | * @brief aclnnMaxV2的第二段接口,用于执行计算。 |
| @@ -53,4 +53,4 @@ ACLNN_API aclnnStatus aclnnMaxV2(void* workspace, uint64_t workspaceSize, aclOpE | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | 55 | ||
| 56 | -#endif // OP_API_INC_MAX_V2_H_ | 56 | +#endif // OP_API_INC_MAX_V2_H_ |
| @@ -29,64 +29,71 @@ static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST_910 = | |||
| 29 | 29 | ||
| 30 | static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST_GE910B = { | 30 | static const std::initializer_list<op::DataType> AICORE_DTYPE_SUPPORT_LIST_GE910B = { |
| 31 | op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT, op::DataType::DT_UINT8, op::DataType::DT_INT32, | 31 | op::DataType::DT_FLOAT16, op::DataType::DT_FLOAT, op::DataType::DT_UINT8, op::DataType::DT_INT32, |
| 32 | - op::DataType::DT_INT64, op::DataType::DT_BF16, op::DataType::DT_INT8}; | 32 | + op::DataType::DT_INT64, op::DataType::DT_BF16, op::DataType::DT_INT8}; |
| 33 | 33 | ||
| 34 | // 判断芯片类型是否大于等于910B | 34 | // 判断芯片类型是否大于等于910B |
| 35 | -static inline bool CheckSocVersionGe910B(void) { | 35 | +static inline bool CheckSocVersionGe910B(void) |
| 36 | - return (GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && | 36 | +{ |
| 37 | - GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || | 37 | + return (GetCurrentPlatformInfo().GetSocVersion() >= SocVersion::ASCEND910B && |
| 38 | - IsRegBase(); | 38 | + GetCurrentPlatformInfo().GetSocVersion() <= SocVersion::ASCEND910E) || |
| 39 | + IsRegBase(); | ||
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | -static bool IsAiCoreSupport(const aclTensor *self) { | 42 | +static bool IsAiCoreSupport(const aclTensor* self) |
| 43 | +{ | ||
| 42 | // 获取芯片类型 | 44 | // 获取芯片类型 |
| 43 | - if (CheckSocVersionGe910B()){ | 45 | + if (CheckSocVersionGe910B()) { |
| 44 | - return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST_GE910B); | 46 | + return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST_GE910B); |
| 45 | - } | 47 | + } |
| 46 | - // 910 | 48 | + // 910 |
| 47 | - return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST_910); | 49 | + return CheckType(self->GetDataType(), AICORE_DTYPE_SUPPORT_LIST_910); |
| 48 | } | 50 | } |
| 49 | 51 | ||
| 50 | // AICORE算子kernel | 52 | // AICORE算子kernel |
| 51 | -static const aclTensor *ReduceMaxAiCore(const aclTensor *self, const aclTensor *dimList, bool keepDim, | 53 | +static const aclTensor* ReduceMaxAiCore( |
| 52 | - bool noopWithEmptyDims, const aclTensor *maxOut, aclOpExecutor *executor) { | 54 | + const aclTensor* self, const aclTensor* dimList, bool keepDim, bool noopWithEmptyDims, const aclTensor* maxOut, |
| 53 | - L0_DFX(ReduceMaxAiCore, self, dimList, keepDim, noopWithEmptyDims, maxOut); | 55 | + aclOpExecutor* executor) |
| 56 | +{ | ||
| 57 | + L0_DFX(ReduceMaxAiCore, self, dimList, keepDim, noopWithEmptyDims, maxOut); | ||
| 54 | 58 | ||
| 55 | - auto retAicore = ADD_TO_LAUNCHER_LIST_AICORE(ReduceMax, OP_INPUT(self, dimList), | 59 | + auto retAicore = ADD_TO_LAUNCHER_LIST_AICORE( |
| 56 | - OP_OUTPUT(maxOut), OP_ATTR(keepDim, noopWithEmptyDims)); | 60 | + ReduceMax, OP_INPUT(self, dimList), OP_OUTPUT(maxOut), OP_ATTR(keepDim, noopWithEmptyDims)); |
| 57 | - OP_CHECK_ADD_TO_LAUNCHER_LIST_AICORE(retAicore != ACLNN_SUCCESS, return nullptr, | 61 | + OP_CHECK_ADD_TO_LAUNCHER_LIST_AICORE( |
| 58 | - "ReduceMax ADD_TO_LAUNCHER_LIST_AICORE failed."); | 62 | + retAicore != ACLNN_SUCCESS, return nullptr, "ReduceMax ADD_TO_LAUNCHER_LIST_AICORE failed."); |
| 59 | 63 | ||
| 60 | - return maxOut; | 64 | + return maxOut; |
| 61 | } | 65 | } |
| 62 | 66 | ||
| 63 | // AICPU算子kernel | 67 | // AICPU算子kernel |
| 64 | -static const aclTensor *ReduceMaxAiCpu(const aclTensor *self, const aclTensor *dimList, bool keepDim, | 68 | +static const aclTensor* ReduceMaxAiCpu( |
| 65 | - const aclTensor *maxOut, aclOpExecutor *executor) { | 69 | + const aclTensor* self, const aclTensor* dimList, bool keepDim, const aclTensor* maxOut, aclOpExecutor* executor) |
| 66 | - L0_DFX(ReduceMaxAiCpu, self, dimList, keepDim, maxOut); | 70 | +{ |
| 71 | + L0_DFX(ReduceMaxAiCpu, self, dimList, keepDim, maxOut); | ||
| 67 | 72 | ||
| 68 | - static internal::AicpuTaskSpace space("Max", ge::DEPEND_IN_SHAPE, true); | 73 | + static internal::AicpuTaskSpace space("Max", ge::DEPEND_IN_SHAPE, true); |
| 69 | - auto ret = ADD_TO_LAUNCHER_LIST_AICPU(ReduceMax, OP_ATTR_NAMES({"keep_dims", "Tidx"}), OP_INPUT(self, dimList), | 74 | + auto ret = ADD_TO_LAUNCHER_LIST_AICPU( |
| 70 | - OP_OUTPUT(maxOut), OP_ATTR(keepDim, dimList->GetDataType())); | 75 | + ReduceMax, OP_ATTR_NAMES({"keep_dims", "Tidx"}), OP_INPUT(self, dimList), OP_OUTPUT(maxOut), |
| 71 | - CHECK_RET(ret == ACLNN_SUCCESS, nullptr); | 76 | + OP_ATTR(keepDim, dimList->GetDataType())); |
| 72 | - return maxOut; | 77 | + CHECK_RET(ret == ACLNN_SUCCESS, nullptr); |
| 78 | + return maxOut; | ||
| 73 | } | 79 | } |
| 74 | 80 | ||
| 75 | -const aclTensor *ReduceMax(const aclTensor *self, const aclIntArray *dim, bool keepDim, | 81 | +const aclTensor* ReduceMax( |
| 76 | - bool noopWithEmptyDims, aclOpExecutor *executor) { | 82 | + const aclTensor* self, const aclIntArray* dim, bool keepDim, bool noopWithEmptyDims, aclOpExecutor* executor) |
| 77 | - auto dimList = executor->ConvertToTensor(dim, op::DataType::DT_INT64); | 83 | +{ |
| 78 | - auto maxOut = executor->AllocTensor(self->GetViewShape(), self->GetDataType()); | 84 | + auto dimList = executor->ConvertToTensor(dim, op::DataType::DT_INT64); |
| 85 | + auto maxOut = executor->AllocTensor(self->GetViewShape(), self->GetDataType()); | ||
| 79 | 86 | ||
| 80 | - auto ret = INFER_SHAPE(ReduceMax, OP_INPUT(self, dimList), OP_OUTPUT(maxOut), OP_ATTR(keepDim, noopWithEmptyDims)); | 87 | + auto ret = INFER_SHAPE(ReduceMax, OP_INPUT(self, dimList), OP_OUTPUT(maxOut), OP_ATTR(keepDim, noopWithEmptyDims)); |
| 81 | - if (ret != ACLNN_SUCCESS) { | 88 | + if (ret != ACLNN_SUCCESS) { |
| 82 | - OP_LOGE(ACLNN_ERR_PARAM_INVALID, "ReduceMax infer shape faild."); | 89 | + OP_LOGE(ACLNN_ERR_PARAM_INVALID, "ReduceMax infer shape faild."); |
| 83 | - return nullptr; | 90 | + return nullptr; |
| 84 | - } | 91 | + } |
| 85 | 92 | ||
| 86 | - if (IsAiCoreSupport(self)) { | 93 | + if (IsAiCoreSupport(self)) { |
| 87 | - return ReduceMaxAiCore(self, dimList, keepDim, noopWithEmptyDims, maxOut, executor); | 94 | + return ReduceMaxAiCore(self, dimList, keepDim, noopWithEmptyDims, maxOut, executor); |
| 88 | - } else { | 95 | + } else { |
| 89 | - return ReduceMaxAiCpu(self, dimList, keepDim, maxOut, executor); | 96 | + return ReduceMaxAiCpu(self, dimList, keepDim, maxOut, executor); |
| 90 | - } | 97 | + } |
| 91 | } | 98 | } |
| 92 | } // namespace l0op | 99 | } // namespace l0op |
| @@ -13,8 +13,8 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | namespace l0op { | 15 | namespace l0op { |
| 16 | -const aclTensor *ReduceMax(const aclTensor *self, const aclIntArray *dim, | 16 | +const aclTensor* ReduceMax( |
| 17 | - bool keepDim, bool noopWithEmptyDims, aclOpExecutor *executor); | 17 | + const aclTensor* self, const aclIntArray* dim, bool keepDim, bool noopWithEmptyDims, aclOpExecutor* executor); |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | 20 | ||
| @@ -1,19 +0,0 @@ | |||
| 1 | -/** | ||
| 2 | - * Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | - * This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | - * CANN Open Software License Agreement Version 2.0 (the "License") | ||
| 5 | - * Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | - * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | - * See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | - */ | ||
| 10 | - | ||
| 11 | -/*! | ||
| 12 | - * \file reduce_max_tiling_arch35.h | ||
| 13 | - * \brief tiling for reduce max | ||
| 14 | - */ | ||
| 15 | - | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | - | ||
| @@ -15,45 +15,36 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | namespace ops { | 17 | namespace ops { |
| 18 | -static const std::vector<ge::DataType> dataType = {ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_UINT8, ge::DT_INT32, | 18 | +static const std::vector<ge::DataType> dataType = { |
| 19 | - ge::DT_INT64, ge::DT_BF16, ge::DT_INT8, | 19 | + ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_UINT8, ge::DT_INT32, ge::DT_INT64, ge::DT_BF16, ge::DT_INT8, |
| 20 | - ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_UINT8, ge::DT_INT32, | 20 | + ge::DT_FLOAT16, ge::DT_FLOAT, ge::DT_UINT8, ge::DT_INT32, ge::DT_INT64, ge::DT_BF16, ge::DT_INT8}; |
| 21 | - ge::DT_INT64, ge::DT_BF16, ge::DT_INT8}; | 21 | + |
| 22 | - | 22 | +static const std::vector<ge::Format> format = { |
| 23 | -static const std::vector<ge::Format> format = {ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, | 23 | + ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, |
| 24 | - ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, | 24 | + ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}; |
| 25 | - ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND, | ||
| 26 | - ge::FORMAT_ND, ge::FORMAT_ND, ge::FORMAT_ND}; | ||
| 27 | 25 | ||
| 28 | static const std::vector<ge::DataType> axesDataType = { | 26 | static const std::vector<ge::DataType> axesDataType = { |
| 29 | ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, | 27 | ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, ge::DT_INT32, |
| 30 | ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64}; | 28 | ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64, ge::DT_INT64}; |
| 31 | - | 29 | + |
| 32 | class ReduceMax : public OpDef { | 30 | class ReduceMax : public OpDef { |
| 33 | - public: | 31 | +public: |
| 34 | - explicit ReduceMax(const char* name) : OpDef(name) { | 32 | + explicit ReduceMax(const char* name) : OpDef(name) |
| 35 | - this->Input("x") | 33 | + { |
| 36 | - .ParamType(REQUIRED) | 34 | + this->Input("x").ParamType(REQUIRED).DataType(dataType).Format(format).UnknownShapeFormat(format); |
| 37 | - .DataType(dataType) | 35 | + |
| 38 | - .Format(format) | ||
| 39 | - .UnknownShapeFormat(format); | ||
| 40 | - | ||
| 41 | this->Input("axes") | 36 | this->Input("axes") |
| 42 | .ParamType(REQUIRED) | 37 | .ParamType(REQUIRED) |
| 43 | .ValueDepend(OPTIONAL) | 38 | .ValueDepend(OPTIONAL) |
| 44 | .DataType(axesDataType) | 39 | .DataType(axesDataType) |
| 45 | .Format(format) | 40 | .Format(format) |
| 46 | .UnknownShapeFormat(format); | 41 | .UnknownShapeFormat(format); |
| 47 | - | 42 | + |
| 48 | - this->Output("y") | 43 | + this->Output("y").ParamType(REQUIRED).DataType(dataType).Format(format).UnknownShapeFormat(format); |
| 49 | - .ParamType(REQUIRED) | 44 | + |
| 50 | - .DataType(dataType) | ||
| 51 | - .Format(format) | ||
| 52 | - .UnknownShapeFormat(format); | ||
| 53 | - | ||
| 54 | this->Attr("keep_dims").AttrType(OPTIONAL).Bool(false); | 45 | this->Attr("keep_dims").AttrType(OPTIONAL).Bool(false); |
| 55 | this->Attr("noop_with_empty_axes").AttrType(OPTIONAL).Bool(true); | 46 | this->Attr("noop_with_empty_axes").AttrType(OPTIONAL).Bool(true); |
| 56 | - | 47 | + |
| 57 | OpAICoreConfig aicoreConfig; | 48 | OpAICoreConfig aicoreConfig; |
| 58 | aicoreConfig.DynamicCompileStaticFlag(true) | 49 | aicoreConfig.DynamicCompileStaticFlag(true) |
| 59 | .DynamicRankSupportFlag(true) | 50 | .DynamicRankSupportFlag(true) |
| @@ -63,6 +54,6 @@ class ReduceMax : public OpDef { | |||
| 63 | this->AICore().AddConfig("mc62cm12a", aicoreConfig); | 54 | this->AICore().AddConfig("mc62cm12a", aicoreConfig); |
| 64 | } | 55 | } |
| 65 | }; | 56 | }; |
| 66 | - | 57 | + |
| 67 | OP_ADD(ReduceMax); | 58 | OP_ADD(ReduceMax); |
| 68 | -} // namespace ops | 59 | +} // namespace ops |
| @@ -14,15 +14,13 @@ | |||
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | - | ||
| 18 | - | ||
| 19 | 17 | ||
| 20 | using namespace ge; | 18 | using namespace ge; |
| 21 | namespace ops { | 19 | namespace ops { |
| 22 | 20 | ||
| 23 | static ge::graphStatus InferShape4ReduceMax(gert::InferShapeContext* context) | 21 | static ge::graphStatus InferShape4ReduceMax(gert::InferShapeContext* context) |
| 24 | { | 22 | { |
| 25 | - OP_LOGI("Begin InferShape4ReduceMax."); | 23 | + OP_LOGD("Begin InferShape4ReduceMax."); |
| 26 | return Ops::Base::InferShape4Reduce(context); | 24 | return Ops::Base::InferShape4Reduce(context); |
| 27 | } | 25 | } |
| 28 | 26 | ||
| @@ -1,16 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| @@ -1,16 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| @@ -1,18 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -message(STATUS "=== Debug: CURRENT_SOURCE_DIRS =${CURRENT_SOURCE_DIRS} ") | ||
| 13 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 14 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 15 | - add_subdirectory(${SUB_DIR}) | ||
| 16 | - endif() | ||
| 17 | -endforeach() | ||
| 18 | - | ||
| @@ -1,14 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -message(STATUS "=== Debug: target_sources add test_*_proto.cpp: ${test_xxx_proto.cpp} ") | ||
| 12 | -if(PASS_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 13 | - add_modules_llt_sources(HOSTNAME ${OPTEST_NAME} MODE PRIVATE DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| 14 | -endif() | ||
| @@ -1,19 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||
| 11 | -file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) | ||
| 12 | -foreach(SUB_DIR ${CURRENT_DIRS}) | ||
| 13 | - if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt") | ||
| 14 | - add_subdirectory(${SUB_DIR}) | ||
| 15 | - endif() | ||
| 16 | -endforeach() | ||
| 17 | - | ||
| 18 | -if(OP_API_UT OR (UT_TEST_ALL AND NOT AICPU_ONLY)) | ||
| 19 | -endif() | ||
| @@ -1,10 +0,0 @@ | |||
| 1 | -# ---------------------------------------------------------------------------- | ||
| 2 | -# Copyright (c) 2025 Huawei Technologies Co., Ltd. | ||
| 3 | -# This program is free software, you can redistribute it and/or modify it under the terms and conditions of | ||
| 4 | -# CANN Open Software License Agreement Version 2.0 (the "License"). | ||
| 5 | -# Please refer to the License for details. You may not use this file except in compliance with the License. | ||
| 6 | -# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, | ||
| 7 | -# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. | ||
| 8 | -# See LICENSE in the root of the software repository for the full text of the License. | ||
| 9 | -# ---------------------------------------------------------------------------- | ||
| 10 | - | ||