已合并
常量折叠和infershape整改 #4582
liu-lu创建于 21 天前
常量折叠和infershape整改 #4582
已合并
共 15 个文件变更+799-802
| @@ -11,7 +11,7 @@ | |||
| 11 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") | 11 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") |
| 12 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | 12 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 13 | set(SUPPORT_TILING_DIR "arch35" "arch35") | 13 | set(SUPPORT_TILING_DIR "arch35" "arch35") |
| 14 | -add_all_modules_sources(OPTYPE add ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | 14 | +add_all_modules_sources(OPTYPE add ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE) |
| 15 | 15 | ||
| 16 | add_kernel_sources( | 16 | add_kernel_sources( |
| 17 | KERNEL_SRC arch35/add.cpp | 17 | KERNEL_SRC arch35/add.cpp |
| @@ -13,360 +13,340 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | namespace { | 21 | namespace { |
| 21 | -const char *const kAdd = "Add"; | 22 | +const char* const kAdd = "Add"; |
| 22 | constexpr int64_t kParallelBytesThresh = 192LL * 1024LL; | 23 | constexpr int64_t kParallelBytesThresh = 192LL * 1024LL; |
| 23 | // per-shard target ~256 KiB of output. Sized large enough to amortize | 24 | // per-shard target ~256 KiB of output. Sized large enough to amortize |
| 24 | constexpr int64_t kBytesPerShard = 256LL * 1024LL; | 25 | constexpr int64_t kBytesPerShard = 256LL * 1024LL; |
| 25 | -} // namespace | 26 | +} // namespace |
| 26 | 27 | ||
| 27 | namespace aicpu { | 28 | namespace aicpu { |
| 28 | -uint32_t CheckPermissionType(const CpuKernelContext &ctx) { | 29 | +uint32_t CheckPermissionType(const CpuKernelContext& ctx) |
| 29 | - const DataType input0_data_type = ctx.Input(kFirstInputIndex)->GetDataType(); | 30 | +{ |
| 30 | - const DataType input1_data_type = ctx.Input(kSecondInputIndex)->GetDataType(); | 31 | + const DataType input0_data_type = ctx.Input(kFirstInputIndex)->GetDataType(); |
| 31 | - const DataType output_data_type = ctx.Output(kFirstOutputIndex)->GetDataType(); | 32 | + const DataType input1_data_type = ctx.Input(kSecondInputIndex)->GetDataType(); |
| 32 | - if (input0_data_type != output_data_type) { | 33 | + const DataType output_data_type = ctx.Output(kFirstOutputIndex)->GetDataType(); |
| 33 | - KERNEL_LOG_ERROR( | 34 | + if (input0_data_type != output_data_type) { |
| 34 | - "[Add] Output must have the same dtype as input, but got " | 35 | + KERNEL_LOG_ERROR("[Add] Output must have the same dtype as input, but got " |
| 35 | - "input0[%s] input1[%s] output[%s].", | 36 | + "input0[%s] input1[%s] output[%s].", |
| 36 | - DTypeStr(input0_data_type).c_str(), | 37 | + DTypeStr(input0_data_type).c_str(), DTypeStr(input1_data_type).c_str(), |
| 37 | - DTypeStr(input1_data_type).c_str(), | 38 | + DTypeStr(output_data_type).c_str()); |
| 38 | - DTypeStr(output_data_type).c_str()); | 39 | + return KERNEL_STATUS_PARAM_INVALID; |
| 39 | - return KERNEL_STATUS_PARAM_INVALID; | 40 | + } |
| 40 | - } | 41 | + return KERNEL_STATUS_OK; |
| 41 | - return KERNEL_STATUS_OK; | ||
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | -uint32_t AddCpuKernel::Compute(CpuKernelContext &ctx) { | 44 | +uint32_t AddCpuKernel::Compute(CpuKernelContext& ctx) |
| 45 | - KERNEL_HANDLE_ERROR(NormalMathCheck(ctx), "Normal match check params failed."); | 45 | +{ |
| 46 | - KERNEL_HANDLE_ERROR(CheckPermissionType(ctx), "Type permission check failed."); | 46 | + KERNEL_HANDLE_ERROR(NormalMathCheck(ctx), "Normal match check params failed."); |
| 47 | - Tensor *input0 = ctx.Input(kFirstInputIndex); | 47 | + KERNEL_HANDLE_ERROR(CheckPermissionType(ctx), "Type permission check failed."); |
| 48 | - Tensor *input1 = ctx.Input(kSecondInputIndex); | 48 | + Tensor* input0 = ctx.Input(kFirstInputIndex); |
| 49 | - if ((input0->GetDataSize() == 0) || (input1->GetDataSize() == 0)) { | 49 | + Tensor* input1 = ctx.Input(kSecondInputIndex); |
| 50 | - KERNEL_LOG_INFO("[%s] Input is empty tensor.", ctx.GetOpType().c_str()); | 50 | + if ((input0->GetDataSize() == 0) || (input1->GetDataSize() == 0)) { |
| 51 | - return KERNEL_STATUS_OK; | 51 | + KERNEL_LOG_INFO("[%s] Input is empty tensor.", ctx.GetOpType().c_str()); |
| 52 | - } | 52 | + return KERNEL_STATUS_OK; |
| 53 | + } | ||
| 53 | 54 | ||
| 54 | - const DataType input0_data_type = input0->GetDataType(); | 55 | + const DataType input0_data_type = input0->GetDataType(); |
| 55 | - KERNEL_LOG_INFO("[%s] Compute begin, dtype=%d, in0_bytes=%lu, in1_bytes=%lu, out_bytes=%lu.", | 56 | + KERNEL_LOG_INFO("[%s] Compute begin, dtype=%d, in0_bytes=%lu, in1_bytes=%lu, out_bytes=%lu.", |
| 56 | - ctx.GetOpType().c_str(), static_cast<int>(input0_data_type), | 57 | + ctx.GetOpType().c_str(), static_cast<int>(input0_data_type), input0->GetDataSize(), |
| 57 | - input0->GetDataSize(), input1->GetDataSize(), | 58 | + input1->GetDataSize(), ctx.Output(kFirstOutputIndex)->GetDataSize()); |
| 58 | - ctx.Output(kFirstOutputIndex)->GetDataSize()); | ||
| 59 | 59 | ||
| 60 | - // choose compute function depend on dataType | 60 | + // choose compute function depend on dataType |
| 61 | - switch (input0_data_type) { | 61 | + switch (input0_data_type) { |
| 62 | - case DT_FLOAT16: | 62 | + case DT_FLOAT16: |
| 63 | - return AddCompute<Eigen::half>(ctx); | 63 | + return AddCompute<Eigen::half>(ctx); |
| 64 | - case DT_FLOAT: | 64 | + case DT_FLOAT: |
| 65 | - return AddCompute<float>(ctx); | 65 | + return AddCompute<float>(ctx); |
| 66 | - case DT_DOUBLE: | 66 | + case DT_DOUBLE: |
| 67 | - return AddCompute<double>(ctx); | 67 | + return AddCompute<double>(ctx); |
| 68 | - case DT_INT8: | 68 | + case DT_INT8: |
| 69 | - return AddCompute<int8_t>(ctx); | 69 | + return AddCompute<int8_t>(ctx); |
| 70 | - case DT_INT16: | 70 | + case DT_INT16: |
| 71 | - return AddCompute<int16_t>(ctx); | 71 | + return AddCompute<int16_t>(ctx); |
| 72 | - case DT_INT32: | 72 | + case DT_INT32: |
| 73 | - return AddCompute<int32_t>(ctx); | 73 | + return AddCompute<int32_t>(ctx); |
| 74 | - case DT_INT64: | 74 | + case DT_INT64: |
| 75 | - return AddCompute<int64_t>(ctx); | 75 | + return AddCompute<int64_t>(ctx); |
| 76 | - case DT_UINT8: | 76 | + case DT_UINT8: |
| 77 | - return AddCompute<uint8_t>(ctx); | 77 | + return AddCompute<uint8_t>(ctx); |
| 78 | - case DT_UINT16: | 78 | + case DT_UINT16: |
| 79 | - return AddCompute<uint16_t>(ctx); | 79 | + return AddCompute<uint16_t>(ctx); |
| 80 | - case DT_UINT32: | 80 | + case DT_UINT32: |
| 81 | - return AddCompute<uint32_t>(ctx); | 81 | + return AddCompute<uint32_t>(ctx); |
| 82 | - case DT_UINT64: | 82 | + case DT_UINT64: |
| 83 | - return AddCompute<uint64_t>(ctx); | 83 | + return AddCompute<uint64_t>(ctx); |
| 84 | - case DT_COMPLEX64: | 84 | + case DT_COMPLEX64: |
| 85 | - return AddCompute<std::complex<float>>(ctx); | 85 | + return AddCompute<std::complex<float>>(ctx); |
| 86 | - case DT_COMPLEX128: | 86 | + case DT_COMPLEX128: |
| 87 | - return AddCompute<std::complex<double>>(ctx); | 87 | + return AddCompute<std::complex<double>>(ctx); |
| 88 | - default: | 88 | + default: |
| 89 | - KERNEL_LOG_ERROR( | 89 | + KERNEL_LOG_ERROR("[%s] Data type of input is not supported, got dtype=[%s]. " |
| 90 | - "[%s] Data type of input is not supported, got dtype=[%s]. " | 90 | + "Expect one of {FP16,FP32,FP64,INT8..INT64,UINT8..UINT64,CPX64,CPX128}.", |
| 91 | - "Expect one of {FP16,FP32,FP64,INT8..INT64,UINT8..UINT64,CPX64,CPX128}.", | 91 | + ctx.GetOpType().c_str(), DTypeStr(input0_data_type).c_str()); |
| 92 | - ctx.GetOpType().c_str(), DTypeStr(input0_data_type).c_str()); | 92 | + return KERNEL_STATUS_PARAM_INVALID; |
| 93 | - return KERNEL_STATUS_PARAM_INVALID; | 93 | + } |
| 94 | - } | ||
| 95 | } | 94 | } |
| 96 | 95 | ||
| 97 | template <typename Body> | 96 | template <typename Body> |
| 98 | -uint32_t AddCpuKernel::RunMaybeParallel(const CpuKernelContext &ctx, | 97 | +uint32_t AddCpuKernel::RunMaybeParallel(const CpuKernelContext& ctx, const char* tag, int64_t total, int64_t elem_bytes, |
| 99 | - const char *tag, int64_t total, | 98 | + const Body& body) const |
| 100 | - int64_t elem_bytes, | 99 | +{ |
| 101 | - const Body &body) const { | 100 | + const int64_t total_bytes = total * elem_bytes; |
| 102 | - const int64_t total_bytes = total * elem_bytes; | 101 | + if (total_bytes < kParallelBytesThresh) { |
| 103 | - if (total_bytes < kParallelBytesThresh) { | 102 | + KERNEL_LOG_INFO("[%s] %s serial path, total_bytes=%ld.", ctx.GetOpType().c_str(), tag, total_bytes); |
| 104 | - KERNEL_LOG_INFO("[%s] %s serial path, total_bytes=%ld.", | 103 | + body(0, total); |
| 105 | - ctx.GetOpType().c_str(), tag, total_bytes); | 104 | + return KERNEL_STATUS_OK; |
| 106 | - body(0, total); | 105 | + } |
| 106 | + // Guard against zero/negative elem_bytes. All current callers pass | ||
| 107 | + // sizeof(T) which is always >= 1, but this keeps the divisor safe for | ||
| 108 | + // any future caller and silences static analyzers. | ||
| 109 | + if (__builtin_expect(elem_bytes <= 0, 0)) { | ||
| 110 | + KERNEL_LOG_ERROR("[%s] %s invalid elem_bytes=%ld, fallback to serial.", ctx.GetOpType().c_str(), tag, | ||
| 111 | + elem_bytes); | ||
| 112 | + body(0, total); | ||
| 113 | + return KERNEL_STATUS_OK; | ||
| 114 | + } | ||
| 115 | + const int64_t per_unit = std::max<int64_t>(1, kBytesPerShard / elem_bytes); | ||
| 116 | + KERNEL_LOG_INFO("[%s] %s parallel path, total=%ld, per_unit=%ld.", ctx.GetOpType().c_str(), tag, total, per_unit); | ||
| 117 | + const uint32_t rc = CpuKernelUtils::ParallelFor(ctx, total, per_unit, body); | ||
| 118 | + if (__builtin_expect(rc != KERNEL_STATUS_OK, 0)) { | ||
| 119 | + KERNEL_LOG_ERROR("[%s] %s ParallelFor failed, rc=%u, total=%ld, per_unit=%ld.", ctx.GetOpType().c_str(), tag, | ||
| 120 | + rc, total, per_unit); | ||
| 121 | + return rc; | ||
| 122 | + } | ||
| 107 | return KERNEL_STATUS_OK; | 123 | return KERNEL_STATUS_OK; |
| 108 | - } | 124 | +} |
| 109 | - // Guard against zero/negative elem_bytes. All current callers pass | 125 | + |
| 110 | - // sizeof(T) which is always >= 1, but this keeps the divisor safe for | 126 | +template <typename T> |
| 111 | - // any future caller and silences static analyzers. | 127 | +uint32_t AddCpuKernel::AddSameShape(const CpuKernelContext& ctx, const T* x0, const T* x1, T* y, int64_t total) const |
| 112 | - if (__builtin_expect(elem_bytes <= 0, 0)) { | 128 | +{ |
| 113 | - KERNEL_LOG_ERROR("[%s] %s invalid elem_bytes=%ld, fallback to serial.", | 129 | + auto body = [x0, x1, y](int64_t beg, int64_t end) { |
| 114 | - ctx.GetOpType().c_str(), tag, elem_bytes); | 130 | + const T* __restrict__ a = x0 + beg; |
| 115 | - body(0, total); | 131 | + const T* __restrict__ b = x1 + beg; |
| 132 | + T* __restrict__ o = y + beg; | ||
| 133 | + const int64_t n = end - beg; | ||
| 134 | + for (int64_t i = 0; i < n; ++i) { | ||
| 135 | + o[i] = a[i] + b[i]; | ||
| 136 | + } | ||
| 137 | + }; | ||
| 138 | + return RunMaybeParallel(ctx, "same-shape", total, static_cast<int64_t>(sizeof(T)), body); | ||
| 139 | +} | ||
| 140 | + | ||
| 141 | +template <typename T> | ||
| 142 | +uint32_t AddCpuKernel::AddScalarBcast(const CpuKernelContext& ctx, const T* vec, T scalar_val, T* y, | ||
| 143 | + int64_t total) const | ||
| 144 | +{ | ||
| 145 | + auto body = [vec, scalar_val, y](int64_t beg, int64_t end) { | ||
| 146 | + const T* __restrict__ a = vec + beg; | ||
| 147 | + T* __restrict__ o = y + beg; | ||
| 148 | + const T s = scalar_val; | ||
| 149 | + const int64_t n = end - beg; | ||
| 150 | + for (int64_t i = 0; i < n; ++i) { | ||
| 151 | + o[i] = a[i] + s; | ||
| 152 | + } | ||
| 153 | + }; | ||
| 154 | + return RunMaybeParallel(ctx, "scalar-bcast", total, static_cast<int64_t>(sizeof(T)), body); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +template <typename T> | ||
| 158 | +uint32_t AddCpuKernel::AddGenericBcast(const CpuKernelContext& ctx, BCalcInfo& calc_info) const | ||
| 159 | +{ | ||
| 160 | + (void)ctx; | ||
| 161 | + return AddCalculateWithRankCheck<T>(ctx, calc_info); | ||
| 162 | +} | ||
| 163 | + | ||
| 164 | +uint32_t AddCpuKernel::ValidateAndBroadcast(const CpuKernelContext& ctx, BCalcInfo& calc_info) const | ||
| 165 | +{ | ||
| 166 | + // Raw-shape validation (must match the original kernel's failure modes): | ||
| 167 | + // 1. Any raw tensor rank > 8 is rejected even if size-1 dims could be | ||
| 168 | + // squeezed away by Bcast (keeps parity with the original Eigen path | ||
| 169 | + // that switches on calc_info.shape_out.size() up to kRank8). | ||
| 170 | + // 2. Both inputs must broadcast to the declared output shape; otherwise | ||
| 171 | + // reject. Bcast internally only derives a compatible broadcast shape | ||
| 172 | + // from the two inputs and never cross-checks the output tensor. | ||
| 173 | + const auto& raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); | ||
| 174 | + const auto& raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); | ||
| 175 | + const auto& raw_out = calc_info.output->GetTensorShape()->GetDimSizes(); | ||
| 176 | + if (raw0.size() > static_cast<size_t>(kRank8) || raw1.size() > static_cast<size_t>(kRank8) || | ||
| 177 | + raw_out.size() > static_cast<size_t>(kRank8)) { | ||
| 178 | + KERNEL_LOG_ERROR("[%s] Rank of input/output must be <= 8, got in0_rank=%zu, " | ||
| 179 | + "in1_rank=%zu, out_rank=%zu.", | ||
| 180 | + ctx.GetOpType().c_str(), raw0.size(), raw1.size(), raw_out.size()); | ||
| 181 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + Bcast bcast; | ||
| 185 | + if (bcast.GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) { | ||
| 186 | + KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", ctx.GetOpType().c_str()); | ||
| 187 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 188 | + } | ||
| 189 | + bcast.GetBcastVec(calc_info); | ||
| 190 | + | ||
| 191 | + // Validate declared output shape against the broadcast result. The rank | ||
| 192 | + // must match and every dim must equal the broadcast dim. | ||
| 193 | + if (raw_out.size() != calc_info.shape_out.size()) { | ||
| 194 | + KERNEL_LOG_ERROR("[%s] Output rank [%zu] does not match broadcast rank [%zu].", ctx.GetOpType().c_str(), | ||
| 195 | + raw_out.size(), calc_info.shape_out.size()); | ||
| 196 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 197 | + } | ||
| 198 | + for (size_t i = 0; i < raw_out.size(); ++i) { | ||
| 199 | + if (raw_out[i] != calc_info.shape_out[i]) { | ||
| 200 | + KERNEL_LOG_ERROR("[%s] Output dim[%zu]=%ld mismatches broadcast dim=%ld.", ctx.GetOpType().c_str(), i, | ||
| 201 | + raw_out[i], calc_info.shape_out[i]); | ||
| 202 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 203 | + } | ||
| 204 | + } | ||
| 116 | return KERNEL_STATUS_OK; | 205 | return KERNEL_STATUS_OK; |
| 117 | - } | ||
| 118 | - const int64_t per_unit = std::max<int64_t>(1, kBytesPerShard / elem_bytes); | ||
| 119 | - KERNEL_LOG_INFO("[%s] %s parallel path, total=%ld, per_unit=%ld.", | ||
| 120 | - ctx.GetOpType().c_str(), tag, total, per_unit); | ||
| 121 | - const uint32_t rc = CpuKernelUtils::ParallelFor(ctx, total, per_unit, body); | ||
| 122 | - if (__builtin_expect(rc != KERNEL_STATUS_OK, 0)) { | ||
| 123 | - KERNEL_LOG_ERROR("[%s] %s ParallelFor failed, rc=%u, total=%ld, per_unit=%ld.", | ||
| 124 | - ctx.GetOpType().c_str(), tag, rc, total, per_unit); | ||
| 125 | - return rc; | ||
| 126 | - } | ||
| 127 | - return KERNEL_STATUS_OK; | ||
| 128 | } | 206 | } |
| 129 | 207 | ||
| 130 | template <typename T> | 208 | template <typename T> |
| 131 | -uint32_t AddCpuKernel::AddSameShape(const CpuKernelContext &ctx, const T *x0, | 209 | +uint32_t AddCpuKernel::AddCompute(const CpuKernelContext& ctx) const |
| 132 | - const T *x1, T *y, int64_t total) const { | 210 | +{ |
| 133 | - auto body = [x0, x1, y](int64_t beg, int64_t end) { | 211 | + BCalcInfo calc_info; |
| 134 | - const T *__restrict__ a = x0 + beg; | 212 | + calc_info.input_0 = ctx.Input(kFirstInputIndex); |
| 135 | - const T *__restrict__ b = x1 + beg; | 213 | + calc_info.input_1 = ctx.Input(kSecondInputIndex); |
| 136 | - T *__restrict__ o = y + beg; | 214 | + calc_info.output = ctx.Output(kFirstOutputIndex); |
| 137 | - const int64_t n = end - beg; | 215 | + |
| 138 | - for (int64_t i = 0; i < n; ++i) { | 216 | + KERNEL_CHECK_NULLPTR(calc_info.input_0->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[0] data failed", |
| 139 | - o[i] = a[i] + b[i]; | 217 | + ctx.GetOpType().c_str()) |
| 218 | + KERNEL_CHECK_NULLPTR(calc_info.input_1->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[1] data failed", | ||
| 219 | + ctx.GetOpType().c_str()) | ||
| 220 | + KERNEL_CHECK_NULLPTR(calc_info.output->GetData(), KERNEL_STATUS_PARAM_INVALID, "[%s] Get output data failed", | ||
| 221 | + ctx.GetOpType().c_str()) | ||
| 222 | + | ||
| 223 | + T* const x0_ptr = PtrToPtr<void, T>(calc_info.input_0->GetData()); | ||
| 224 | + T* const x1_ptr = PtrToPtr<void, T>(calc_info.input_1->GetData()); | ||
| 225 | + T* const y_ptr = PtrToPtr<void, T>(calc_info.output->GetData()); | ||
| 226 | + | ||
| 227 | + const int64_t n0 = calc_info.input_0->NumElements(); | ||
| 228 | + const int64_t n1 = calc_info.input_1->NumElements(); | ||
| 229 | + const int64_t ny = calc_info.output->NumElements(); | ||
| 230 | + | ||
| 231 | + KERNEL_LOG_INFO("[%s] Input[0] size=%lu, Input[1] size=%lu, Output size=%lu.", ctx.GetOpType().c_str(), | ||
| 232 | + calc_info.input_0->GetDataSize(), calc_info.input_1->GetDataSize(), | ||
| 233 | + calc_info.output->GetDataSize()); | ||
| 234 | + | ||
| 235 | + const uint32_t vrc = ValidateAndBroadcast(ctx, calc_info); | ||
| 236 | + if (vrc != KERNEL_STATUS_OK) { | ||
| 237 | + return vrc; | ||
| 140 | } | 238 | } |
| 141 | - }; | ||
| 142 | - return RunMaybeParallel(ctx, "same-shape", total, | ||
| 143 | - static_cast<int64_t>(sizeof(T)), body); | ||
| 144 | -} | ||
| 145 | 239 | ||
| 146 | -template <typename T> | 240 | + const auto& raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); |
| 147 | -uint32_t AddCpuKernel::AddScalarBcast(const CpuKernelContext &ctx, const T *vec, | 241 | + const auto& raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); |
| 148 | - T scalar_val, T *y, | 242 | + const auto& raw_out = calc_info.output->GetTensorShape()->GetDimSizes(); |
| 149 | - int64_t total) const { | 243 | + |
| 150 | - auto body = [vec, scalar_val, y](int64_t beg, int64_t end) { | 244 | + if (raw0 == raw1 && raw0 == raw_out && n0 == n1 && n0 == ny) { |
| 151 | - const T *__restrict__ a = vec + beg; | 245 | + KERNEL_LOG_INFO("[%s] same-shape branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny); |
| 152 | - T *__restrict__ o = y + beg; | 246 | + return AddSameShape<T>(ctx, x0_ptr, x1_ptr, y_ptr, ny); |
| 153 | - const T s = scalar_val; | ||
| 154 | - const int64_t n = end - beg; | ||
| 155 | - for (int64_t i = 0; i < n; ++i) { | ||
| 156 | - o[i] = a[i] + s; | ||
| 157 | } | 247 | } |
| 158 | - }; | 248 | + if (n0 == 1 && n1 == ny && raw1 == raw_out) { |
| 159 | - return RunMaybeParallel(ctx, "scalar-bcast", total, | 249 | + KERNEL_LOG_INFO("[%s] x0-scalar bcast branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny); |
| 160 | - static_cast<int64_t>(sizeof(T)), body); | 250 | + return AddScalarBcast<T>(ctx, x1_ptr, *x0_ptr, y_ptr, ny); |
| 161 | -} | ||
| 162 | - | ||
| 163 | -template <typename T> | ||
| 164 | -uint32_t AddCpuKernel::AddGenericBcast(const CpuKernelContext &ctx, | ||
| 165 | - BCalcInfo &calc_info) const { | ||
| 166 | - (void)ctx; | ||
| 167 | - return AddCalculateWithRankCheck<T>(ctx, calc_info); | ||
| 168 | -} | ||
| 169 | - | ||
| 170 | -uint32_t AddCpuKernel::ValidateAndBroadcast(const CpuKernelContext &ctx, | ||
| 171 | - BCalcInfo &calc_info) const { | ||
| 172 | - // Raw-shape validation (must match the original kernel's failure modes): | ||
| 173 | - // 1. Any raw tensor rank > 8 is rejected even if size-1 dims could be | ||
| 174 | - // squeezed away by Bcast (keeps parity with the original Eigen path | ||
| 175 | - // that switches on calc_info.shape_out.size() up to kRank8). | ||
| 176 | - // 2. Both inputs must broadcast to the declared output shape; otherwise | ||
| 177 | - // reject. Bcast internally only derives a compatible broadcast shape | ||
| 178 | - // from the two inputs and never cross-checks the output tensor. | ||
| 179 | - const auto &raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); | ||
| 180 | - const auto &raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); | ||
| 181 | - const auto &raw_out = calc_info.output->GetTensorShape()->GetDimSizes(); | ||
| 182 | - if (raw0.size() > static_cast<size_t>(kRank8) || | ||
| 183 | - raw1.size() > static_cast<size_t>(kRank8) || | ||
| 184 | - raw_out.size() > static_cast<size_t>(kRank8)) { | ||
| 185 | - KERNEL_LOG_ERROR( | ||
| 186 | - "[%s] Rank of input/output must be <= 8, got in0_rank=%zu, " | ||
| 187 | - "in1_rank=%zu, out_rank=%zu.", | ||
| 188 | - ctx.GetOpType().c_str(), raw0.size(), raw1.size(), raw_out.size()); | ||
| 189 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 190 | - } | ||
| 191 | - | ||
| 192 | - Bcast bcast; | ||
| 193 | - if (bcast.GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) { | ||
| 194 | - KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", | ||
| 195 | - ctx.GetOpType().c_str()); | ||
| 196 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 197 | - } | ||
| 198 | - bcast.GetBcastVec(calc_info); | ||
| 199 | - | ||
| 200 | - // Validate declared output shape against the broadcast result. The rank | ||
| 201 | - // must match and every dim must equal the broadcast dim. | ||
| 202 | - if (raw_out.size() != calc_info.shape_out.size()) { | ||
| 203 | - KERNEL_LOG_ERROR( | ||
| 204 | - "[%s] Output rank [%zu] does not match broadcast rank [%zu].", | ||
| 205 | - ctx.GetOpType().c_str(), raw_out.size(), calc_info.shape_out.size()); | ||
| 206 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 207 | - } | ||
| 208 | - for (size_t i = 0; i < raw_out.size(); ++i) { | ||
| 209 | - if (raw_out[i] != calc_info.shape_out[i]) { | ||
| 210 | - KERNEL_LOG_ERROR( | ||
| 211 | - "[%s] Output dim[%zu]=%ld mismatches broadcast dim=%ld.", | ||
| 212 | - ctx.GetOpType().c_str(), i, raw_out[i], calc_info.shape_out[i]); | ||
| 213 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 214 | } | 251 | } |
| 215 | - } | 252 | + if (n1 == 1 && n0 == ny && raw0 == raw_out) { |
| 216 | - return KERNEL_STATUS_OK; | 253 | + KERNEL_LOG_INFO("[%s] x1-scalar bcast branch selected, elems=%ld.", ctx.GetOpType().c_str(), ny); |
| 217 | -} | 254 | + return AddScalarBcast<T>(ctx, x0_ptr, *x1_ptr, y_ptr, ny); |
| 218 | - | 255 | + } |
| 219 | -template <typename T> | 256 | + return AddGenericBcast<T>(ctx, calc_info); |
| 220 | -uint32_t AddCpuKernel::AddCompute(const CpuKernelContext &ctx) const { | 257 | +} |
| 221 | - BCalcInfo calc_info; | 258 | + |
| 222 | - calc_info.input_0 = ctx.Input(kFirstInputIndex); | 259 | +template <typename T> |
| 223 | - calc_info.input_1 = ctx.Input(kSecondInputIndex); | 260 | +uint32_t AddCpuKernel::AddCalculateWithRankCheck(const CpuKernelContext& ctx, BCalcInfo& calc_info) const |
| 224 | - calc_info.output = ctx.Output(kFirstOutputIndex); | 261 | +{ |
| 225 | - | 262 | + const int32_t rank = static_cast<int32_t>(calc_info.shape_out.size()); |
| 226 | - KERNEL_CHECK_NULLPTR(calc_info.input_0->GetData(), | 263 | + switch (rank) { |
| 227 | - KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[0] data failed", | 264 | + case 0: { |
| 228 | - ctx.GetOpType().c_str()) | 265 | + // Rank-0 already handled by same-shape fast path, but keep for safety. |
| 229 | - KERNEL_CHECK_NULLPTR(calc_info.input_1->GetData(), | 266 | + const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData()); |
| 230 | - KERNEL_STATUS_PARAM_INVALID, "[%s] Get input[1] data failed", | 267 | + const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData()); |
| 231 | - ctx.GetOpType().c_str()) | 268 | + T* value_out = PtrToPtr<void, T>(calc_info.output->GetData()); |
| 232 | - KERNEL_CHECK_NULLPTR(calc_info.output->GetData(), KERNEL_STATUS_PARAM_INVALID, | 269 | + *value_out = v0 + v1; |
| 233 | - "[%s] Get output data failed", ctx.GetOpType().c_str()) | 270 | + return KERNEL_STATUS_OK; |
| 234 | - | 271 | + } |
| 235 | - T *const x0_ptr = PtrToPtr<void, T>(calc_info.input_0->GetData()); | 272 | + case kRank1: |
| 236 | - T *const x1_ptr = PtrToPtr<void, T>(calc_info.input_1->GetData()); | 273 | + return AddCalculateWithAlignedCheck<kRank1, T>(ctx, calc_info); |
| 237 | - T *const y_ptr = PtrToPtr<void, T>(calc_info.output->GetData()); | 274 | + case kRank2: |
| 238 | - | 275 | + return AddCalculateWithAlignedCheck<kRank2, T>(ctx, calc_info); |
| 239 | - const int64_t n0 = calc_info.input_0->NumElements(); | 276 | + case kRank3: |
| 240 | - const int64_t n1 = calc_info.input_1->NumElements(); | 277 | + return AddCalculateWithAlignedCheck<kRank3, T>(ctx, calc_info); |
| 241 | - const int64_t ny = calc_info.output->NumElements(); | 278 | + case kRank4: |
| 242 | - | 279 | + return AddCalculateWithAlignedCheck<kRank4, T>(ctx, calc_info); |
| 243 | - KERNEL_LOG_INFO("[%s] Input[0] size=%lu, Input[1] size=%lu, Output size=%lu.", | 280 | + case kRank5: |
| 244 | - ctx.GetOpType().c_str(), calc_info.input_0->GetDataSize(), | 281 | + return AddCalculateWithAlignedCheck<kRank5, T>(ctx, calc_info); |
| 245 | - calc_info.input_1->GetDataSize(), | 282 | + case kRank6: |
| 246 | - calc_info.output->GetDataSize()); | 283 | + return AddCalculateWithAlignedCheck<kRank6, T>(ctx, calc_info); |
| 247 | - | 284 | + case kRank7: |
| 248 | - const uint32_t vrc = ValidateAndBroadcast(ctx, calc_info); | 285 | + return AddCalculateWithAlignedCheck<kRank7, T>(ctx, calc_info); |
| 249 | - if (vrc != KERNEL_STATUS_OK) { | 286 | + case kRank8: |
| 250 | - return vrc; | 287 | + return AddCalculateWithAlignedCheck<kRank8, T>(ctx, calc_info); |
| 251 | - } | 288 | + default: |
| 252 | - | 289 | + KERNEL_LOG_ERROR("[%s] Rank of output must be in [0,8], got rank=%zu.", ctx.GetOpType().c_str(), |
| 253 | - const auto &raw0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); | 290 | + calc_info.shape_out.size()); |
| 254 | - const auto &raw1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); | 291 | + return KERNEL_STATUS_PARAM_INVALID; |
| 255 | - const auto &raw_out = calc_info.output->GetTensorShape()->GetDimSizes(); | ||
| 256 | - | ||
| 257 | - if (raw0 == raw1 && raw0 == raw_out && n0 == n1 && n0 == ny) { | ||
| 258 | - KERNEL_LOG_INFO("[%s] same-shape branch selected, elems=%ld.", | ||
| 259 | - ctx.GetOpType().c_str(), ny); | ||
| 260 | - return AddSameShape<T>(ctx, x0_ptr, x1_ptr, y_ptr, ny); | ||
| 261 | - } | ||
| 262 | - if (n0 == 1 && n1 == ny && raw1 == raw_out) { | ||
| 263 | - KERNEL_LOG_INFO("[%s] x0-scalar bcast branch selected, elems=%ld.", | ||
| 264 | - ctx.GetOpType().c_str(), ny); | ||
| 265 | - return AddScalarBcast<T>(ctx, x1_ptr, *x0_ptr, y_ptr, ny); | ||
| 266 | - } | ||
| 267 | - if (n1 == 1 && n0 == ny && raw0 == raw_out) { | ||
| 268 | - KERNEL_LOG_INFO("[%s] x1-scalar bcast branch selected, elems=%ld.", | ||
| 269 | - ctx.GetOpType().c_str(), ny); | ||
| 270 | - return AddScalarBcast<T>(ctx, x0_ptr, *x1_ptr, y_ptr, ny); | ||
| 271 | - } | ||
| 272 | - return AddGenericBcast<T>(ctx, calc_info); | ||
| 273 | -} | ||
| 274 | - | ||
| 275 | -template <typename T> | ||
| 276 | -uint32_t AddCpuKernel::AddCalculateWithRankCheck(const CpuKernelContext &ctx, | ||
| 277 | - BCalcInfo &calc_info) const { | ||
| 278 | - const int32_t rank = static_cast<int32_t>(calc_info.shape_out.size()); | ||
| 279 | - switch (rank) { | ||
| 280 | - case 0: { | ||
| 281 | - // Rank-0 already handled by same-shape fast path, but keep for safety. | ||
| 282 | - const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData()); | ||
| 283 | - const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData()); | ||
| 284 | - T *value_out = PtrToPtr<void, T>(calc_info.output->GetData()); | ||
| 285 | - *value_out = v0 + v1; | ||
| 286 | - return KERNEL_STATUS_OK; | ||
| 287 | } | 292 | } |
| 288 | - case kRank1: | ||
| 289 | - return AddCalculateWithAlignedCheck<kRank1, T>(ctx, calc_info); | ||
| 290 | - case kRank2: | ||
| 291 | - return AddCalculateWithAlignedCheck<kRank2, T>(ctx, calc_info); | ||
| 292 | - case kRank3: | ||
| 293 | - return AddCalculateWithAlignedCheck<kRank3, T>(ctx, calc_info); | ||
| 294 | - case kRank4: | ||
| 295 | - return AddCalculateWithAlignedCheck<kRank4, T>(ctx, calc_info); | ||
| 296 | - case kRank5: | ||
| 297 | - return AddCalculateWithAlignedCheck<kRank5, T>(ctx, calc_info); | ||
| 298 | - case kRank6: | ||
| 299 | - return AddCalculateWithAlignedCheck<kRank6, T>(ctx, calc_info); | ||
| 300 | - case kRank7: | ||
| 301 | - return AddCalculateWithAlignedCheck<kRank7, T>(ctx, calc_info); | ||
| 302 | - case kRank8: | ||
| 303 | - return AddCalculateWithAlignedCheck<kRank8, T>(ctx, calc_info); | ||
| 304 | - default: | ||
| 305 | - KERNEL_LOG_ERROR( | ||
| 306 | - "[%s] Rank of output must be in [0,8], got rank=%zu.", | ||
| 307 | - ctx.GetOpType().c_str(), calc_info.shape_out.size()); | ||
| 308 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 309 | - } | ||
| 310 | } | 293 | } |
| 311 | 294 | ||
| 312 | template <int32_t RANK, typename T> | 295 | template <int32_t RANK, typename T> |
| 313 | -uint32_t AddCpuKernel::AddCalculateWithAlignedCheck( | 296 | +uint32_t AddCpuKernel::AddCalculateWithAlignedCheck(const CpuKernelContext& ctx, BCalcInfo& calc_info) const |
| 314 | - const CpuKernelContext &ctx, BCalcInfo &calc_info) const { | 297 | +{ |
| 315 | - (void)ctx; | 298 | + (void)ctx; |
| 316 | - if (AlignedCheck(calc_info)) { | 299 | + if (AlignedCheck(calc_info)) { |
| 317 | - return AddCalculate<RANK, T, Eigen::Aligned>(calc_info); | 300 | + return AddCalculate<RANK, T, Eigen::Aligned>(calc_info); |
| 318 | - } | 301 | + } |
| 319 | - return AddCalculate<RANK, T, Eigen::Unaligned>(calc_info); | 302 | + return AddCalculate<RANK, T, Eigen::Unaligned>(calc_info); |
| 320 | } | 303 | } |
| 321 | 304 | ||
| 322 | -bool AddCpuKernel::AlignedCheck(const BCalcInfo &calc_info) const { | 305 | +bool AddCpuKernel::AlignedCheck(const BCalcInfo& calc_info) const |
| 323 | - return AddrAlignedCheck(calc_info.input_0->GetData()) && | 306 | +{ |
| 324 | - AddrAlignedCheck(calc_info.input_1->GetData()) && | 307 | + return AddrAlignedCheck(calc_info.input_0->GetData()) && AddrAlignedCheck(calc_info.input_1->GetData()) && |
| 325 | - AddrAlignedCheck(calc_info.output->GetData()); | 308 | + AddrAlignedCheck(calc_info.output->GetData()); |
| 326 | } | 309 | } |
| 327 | 310 | ||
| 328 | template <int32_t RANK, typename T, int32_t OPTION> | 311 | template <int32_t RANK, typename T, int32_t OPTION> |
| 329 | -uint32_t AddCpuKernel::AddCalculate(BCalcInfo &calc_info) const { | 312 | +uint32_t AddCpuKernel::AddCalculate(BCalcInfo& calc_info) const |
| 330 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input0( | 313 | +{ |
| 331 | - PtrToPtr<void, T>(calc_info.input_0->GetData()), | 314 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input0(PtrToPtr<void, T>(calc_info.input_0->GetData()), |
| 332 | - calc_info.input_0->GetTensorShape()->NumElements()); | 315 | + calc_info.input_0->GetTensorShape()->NumElements()); |
| 333 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1( | 316 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(PtrToPtr<void, T>(calc_info.input_1->GetData()), |
| 334 | - PtrToPtr<void, T>(calc_info.input_1->GetData()), | 317 | + calc_info.input_1->GetTensorShape()->NumElements()); |
| 335 | - calc_info.input_1->GetTensorShape()->NumElements()); | 318 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(PtrToPtr<void, T>(calc_info.output->GetData()), |
| 336 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output( | 319 | + calc_info.output->GetTensorShape()->NumElements()); |
| 337 | - PtrToPtr<void, T>(calc_info.output->GetData()), | 320 | + const auto& input_shape_0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); |
| 338 | - calc_info.output->GetTensorShape()->NumElements()); | 321 | + const auto& input_shape_1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); |
| 339 | - const auto &input_shape_0 = calc_info.input_0->GetTensorShape()->GetDimSizes(); | 322 | + if (input_shape_0.empty()) { |
| 340 | - const auto &input_shape_1 = calc_info.input_1->GetTensorShape()->GetDimSizes(); | 323 | + const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData()); |
| 341 | - if (input_shape_0.empty()) { | 324 | + output = v0 + input1; |
| 342 | - const T v0 = *PtrToPtr<void, const T>(calc_info.input_0->GetData()); | 325 | + return KERNEL_STATUS_OK; |
| 343 | - output = v0 + input1; | 326 | + } |
| 327 | + | ||
| 328 | + if (input_shape_1.empty()) { | ||
| 329 | + const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData()); | ||
| 330 | + output = input0 + v1; | ||
| 331 | + return KERNEL_STATUS_OK; | ||
| 332 | + } | ||
| 333 | + | ||
| 334 | + Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0; | ||
| 335 | + Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1; | ||
| 336 | + Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out; | ||
| 337 | + Eigen::array<Eigen::DenseIndex, RANK> bcast0; | ||
| 338 | + Eigen::array<Eigen::DenseIndex, RANK> bcast1; | ||
| 339 | + | ||
| 340 | + for (int32_t i = 0; i < RANK; i++) { | ||
| 341 | + reshape0[(RANK - i) - 1] = calc_info.reshape_0[i]; | ||
| 342 | + reshape1[(RANK - i) - 1] = calc_info.reshape_1[i]; | ||
| 343 | + shape_out[(RANK - i) - 1] = calc_info.shape_out[i]; | ||
| 344 | + bcast0[(RANK - i) - 1] = calc_info.bcast_0[i]; | ||
| 345 | + bcast1[(RANK - i) - 1] = calc_info.bcast_1[i]; | ||
| 346 | + } | ||
| 347 | + output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0) + input1.reshape(reshape1).broadcast(bcast1); | ||
| 344 | return KERNEL_STATUS_OK; | 348 | return KERNEL_STATUS_OK; |
| 345 | - } | ||
| 346 | - | ||
| 347 | - if (input_shape_1.empty()) { | ||
| 348 | - const T v1 = *PtrToPtr<void, const T>(calc_info.input_1->GetData()); | ||
| 349 | - output = input0 + v1; | ||
| 350 | - return KERNEL_STATUS_OK; | ||
| 351 | - } | ||
| 352 | - | ||
| 353 | - Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0; | ||
| 354 | - Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1; | ||
| 355 | - Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out; | ||
| 356 | - Eigen::array<Eigen::DenseIndex, RANK> bcast0; | ||
| 357 | - Eigen::array<Eigen::DenseIndex, RANK> bcast1; | ||
| 358 | - | ||
| 359 | - for (int32_t i = 0; i < RANK; i++) { | ||
| 360 | - reshape0[(RANK - i) - 1] = calc_info.reshape_0[i]; | ||
| 361 | - reshape1[(RANK - i) - 1] = calc_info.reshape_1[i]; | ||
| 362 | - shape_out[(RANK - i) - 1] = calc_info.shape_out[i]; | ||
| 363 | - bcast0[(RANK - i) - 1] = calc_info.bcast_0[i]; | ||
| 364 | - bcast1[(RANK - i) - 1] = calc_info.bcast_1[i]; | ||
| 365 | - } | ||
| 366 | - output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0) + | ||
| 367 | - input1.reshape(reshape1).broadcast(bcast1); | ||
| 368 | - return KERNEL_STATUS_OK; | ||
| 369 | } | 349 | } |
| 370 | 350 | ||
| 371 | -REGISTER_CPU_KERNEL(kAdd, AddCpuKernel); | 351 | +OPS_MATH_REGISTER_CPU_KERNELV2(kAdd, AddCpuKernel); |
| 372 | -} // namespace aicpu | 352 | +} // namespace aicpu |
| @@ -12,4 +12,4 @@ | |||
| 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") | 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") |
| 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") | 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") |
| 15 | -add_all_modules_sources(OPTYPE round ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | 15 | +add_all_modules_sources(OPTYPE round ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE) |
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | + | ||
| 14 | 15 | ||
| 15 | 16 | ||
| 16 | 17 | ||
| @@ -18,144 +19,145 @@ | |||
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | namespace { | 21 | namespace { |
| 21 | -const char *const kRound = "Round"; | 22 | +const char* const kRound = "Round"; |
| 22 | 23 | ||
| 23 | -bool IsValueEqualForDouble(double a, double b) { | 24 | +bool IsValueEqualForDouble(double a, double b) |
| 24 | - bool has_inf = std::isinf(a) || std::isinf(b); | 25 | +{ |
| 25 | - bool has_nan = std::isnan(a) || std::isnan(b); | 26 | + bool has_inf = std::isinf(a) || std::isinf(b); |
| 26 | - if (has_inf || has_nan) { | 27 | + bool has_nan = std::isnan(a) || std::isnan(b); |
| 27 | - return a == b; | 28 | + if (has_inf || has_nan) { |
| 28 | - } | 29 | + return a == b; |
| 29 | - constexpr double epsilon = 1e-14; | ||
| 30 | - return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b)); | ||
| 31 | -} | ||
| 32 | - | ||
| 33 | -template <typename T> | ||
| 34 | -inline auto DoCompute(const T &x) -> const T { | ||
| 35 | - T roundval = Eigen::numext::floor(x); | ||
| 36 | - const T fraction = x - roundval; | ||
| 37 | - const T point_five = T(.5); | ||
| 38 | - bool is_point_five = std::is_same<T, double>::value ? | ||
| 39 | - IsValueEqualForDouble(fraction, point_five) : aicpu::IsValueEqual<T>(fraction, point_five); | ||
| 40 | - if (fraction > point_five) { | ||
| 41 | - roundval += T(1.0); | ||
| 42 | - } else if (is_point_five) { | ||
| 43 | - const T nearest_even_int = | ||
| 44 | - roundval - T(2) * Eigen::numext::floor(point_five * x); | ||
| 45 | - bool is_odd = std::is_same<T, double>::value ? | ||
| 46 | - IsValueEqualForDouble(nearest_even_int, T(1)) : aicpu::IsValueEqual<T>(nearest_even_int, T(1)); | ||
| 47 | - if (is_odd) { | ||
| 48 | - roundval += T(1); | ||
| 49 | } | 30 | } |
| 50 | - } | 31 | + constexpr double epsilon = 1e-14; |
| 51 | - return roundval; | 32 | + return std::abs(a - b) <= epsilon * std::max(std::abs(a), std::abs(b)); |
| 52 | } | 33 | } |
| 53 | 34 | ||
| 54 | template <typename T> | 35 | template <typename T> |
| 55 | -inline auto ScalarRoundWithDecimals(const T &x, const T &pow_decimals, const bool &neg_flag) -> const T { | 36 | +inline auto DoCompute(const T& x) -> const T |
| 56 | - T roundval = neg_flag ? DoCompute<T>(x / pow_decimals) : DoCompute<T>(x * pow_decimals); | 37 | +{ |
| 57 | - return neg_flag ? roundval * pow_decimals : roundval / pow_decimals; | 38 | + T roundval = Eigen::numext::floor(x); |
| 39 | + const T fraction = x - roundval; | ||
| 40 | + const T point_five = T(.5); | ||
| 41 | + bool is_point_five = std::is_same<T, double>::value ? IsValueEqualForDouble(fraction, point_five) : | ||
| 42 | + aicpu::IsValueEqual<T>(fraction, point_five); | ||
| 43 | + if (fraction > point_five) { | ||
| 44 | + roundval += T(1.0); | ||
| 45 | + } else if (is_point_five) { | ||
| 46 | + const T nearest_even_int = roundval - T(2) * Eigen::numext::floor(point_five * x); | ||
| 47 | + bool is_odd = std::is_same<T, double>::value ? IsValueEqualForDouble(nearest_even_int, T(1)) : | ||
| 48 | + aicpu::IsValueEqual<T>(nearest_even_int, T(1)); | ||
| 49 | + if (is_odd) { | ||
| 50 | + roundval += T(1); | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + return roundval; | ||
| 58 | } | 54 | } |
| 55 | + | ||
| 56 | +template <typename T> | ||
| 57 | +inline auto ScalarRoundWithDecimals(const T& x, const T& pow_decimals, const bool& neg_flag) -> const T | ||
| 58 | +{ | ||
| 59 | + T roundval = neg_flag ? DoCompute<T>(x / pow_decimals) : DoCompute<T>(x * pow_decimals); | ||
| 60 | + return neg_flag ? roundval * pow_decimals : roundval / pow_decimals; | ||
| 59 | } | 61 | } |
| 62 | +} // namespace | ||
| 60 | 63 | ||
| 61 | namespace aicpu { | 64 | namespace aicpu { |
| 62 | template <typename T> | 65 | template <typename T> |
| 63 | -uint32_t RangeRound(CpuKernelContext &ctx, T *input, T *out, int64_t decimals) { | 66 | +uint32_t RangeRound(CpuKernelContext& ctx, T* input, T* out, int64_t decimals) |
| 64 | - uint32_t ret = 0; | 67 | +{ |
| 65 | - uint32_t max_core_num = std::max(1U, aicpu::CpuKernelUtils::GetCPUNum(ctx)); | 68 | + uint32_t ret = 0; |
| 66 | - int64_t input_datasize = ctx.Input(0)->NumElements(); | 69 | + uint32_t max_core_num = std::max(1U, aicpu::CpuKernelUtils::GetCPUNum(ctx)); |
| 67 | - auto per_unit_size = CeilMultiple(input_datasize, max_core_num); | 70 | + int64_t input_datasize = ctx.Input(0)->NumElements(); |
| 68 | - if (decimals == 0) { | 71 | + auto per_unit_size = CeilMultiple(input_datasize, max_core_num); |
| 69 | - auto shard_copy = [&input, &out](int64_t start, int64_t end) { | 72 | + if (decimals == 0) { |
| 70 | - constexpr bool isInt = (Eigen::NumTraits<T>::IsInteger != 0); | 73 | + auto shard_copy = [&input, &out](int64_t start, int64_t end) { |
| 71 | - if (isInt) { | 74 | + constexpr bool isInt = (Eigen::NumTraits<T>::IsInteger != 0); |
| 72 | - for (int64_t i = start; i < end; ++i) { | 75 | + if (isInt) { |
| 73 | - out[i] = input[i]; | 76 | + for (int64_t i = start; i < end; ++i) { |
| 77 | + out[i] = input[i]; | ||
| 78 | + } | ||
| 79 | + } else { | ||
| 80 | + for (int64_t i = start; i < end; ++i) { | ||
| 81 | + out[i] = DoCompute<T>(input[i]); | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + }; | ||
| 85 | + ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy); | ||
| 86 | + } else { | ||
| 87 | + bool neg_flag = false; | ||
| 88 | + if (decimals < 0) { | ||
| 89 | + decimals = -decimals; | ||
| 90 | + neg_flag = true; | ||
| 74 | } | 91 | } |
| 75 | - } else { | 92 | + const T pow_decimals = static_cast<T>(std::pow(10, decimals)); |
| 76 | - for (int64_t i = start; i < end; ++i) { | 93 | + auto shard_copy = [&input, &out, &pow_decimals, &neg_flag](int64_t start, int64_t end) { |
| 77 | - out[i] = DoCompute<T>(input[i]); | 94 | + for (int64_t i = start; i < end; ++i) { |
| 78 | - } | 95 | + out[i] = ScalarRoundWithDecimals<T>(input[i], pow_decimals, neg_flag); |
| 79 | - } | 96 | + } |
| 80 | - }; | 97 | + }; |
| 81 | - ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy); | 98 | + ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy); |
| 82 | - } else { | ||
| 83 | - bool neg_flag = false; | ||
| 84 | - if (decimals < 0) { | ||
| 85 | - decimals = -decimals; | ||
| 86 | - neg_flag = true; | ||
| 87 | } | 99 | } |
| 88 | - const T pow_decimals = static_cast<T>(std::pow(10, decimals)); | 100 | + return ret; |
| 89 | - auto shard_copy = [&input, &out, &pow_decimals, &neg_flag](int64_t start, int64_t end) { | ||
| 90 | - for (int64_t i = start; i < end; ++i) { | ||
| 91 | - out[i] = ScalarRoundWithDecimals<T>(input[i], pow_decimals, neg_flag); | ||
| 92 | - } | ||
| 93 | - }; | ||
| 94 | - ret = CpuKernelUtils::ParallelFor(ctx, input_datasize, per_unit_size, shard_copy); | ||
| 95 | - } | ||
| 96 | - return ret; | ||
| 97 | } | 101 | } |
| 98 | 102 | ||
| 99 | -bool RoundCpuKernel::CheckSupported(DataType input_type) const { | 103 | +bool RoundCpuKernel::CheckSupported(DataType input_type) const |
| 100 | - switch (input_type) { | 104 | +{ |
| 101 | - case DT_FLOAT16: | 105 | + switch (input_type) { |
| 102 | - case DT_FLOAT: | 106 | + case DT_FLOAT16: |
| 103 | - case DT_DOUBLE: | 107 | + case DT_FLOAT: |
| 104 | - case DT_INT32: | 108 | + case DT_DOUBLE: |
| 105 | - case DT_INT64: | 109 | + case DT_INT32: |
| 106 | - return true; | 110 | + case DT_INT64: |
| 107 | - default: | 111 | + return true; |
| 108 | - KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(input_type)); | 112 | + default: |
| 109 | - return false; | 113 | + KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(input_type)); |
| 110 | - } | 114 | + return false; |
| 115 | + } | ||
| 111 | } | 116 | } |
| 112 | 117 | ||
| 113 | -uint32_t RoundCpuKernel::Compute(CpuKernelContext &ctx) { | 118 | +uint32_t RoundCpuKernel::Compute(CpuKernelContext& ctx) |
| 114 | - Tensor *input_tensor = ctx.Input(0); | 119 | +{ |
| 115 | - KERNEL_CHECK_NULLPTR(input_tensor, KERNEL_STATUS_PARAM_INVALID, "Get input[0] failed") | 120 | + Tensor* input_tensor = ctx.Input(0); |
| 116 | - Tensor *output_tensor = ctx.Output(0); | 121 | + KERNEL_CHECK_NULLPTR(input_tensor, KERNEL_STATUS_PARAM_INVALID, "Get input[0] failed") |
| 117 | - KERNEL_CHECK_NULLPTR(output_tensor, KERNEL_STATUS_PARAM_INVALID, "Get output[0] failed") | 122 | + Tensor* output_tensor = ctx.Output(0); |
| 118 | - auto inputdata = input_tensor->GetData(); | 123 | + KERNEL_CHECK_NULLPTR(output_tensor, KERNEL_STATUS_PARAM_INVALID, "Get output[0] failed") |
| 119 | - KERNEL_CHECK_NULLPTR(inputdata, KERNEL_STATUS_PARAM_INVALID, "Get input[0] data failed") | 124 | + auto inputdata = input_tensor->GetData(); |
| 120 | - auto outputdata = output_tensor->GetData(); | 125 | + KERNEL_CHECK_NULLPTR(inputdata, KERNEL_STATUS_PARAM_INVALID, "Get input[0] data failed") |
| 121 | - KERNEL_CHECK_NULLPTR(outputdata, KERNEL_STATUS_PARAM_INVALID, "Get output[0] data failed") | 126 | + auto outputdata = output_tensor->GetData(); |
| 122 | - auto decimals_attr = ctx.GetAttr("decimals"); | 127 | + KERNEL_CHECK_NULLPTR(outputdata, KERNEL_STATUS_PARAM_INVALID, "Get output[0] data failed") |
| 123 | - int64_t decimals = 0; | 128 | + auto decimals_attr = ctx.GetAttr("decimals"); |
| 124 | - if (decimals_attr != nullptr) { | 129 | + int64_t decimals = 0; |
| 125 | - decimals = decimals_attr->GetInt(); | 130 | + if (decimals_attr != nullptr) { |
| 126 | - } | 131 | + decimals = decimals_attr->GetInt(); |
| 127 | - DataType inputtype = input_tensor->GetDataType(); | 132 | + } |
| 128 | - if (!CheckSupported(inputtype)) { | 133 | + DataType inputtype = input_tensor->GetDataType(); |
| 129 | - return KERNEL_STATUS_PARAM_INVALID; | 134 | + if (!CheckSupported(inputtype)) { |
| 130 | - } | 135 | + return KERNEL_STATUS_PARAM_INVALID; |
| 131 | - uint32_t ret = 0; | 136 | + } |
| 132 | - switch (inputtype) { | 137 | + uint32_t ret = 0; |
| 133 | - case DT_FLOAT16: | 138 | + switch (inputtype) { |
| 134 | - ret = RangeRound(ctx, static_cast<Eigen::half *>(inputdata), | 139 | + case DT_FLOAT16: |
| 135 | - static_cast<Eigen::half *>(outputdata), decimals); | 140 | + ret = RangeRound(ctx, static_cast<Eigen::half*>(inputdata), static_cast<Eigen::half*>(outputdata), |
| 136 | - break; | 141 | + decimals); |
| 137 | - case DT_FLOAT: | 142 | + break; |
| 138 | - ret = RangeRound(ctx, static_cast<float *>(inputdata), | 143 | + case DT_FLOAT: |
| 139 | - static_cast<float *>(outputdata), decimals); | 144 | + ret = RangeRound(ctx, static_cast<float*>(inputdata), static_cast<float*>(outputdata), decimals); |
| 140 | - break; | 145 | + break; |
| 141 | - case DT_DOUBLE: | 146 | + case DT_DOUBLE: |
| 142 | - ret = RangeRound(ctx, static_cast<double *>(inputdata), | 147 | + ret = RangeRound(ctx, static_cast<double*>(inputdata), static_cast<double*>(outputdata), decimals); |
| 143 | - static_cast<double *>(outputdata), decimals); | 148 | + break; |
| 144 | - break; | 149 | + case DT_INT32: |
| 145 | - case DT_INT32: | 150 | + ret = RangeRound(ctx, static_cast<int32_t*>(inputdata), static_cast<int32_t*>(outputdata), decimals); |
| 146 | - ret = RangeRound(ctx, static_cast<int32_t *>(inputdata), | 151 | + break; |
| 147 | - static_cast<int32_t *>(outputdata), decimals); | 152 | + case DT_INT64: |
| 148 | - break; | 153 | + ret = RangeRound(ctx, static_cast<int64_t*>(inputdata), static_cast<int64_t*>(outputdata), decimals); |
| 149 | - case DT_INT64: | 154 | + break; |
| 150 | - ret = RangeRound(ctx, static_cast<int64_t *>(inputdata), | 155 | + default: |
| 151 | - static_cast<int64_t *>(outputdata), decimals); | 156 | + KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(inputtype)); |
| 152 | - break; | 157 | + return KERNEL_STATUS_PARAM_INVALID; |
| 153 | - default: | 158 | + } |
| 154 | - KERNEL_LOG_ERROR("Unsupported input data type[%d]", static_cast<int32_t>(inputtype)); | 159 | + return ret; |
| 155 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 156 | - } | ||
| 157 | - return ret; | ||
| 158 | } | 160 | } |
| 159 | 161 | ||
| 160 | -REGISTER_CPU_KERNEL(kRound, RoundCpuKernel); | 162 | +OPS_MATH_REGISTER_CPU_KERNELV2(kRound, RoundCpuKernel); |
| 161 | -} // namespace aicpu | 163 | +} // namespace aicpu |
| @@ -1,11 +1,11 @@ | |||
| 1 | # --------------------------------------------------------------------------------------------------------- | 1 | # --------------------------------------------------------------------------------------------------------- |
| 2 | # Copyright (c) 2025 Huawei Technologies Co., Ltd. | 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 | 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"). | 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. | 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, | 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. | 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. | 8 | # See LICENSE in the root of the software repository for the full text of the License. |
| 9 | # --------------------------------------------------------------------------------------------------------- | 9 | # --------------------------------------------------------------------------------------------------------- |
| 10 | 10 | ||
| 11 | -add_all_modules_sources(OPTYPE search_sorted ACLNNTYPE aclnn_exclude) | 11 | +add_all_modules_sources(OPTYPE search_sorted ACLNNTYPE aclnn_exclude HOSTCPU TRUE) |
| @@ -0,0 +1,30 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +using namespace ge; | ||
| 15 | +namespace ops { | ||
| 16 | +static graphStatus InferShape4SearchSorted(gert::InferShapeContext* context) | ||
| 17 | +{ | ||
| 18 | + OP_LOGI("Begin InferShape4SearchSorted"); | ||
| 19 | + const gert::Shape* values_shape = context->GetInputShape(1); | ||
| 20 | + OP_CHECK_NULL_WITH_CONTEXT(context, values_shape); | ||
| 21 | + | ||
| 22 | + gert::Shape* out_shape = context->GetOutputShape(0); | ||
| 23 | + OP_CHECK_NULL_WITH_CONTEXT(context, out_shape); | ||
| 24 | + *out_shape = *values_shape; | ||
| 25 | + | ||
| 26 | + return GRAPH_SUCCESS; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +IMPL_OP_INFERSHAPE(SearchSorted).InferShape(InferShape4SearchSorted); | ||
| 30 | +} // namespace ops | ||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| @@ -258,5 +259,5 @@ uint32_t SearchSortedKernel::Compute(CpuKernelContext& ctx) | |||
| 258 | return iter->second[output_dtype_](right_, sequence_t_, values_t_, sorter_t_, output_t_, ctx); | 259 | return iter->second[output_dtype_](right_, sequence_t_, values_t_, sorter_t_, output_t_, ctx); |
| 259 | } | 260 | } |
| 260 | 261 | ||
| 261 | -REGISTER_CPU_KERNEL(kSearchSorted, SearchSortedKernel); | 262 | +OPS_MATH_REGISTER_CPU_KERNELV2(kSearchSorted, SearchSortedKernel); |
| 262 | } // namespace aicpu | 263 | } // namespace aicpu |
| @@ -12,4 +12,4 @@ | |||
| 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") | 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") |
| 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") | 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") |
| 15 | -add_all_modules_sources(OPTYPE select_v2 ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | 15 | +add_all_modules_sources(OPTYPE select_v2 ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE) |
| @@ -1,31 +0,0 @@ | |||
| 1 | -{ | ||
| 2 | - "SelectV2":{ | ||
| 3 | - "opInfo":{ | ||
| 4 | - "computeCost":"100", | ||
| 5 | - "engine":"DNN_VM_AICPU", | ||
| 6 | - "flagAsync":"False", | ||
| 7 | - "flagPartial":"False", | ||
| 8 | - "functionName":"RunCpuKernel", | ||
| 9 | - "kernelSo":"libmath_aicpu_kernels.so", | ||
| 10 | - "opKernelLib":"CUSTAICPUKernel", | ||
| 11 | - "userDefined":"True", | ||
| 12 | - "workspaceSize":"100" | ||
| 13 | - }, | ||
| 14 | - "input0": { | ||
| 15 | - "name": "condition", | ||
| 16 | - "type": "DT_BOOL" | ||
| 17 | - }, | ||
| 18 | - "input1": { | ||
| 19 | - "name": "then", | ||
| 20 | - "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL" | ||
| 21 | - }, | ||
| 22 | - "input2": { | ||
| 23 | - "name": "else", | ||
| 24 | - "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL" | ||
| 25 | - }, | ||
| 26 | - "output0": { | ||
| 27 | - "name": "result", | ||
| 28 | - "type": "DT_COMPLEX128,DT_COMPLEX64,DT_DOUBLE,DT_FLOAT,DT_FLOAT16,DT_INT16,DT_INT32,DT_INT64,DT_INT8,DT_UINT16,DT_UINT32,DT_UINT64,DT_UINT8,DT_BOOL" | ||
| 29 | - } | ||
| 30 | - } | ||
| 31 | -} | ||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | 19 | ||
| @@ -22,324 +23,305 @@ const uint32_t kInputNum = 3; | |||
| 22 | const int64_t kNoBroadcastValue = 1; | 23 | const int64_t kNoBroadcastValue = 1; |
| 23 | const int64_t kNoRepeatElements = 2; | 24 | const int64_t kNoRepeatElements = 2; |
| 24 | 25 | ||
| 25 | -#define SELECTV2_COMPUTE_CASE(DTYPE, TYPE) \ | 26 | +#define SELECTV2_COMPUTE_CASE(DTYPE, TYPE) \ |
| 26 | - case (DTYPE): { \ | 27 | + case (DTYPE): { \ |
| 27 | - KernelStatus result = Selectv2BuildBcast<TYPE>(ctx); \ | 28 | + KernelStatus result = Selectv2BuildBcast<TYPE>(ctx); \ |
| 28 | - if (result != KERNEL_STATUS_OK) { \ | 29 | + if (result != KERNEL_STATUS_OK) { \ |
| 29 | - KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \ | 30 | + KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \ |
| 30 | - return static_cast<uint32_t>(result); \ | 31 | + return static_cast<uint32_t>(result); \ |
| 31 | - } \ | 32 | + } \ |
| 32 | - break; \ | 33 | + break; \ |
| 33 | - } | 34 | + } |
| 34 | 35 | ||
| 35 | -#define SELECTV2_DIM_CASE(RANK) \ | 36 | +#define SELECTV2_DIM_CASE(RANK) \ |
| 36 | - case (RANK): { \ | 37 | + case (RANK): { \ |
| 37 | - KernelStatus result = \ | 38 | + KernelStatus result = SelectV2CalculateWithAlignedCheck<RANK, T>(calc_info); \ |
| 38 | - SelectV2CalculateWithAlignedCheck<RANK, T>(calc_info); \ | 39 | + if (result != KERNEL_STATUS_OK) { \ |
| 39 | - if (result != KERNEL_STATUS_OK) { \ | 40 | + KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \ |
| 40 | - KERNEL_LOG_ERROR("SelectV2 kernel compute failed."); \ | 41 | + return result; \ |
| 41 | - return result; \ | 42 | + } \ |
| 42 | - } \ | 43 | + break; \ |
| 43 | - break; \ | 44 | + } |
| 44 | - } | 45 | +} // namespace |
| 45 | -} // namespace | ||
| 46 | 46 | ||
| 47 | namespace aicpu { | 47 | namespace aicpu { |
| 48 | -uint32_t Selectv2CpuKernel::Compute(CpuKernelContext& ctx) { | 48 | +uint32_t Selectv2CpuKernel::Compute(CpuKernelContext& ctx) |
| 49 | - // check if input1 and input2 are of the same type | 49 | +{ |
| 50 | - if (Selectv2ParamCheck(ctx) != KERNEL_STATUS_OK) { | 50 | + // check if input1 and input2 are of the same type |
| 51 | - return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID); | 51 | + if (Selectv2ParamCheck(ctx) != KERNEL_STATUS_OK) { |
| 52 | - } | 52 | + return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID); |
| 53 | - // choose compute function depend on dataType | 53 | + } |
| 54 | - auto data_type = | 54 | + // choose compute function depend on dataType |
| 55 | - static_cast<DataType>(ctx.Input(kSecondInputIndex)->GetDataType()); | 55 | + auto data_type = static_cast<DataType>(ctx.Input(kSecondInputIndex)->GetDataType()); |
| 56 | - switch (data_type) { | 56 | + switch (data_type) { |
| 57 | - SELECTV2_COMPUTE_CASE(DT_FLOAT16, Eigen::half); | 57 | + SELECTV2_COMPUTE_CASE(DT_FLOAT16, Eigen::half); |
| 58 | - SELECTV2_COMPUTE_CASE(DT_FLOAT, float); | 58 | + SELECTV2_COMPUTE_CASE(DT_FLOAT, float); |
| 59 | - SELECTV2_COMPUTE_CASE(DT_DOUBLE, double); | 59 | + SELECTV2_COMPUTE_CASE(DT_DOUBLE, double); |
| 60 | - SELECTV2_COMPUTE_CASE(DT_INT8, int8_t); | 60 | + SELECTV2_COMPUTE_CASE(DT_INT8, int8_t); |
| 61 | - SELECTV2_COMPUTE_CASE(DT_INT16, int16_t); | 61 | + SELECTV2_COMPUTE_CASE(DT_INT16, int16_t); |
| 62 | - SELECTV2_COMPUTE_CASE(DT_INT32, int32_t); | 62 | + SELECTV2_COMPUTE_CASE(DT_INT32, int32_t); |
| 63 | - SELECTV2_COMPUTE_CASE(DT_INT64, int64_t); | 63 | + SELECTV2_COMPUTE_CASE(DT_INT64, int64_t); |
| 64 | - SELECTV2_COMPUTE_CASE(DT_UINT8, uint8_t); | 64 | + SELECTV2_COMPUTE_CASE(DT_UINT8, uint8_t); |
| 65 | - SELECTV2_COMPUTE_CASE(DT_UINT16, uint16_t); | 65 | + SELECTV2_COMPUTE_CASE(DT_UINT16, uint16_t); |
| 66 | - SELECTV2_COMPUTE_CASE(DT_UINT32, uint32_t); | 66 | + SELECTV2_COMPUTE_CASE(DT_UINT32, uint32_t); |
| 67 | - SELECTV2_COMPUTE_CASE(DT_UINT64, uint64_t); | 67 | + SELECTV2_COMPUTE_CASE(DT_UINT64, uint64_t); |
| 68 | - SELECTV2_COMPUTE_CASE(DT_COMPLEX64, std::complex<float>); | 68 | + SELECTV2_COMPUTE_CASE(DT_COMPLEX64, std::complex<float>); |
| 69 | - SELECTV2_COMPUTE_CASE(DT_COMPLEX128, std::complex<double>); | 69 | + SELECTV2_COMPUTE_CASE(DT_COMPLEX128, std::complex<double>); |
| 70 | - SELECTV2_COMPUTE_CASE(DT_BOOL, bool); | 70 | + SELECTV2_COMPUTE_CASE(DT_BOOL, bool); |
| 71 | - default: | 71 | + default: |
| 72 | - KERNEL_LOG_ERROR( | 72 | + KERNEL_LOG_ERROR("[%s] Data type of input is not support, input data type is [%s].", |
| 73 | - "[%s] Data type of input is not support, input data type is [%s].", | 73 | + ctx.GetOpType().c_str(), DTypeStr(data_type).c_str()); |
| 74 | - ctx.GetOpType().c_str(), DTypeStr(data_type).c_str()); | 74 | + return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID); |
| 75 | - return static_cast<uint32_t>(KERNEL_STATUS_PARAM_INVALID); | 75 | + } |
| 76 | - } | 76 | + return static_cast<uint32_t>(KERNEL_STATUS_OK); |
| 77 | - return static_cast<uint32_t>(KERNEL_STATUS_OK); | ||
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | -KernelStatus Selectv2CpuKernel::Selectv2ParamCheck( | 79 | +KernelStatus Selectv2CpuKernel::Selectv2ParamCheck(const CpuKernelContext& ctx) const |
| 81 | - const CpuKernelContext& ctx) const { | 80 | +{ |
| 82 | - KERNEL_CHECK_FALSE((ctx.GetInputsSize() >= kInputNum), | 81 | + KERNEL_CHECK_FALSE((ctx.GetInputsSize() >= kInputNum), KERNEL_STATUS_PARAM_INVALID, |
| 83 | - KERNEL_STATUS_PARAM_INVALID, | 82 | + "[%s] need [%u] inputs, but got [%u].", ctx.GetOpType().c_str(), kInputNum, ctx.GetInputsSize()); |
| 84 | - "[%s] need [%u] inputs, but got [%u].", | 83 | + DataType input1_type = DT_INT8; |
| 85 | - ctx.GetOpType().c_str(), kInputNum, ctx.GetInputsSize()); | 84 | + DataType input2_type = DT_UINT8; |
| 86 | - DataType input1_type = DT_INT8; | 85 | + for (uint32_t i = 0; i < kInputNum; ++i) { |
| 87 | - DataType input2_type = DT_UINT8; | 86 | + Tensor* input = ctx.Input(i); |
| 88 | - for (uint32_t i = 0; i < kInputNum; ++i) { | 87 | + KERNEL_CHECK_NULLPTR(input, KERNEL_STATUS_INNER_ERROR, "[%s] get input[%u] failed.", ctx.GetOpType().c_str(), |
| 89 | - Tensor* input = ctx.Input(i); | 88 | + i); |
| 90 | - KERNEL_CHECK_NULLPTR(input, KERNEL_STATUS_INNER_ERROR, | 89 | + if (i == kSecondInputIndex) { |
| 91 | - "[%s] get input[%u] failed.", ctx.GetOpType().c_str(), | 90 | + input1_type = input->GetDataType(); |
| 92 | - i); | 91 | + } |
| 93 | - if (i == kSecondInputIndex) { | 92 | + if (i == kThirdInputIndex) { |
| 94 | - input1_type = input->GetDataType(); | 93 | + input2_type = input->GetDataType(); |
| 94 | + } | ||
| 95 | + // After confirming that it is a non-empty tensor, perform this step of | ||
| 96 | + // verification | ||
| 97 | + if (!IsEmptyTensor(input)) { | ||
| 98 | + auto input_data = input->GetData(); | ||
| 99 | + KERNEL_CHECK_NULLPTR(input_data, KERNEL_STATUS_PARAM_INVALID, "[%s] get input[%u] tensor data is nullptr.", | ||
| 100 | + ctx.GetOpType().c_str(), i); | ||
| 101 | + } | ||
| 95 | } | 102 | } |
| 96 | - if (i == kThirdInputIndex) { | 103 | + KERNEL_CHECK_FALSE((input1_type == input2_type), KERNEL_STATUS_PARAM_INVALID, |
| 97 | - input2_type = input->GetDataType(); | 104 | + "The data type of input1 [%s] need be same with " |
| 105 | + "input2 [%s].", | ||
| 106 | + DTypeStr(input1_type).c_str(), DTypeStr(input2_type).c_str()) | ||
| 107 | + Tensor* output = ctx.Output(kFirstOutputIndex); | ||
| 108 | + KERNEL_CHECK_NULLPTR(output, KERNEL_STATUS_INNER_ERROR, "[%s] get output failed.", ctx.GetOpType().c_str()); | ||
| 109 | + if (!IsEmptyTensor(output)) { | ||
| 110 | + auto output_data = output->GetData(); | ||
| 111 | + KERNEL_CHECK_NULLPTR(output_data, KERNEL_STATUS_PARAM_INVALID, "[%s] get output tensor data is nullptr.", | ||
| 112 | + ctx.GetOpType().c_str()); | ||
| 98 | } | 113 | } |
| 99 | - // After confirming that it is a non-empty tensor, perform this step of | 114 | + return KERNEL_STATUS_OK; |
| 100 | - // verification | ||
| 101 | - if (!IsEmptyTensor(input)) { | ||
| 102 | - auto input_data = input->GetData(); | ||
| 103 | - KERNEL_CHECK_NULLPTR(input_data, KERNEL_STATUS_PARAM_INVALID, | ||
| 104 | - "[%s] get input[%u] tensor data is nullptr.", | ||
| 105 | - ctx.GetOpType().c_str(), i); | ||
| 106 | - } | ||
| 107 | - } | ||
| 108 | - KERNEL_CHECK_FALSE((input1_type == input2_type), KERNEL_STATUS_PARAM_INVALID, | ||
| 109 | - "The data type of input1 [%s] need be same with " | ||
| 110 | - "input2 [%s].", | ||
| 111 | - DTypeStr(input1_type).c_str(), | ||
| 112 | - DTypeStr(input2_type).c_str()) | ||
| 113 | - Tensor* output = ctx.Output(kFirstOutputIndex); | ||
| 114 | - KERNEL_CHECK_NULLPTR(output, KERNEL_STATUS_INNER_ERROR, | ||
| 115 | - "[%s] get output failed.", ctx.GetOpType().c_str()); | ||
| 116 | - if (!IsEmptyTensor(output)) { | ||
| 117 | - auto output_data = output->GetData(); | ||
| 118 | - KERNEL_CHECK_NULLPTR(output_data, KERNEL_STATUS_PARAM_INVALID, | ||
| 119 | - "[%s] get output tensor data is nullptr.", | ||
| 120 | - ctx.GetOpType().c_str()); | ||
| 121 | - } | ||
| 122 | - return KERNEL_STATUS_OK; | ||
| 123 | } | 115 | } |
| 124 | 116 | ||
| 125 | template <typename T> | 117 | template <typename T> |
| 126 | -KernelStatus Selectv2CpuKernel::Selectv2BuildBcast( | 118 | +KernelStatus Selectv2CpuKernel::Selectv2BuildBcast(const CpuKernelContext& ctx) |
| 127 | - const CpuKernelContext& ctx) { | 119 | +{ |
| 128 | - Tensor* input_0 = ctx.Input(kFirstInputIndex); | 120 | + Tensor* input_0 = ctx.Input(kFirstInputIndex); |
| 129 | - Tensor* input_1 = ctx.Input(kSecondInputIndex); | 121 | + Tensor* input_1 = ctx.Input(kSecondInputIndex); |
| 130 | - Tensor* input_2 = ctx.Input(kThirdInputIndex); | 122 | + Tensor* input_2 = ctx.Input(kThirdInputIndex); |
| 131 | - Tensor* output = ctx.Output(kFirstOutputIndex); | 123 | + Tensor* output = ctx.Output(kFirstOutputIndex); |
| 132 | 124 | ||
| 133 | - if (input_0->GetDataSize() == 0 || input_1->GetDataSize() == 0 || | 125 | + if (input_0->GetDataSize() == 0 || input_1->GetDataSize() == 0 || input_2->GetDataSize() == 0) { |
| 134 | - input_2->GetDataSize() == 0) { | 126 | + KERNEL_LOG_WARN("SelectV2 kernel input tensor is empty."); |
| 135 | - KERNEL_LOG_WARN("SelectV2 kernel input tensor is empty."); | 127 | + return KERNEL_STATUS_OK; |
| 136 | - return KERNEL_STATUS_OK; | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - KERNEL_LOG_DEBUG( | ||
| 140 | - "Selectv2CpuKernel[%s], input0: size[%lu];" | ||
| 141 | - "input1: size[%lu], input2: size[%lu], output: size[%lu].", | ||
| 142 | - ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), | ||
| 143 | - input_2->GetDataSize(), output->GetDataSize()); | ||
| 144 | - | ||
| 145 | - SelectV2BCalcInfo calc_info; | ||
| 146 | - calc_info.input_0 = input_0; | ||
| 147 | - calc_info.input_1 = input_1; | ||
| 148 | - calc_info.input_2 = input_2; | ||
| 149 | - calc_info.output = output; | ||
| 150 | - | ||
| 151 | - // broadcast input | ||
| 152 | - if (Selectv2GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) { | ||
| 153 | - KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", kSelectV2); | ||
| 154 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 155 | - } | ||
| 156 | - SelectV2GetBcastVec(calc_info); | ||
| 157 | - int32_t rank = static_cast<int32_t>(calc_info.shape_out.size()); | ||
| 158 | - switch (rank) { | ||
| 159 | - case SCALAR: { | ||
| 160 | - bool v0 = *(reinterpret_cast<const bool*>(calc_info.input_0->GetData())); | ||
| 161 | - T v1 = *(reinterpret_cast<const T*>(calc_info.input_1->GetData())); | ||
| 162 | - T v2 = *(reinterpret_cast<const T*>(calc_info.input_2->GetData())); | ||
| 163 | - T* value_out = reinterpret_cast<T*>(calc_info.output->GetData()); | ||
| 164 | - *(value_out) = (v0 == true) ? v1 : v2; | ||
| 165 | - return KERNEL_STATUS_OK; | ||
| 166 | } | 128 | } |
| 167 | - SELECTV2_DIM_CASE(ONE_DIM); | 129 | + |
| 168 | - SELECTV2_DIM_CASE(TWO_DIM); | 130 | + KERNEL_LOG_DEBUG("Selectv2CpuKernel[%s], input0: size[%lu];" |
| 169 | - SELECTV2_DIM_CASE(THREE_DIM); | 131 | + "input1: size[%lu], input2: size[%lu], output: size[%lu].", |
| 170 | - SELECTV2_DIM_CASE(FOUR_DIM); | 132 | + ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), input_2->GetDataSize(), |
| 171 | - SELECTV2_DIM_CASE(FIVE_DIM); | 133 | + output->GetDataSize()); |
| 172 | - SELECTV2_DIM_CASE(SIX_DIM); | 134 | + |
| 173 | - SELECTV2_DIM_CASE(SEVEN_DIM); | 135 | + SelectV2BCalcInfo calc_info; |
| 174 | - SELECTV2_DIM_CASE(EIGHT_DIM); | 136 | + calc_info.input_0 = input_0; |
| 175 | - default: | 137 | + calc_info.input_1 = input_1; |
| 176 | - KERNEL_LOG_ERROR("[%s] Rank of output should less than 9 but get [%zu].", | 138 | + calc_info.input_2 = input_2; |
| 177 | - ctx.GetOpType().c_str(), calc_info.shape_out.size()); | 139 | + calc_info.output = output; |
| 178 | - return KERNEL_STATUS_PARAM_INVALID; | 140 | + |
| 179 | - } | 141 | + // broadcast input |
| 180 | - return KERNEL_STATUS_OK; | 142 | + if (Selectv2GenerateBcastInfo(calc_info) != KERNEL_STATUS_OK) { |
| 143 | + KERNEL_LOG_ERROR("[%s] Generate broadcast info failed.", kSelectV2); | ||
| 144 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 145 | + } | ||
| 146 | + SelectV2GetBcastVec(calc_info); | ||
| 147 | + int32_t rank = static_cast<int32_t>(calc_info.shape_out.size()); | ||
| 148 | + switch (rank) { | ||
| 149 | + case SCALAR: { | ||
| 150 | + bool v0 = *(reinterpret_cast<const bool*>(calc_info.input_0->GetData())); | ||
| 151 | + T v1 = *(reinterpret_cast<const T*>(calc_info.input_1->GetData())); | ||
| 152 | + T v2 = *(reinterpret_cast<const T*>(calc_info.input_2->GetData())); | ||
| 153 | + T* value_out = reinterpret_cast<T*>(calc_info.output->GetData()); | ||
| 154 | + *(value_out) = (v0 == true) ? v1 : v2; | ||
| 155 | + return KERNEL_STATUS_OK; | ||
| 156 | + } | ||
| 157 | + SELECTV2_DIM_CASE(ONE_DIM); | ||
| 158 | + SELECTV2_DIM_CASE(TWO_DIM); | ||
| 159 | + SELECTV2_DIM_CASE(THREE_DIM); | ||
| 160 | + SELECTV2_DIM_CASE(FOUR_DIM); | ||
| 161 | + SELECTV2_DIM_CASE(FIVE_DIM); | ||
| 162 | + SELECTV2_DIM_CASE(SIX_DIM); | ||
| 163 | + SELECTV2_DIM_CASE(SEVEN_DIM); | ||
| 164 | + SELECTV2_DIM_CASE(EIGHT_DIM); | ||
| 165 | + default: | ||
| 166 | + KERNEL_LOG_ERROR("[%s] Rank of output should less than 9 but get [%zu].", ctx.GetOpType().c_str(), | ||
| 167 | + calc_info.shape_out.size()); | ||
| 168 | + return KERNEL_STATUS_PARAM_INVALID; | ||
| 169 | + } | ||
| 170 | + return KERNEL_STATUS_OK; | ||
| 181 | } | 171 | } |
| 182 | 172 | ||
| 183 | template <int32_t RANK, typename T> | 173 | template <int32_t RANK, typename T> |
| 184 | -KernelStatus Selectv2CpuKernel::SelectV2CalculateWithAlignedCheck( | 174 | +KernelStatus Selectv2CpuKernel::SelectV2CalculateWithAlignedCheck(SelectV2BCalcInfo& calc_info) |
| 185 | - SelectV2BCalcInfo& calc_info) { | 175 | +{ |
| 186 | - if (AlignedCheck(calc_info)) { | 176 | + if (AlignedCheck(calc_info)) { |
| 187 | - return SelectV2Calculate<RANK, T, Eigen::Aligned>(calc_info); | 177 | + return SelectV2Calculate<RANK, T, Eigen::Aligned>(calc_info); |
| 188 | - } | 178 | + } |
| 189 | - return SelectV2Calculate<RANK, T, Eigen::Unaligned>(calc_info); | 179 | + return SelectV2Calculate<RANK, T, Eigen::Unaligned>(calc_info); |
| 190 | } | 180 | } |
| 191 | 181 | ||
| 192 | -bool Selectv2CpuKernel::AlignedCheck(const SelectV2BCalcInfo& calc_info) const { | 182 | +bool Selectv2CpuKernel::AlignedCheck(const SelectV2BCalcInfo& calc_info) const |
| 193 | - return AddrAlignedCheck(calc_info.input_0->GetData()) && | 183 | +{ |
| 194 | - AddrAlignedCheck(calc_info.input_1->GetData()) && | 184 | + return AddrAlignedCheck(calc_info.input_0->GetData()) && AddrAlignedCheck(calc_info.input_1->GetData()) && |
| 195 | - AddrAlignedCheck(calc_info.input_2->GetData()) && | 185 | + AddrAlignedCheck(calc_info.input_2->GetData()) && AddrAlignedCheck(calc_info.output->GetData()); |
| 196 | - AddrAlignedCheck(calc_info.output->GetData()); | ||
| 197 | } | 186 | } |
| 198 | 187 | ||
| 199 | template <int32_t RANK, typename T, int32_t OPTION> | 188 | template <int32_t RANK, typename T, int32_t OPTION> |
| 200 | -KernelStatus Selectv2CpuKernel::SelectV2Calculate(SelectV2BCalcInfo& calc_info) { | 189 | +KernelStatus Selectv2CpuKernel::SelectV2Calculate(SelectV2BCalcInfo& calc_info) |
| 201 | - Eigen::TensorMap<Eigen::Tensor<bool, 1>, OPTION> input0( | 190 | +{ |
| 202 | - static_cast<bool*>(calc_info.input_0->GetData()), | 191 | + Eigen::TensorMap<Eigen::Tensor<bool, 1>, OPTION> input0(static_cast<bool*>(calc_info.input_0->GetData()), |
| 203 | - calc_info.input_0->GetTensorShape()->NumElements()); | 192 | + calc_info.input_0->GetTensorShape()->NumElements()); |
| 204 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1( | 193 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input1(static_cast<T*>(calc_info.input_1->GetData()), |
| 205 | - static_cast<T*>(calc_info.input_1->GetData()), | 194 | + calc_info.input_1->GetTensorShape()->NumElements()); |
| 206 | - calc_info.input_1->GetTensorShape()->NumElements()); | 195 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input2(static_cast<T*>(calc_info.input_2->GetData()), |
| 207 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> input2( | 196 | + calc_info.input_2->GetTensorShape()->NumElements()); |
| 208 | - static_cast<T*>(calc_info.input_2->GetData()), | 197 | + Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output(static_cast<T*>(calc_info.output->GetData()), |
| 209 | - calc_info.input_2->GetTensorShape()->NumElements()); | 198 | + calc_info.output->GetTensorShape()->NumElements()); |
| 210 | - Eigen::TensorMap<Eigen::Tensor<T, 1>, OPTION> output( | ||
| 211 | - static_cast<T*>(calc_info.output->GetData()), | ||
| 212 | - calc_info.output->GetTensorShape()->NumElements()); | ||
| 213 | 199 | ||
| 214 | - Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0; | 200 | + Eigen::DSizes<Eigen::DenseIndex, RANK> reshape0; |
| 215 | - Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1; | 201 | + Eigen::DSizes<Eigen::DenseIndex, RANK> reshape1; |
| 216 | - Eigen::DSizes<Eigen::DenseIndex, RANK> reshape2; | 202 | + Eigen::DSizes<Eigen::DenseIndex, RANK> reshape2; |
| 217 | - Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out; | 203 | + Eigen::DSizes<Eigen::DenseIndex, RANK> shape_out; |
| 218 | - Eigen::array<Eigen::DenseIndex, RANK> bcast0; | 204 | + Eigen::array<Eigen::DenseIndex, RANK> bcast0; |
| 219 | - Eigen::array<Eigen::DenseIndex, RANK> bcast1; | 205 | + Eigen::array<Eigen::DenseIndex, RANK> bcast1; |
| 220 | - Eigen::array<Eigen::DenseIndex, RANK> bcast2; | 206 | + Eigen::array<Eigen::DenseIndex, RANK> bcast2; |
| 221 | 207 | ||
| 222 | - for (size_t i = 0; i < static_cast<size_t>(RANK); ++i) { | 208 | + for (size_t i = 0; i < static_cast<size_t>(RANK); ++i) { |
| 223 | - size_t index = (static_cast<size_t>(RANK) - i) - 1UL; | 209 | + size_t index = (static_cast<size_t>(RANK) - i) - 1UL; |
| 224 | - reshape0[index] = calc_info.reshape_0[i]; | 210 | + reshape0[index] = calc_info.reshape_0[i]; |
| 225 | - reshape1[index] = calc_info.reshape_1[i]; | 211 | + reshape1[index] = calc_info.reshape_1[i]; |
| 226 | - reshape2[index] = calc_info.reshape_2[i]; | 212 | + reshape2[index] = calc_info.reshape_2[i]; |
| 227 | - shape_out[index] = calc_info.shape_out[i]; | 213 | + shape_out[index] = calc_info.shape_out[i]; |
| 228 | - bcast0[index] = calc_info.bcast_0[i]; | 214 | + bcast0[index] = calc_info.bcast_0[i]; |
| 229 | - bcast1[index] = calc_info.bcast_1[i]; | 215 | + bcast1[index] = calc_info.bcast_1[i]; |
| 230 | - bcast2[index] = calc_info.bcast_2[i]; | 216 | + bcast2[index] = calc_info.bcast_2[i]; |
| 231 | - } | 217 | + } |
| 232 | 218 | ||
| 233 | - output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0).select( | 219 | + output.reshape(shape_out) = input0.reshape(reshape0).broadcast(bcast0).select( |
| 234 | - input1.reshape(reshape1).broadcast(bcast1), | 220 | + input1.reshape(reshape1).broadcast(bcast1), input2.reshape(reshape2).broadcast(bcast2)); |
| 235 | - input2.reshape(reshape2).broadcast(bcast2)); | 221 | + return KERNEL_STATUS_OK; |
| 236 | - return KERNEL_STATUS_OK; | ||
| 237 | } | 222 | } |
| 238 | 223 | ||
| 239 | -KernelStatus Selectv2CpuKernel::Selectv2GenerateBcastInfo( | 224 | +KernelStatus Selectv2CpuKernel::Selectv2GenerateBcastInfo(const SelectV2BCalcInfo& calc_info) |
| 240 | - const SelectV2BCalcInfo& calc_info) { | 225 | +{ |
| 241 | - x_reshape_ = calc_info.input_0->GetTensorShape()->GetDimSizes(); | 226 | + x_reshape_ = calc_info.input_0->GetTensorShape()->GetDimSizes(); |
| 242 | - y_reshape_ = calc_info.input_1->GetTensorShape()->GetDimSizes(); | 227 | + y_reshape_ = calc_info.input_1->GetTensorShape()->GetDimSizes(); |
| 243 | - z_reshape_ = calc_info.input_2->GetTensorShape()->GetDimSizes(); | 228 | + z_reshape_ = calc_info.input_2->GetTensorShape()->GetDimSizes(); |
| 244 | - shape_out_ = calc_info.output->GetTensorShape()->GetDimSizes(); | 229 | + shape_out_ = calc_info.output->GetTensorShape()->GetDimSizes(); |
| 245 | 230 | ||
| 246 | - std::reverse(x_reshape_.begin(), x_reshape_.end()); | 231 | + std::reverse(x_reshape_.begin(), x_reshape_.end()); |
| 247 | - std::reverse(y_reshape_.begin(), y_reshape_.end()); | 232 | + std::reverse(y_reshape_.begin(), y_reshape_.end()); |
| 248 | - std::reverse(z_reshape_.begin(), z_reshape_.end()); | 233 | + std::reverse(z_reshape_.begin(), z_reshape_.end()); |
| 249 | 234 | ||
| 250 | - size_t dim_num_x = x_reshape_.size(); | 235 | + size_t dim_num_x = x_reshape_.size(); |
| 251 | - size_t dim_num_y = y_reshape_.size(); | 236 | + size_t dim_num_y = y_reshape_.size(); |
| 252 | - size_t dim_num_z = z_reshape_.size(); | 237 | + size_t dim_num_z = z_reshape_.size(); |
| 253 | 238 | ||
| 254 | - size_t max_size = std::max({dim_num_x, dim_num_y, dim_num_z}); | 239 | + size_t max_size = std::max({dim_num_x, dim_num_y, dim_num_z}); |
| 255 | - if (dim_num_x != max_size) { | 240 | + if (dim_num_x != max_size) { |
| 256 | - x_reshape_.resize(max_size, kNoBroadcastValue); | 241 | + x_reshape_.resize(max_size, kNoBroadcastValue); |
| 257 | - } | 242 | + } |
| 258 | - if (dim_num_y != max_size) { | 243 | + if (dim_num_y != max_size) { |
| 259 | - y_reshape_.resize(max_size, kNoBroadcastValue); | 244 | + y_reshape_.resize(max_size, kNoBroadcastValue); |
| 260 | - } | 245 | + } |
| 261 | - if (dim_num_z != max_size) { | 246 | + if (dim_num_z != max_size) { |
| 262 | - z_reshape_.resize(max_size, kNoBroadcastValue); | 247 | + z_reshape_.resize(max_size, kNoBroadcastValue); |
| 263 | - } | 248 | + } |
| 264 | - std::reverse(x_reshape_.begin(), x_reshape_.end()); | 249 | + std::reverse(x_reshape_.begin(), x_reshape_.end()); |
| 265 | - std::reverse(y_reshape_.begin(), y_reshape_.end()); | 250 | + std::reverse(y_reshape_.begin(), y_reshape_.end()); |
| 266 | - std::reverse(z_reshape_.begin(), z_reshape_.end()); | 251 | + std::reverse(z_reshape_.begin(), z_reshape_.end()); |
| 267 | - // Check if shape match | 252 | + // Check if shape match |
| 268 | - if (shape_out_.size() != max_size) { | 253 | + if (shape_out_.size() != max_size) { |
| 269 | - KERNEL_LOG_ERROR("shape mismatch, max_dim_in=%zu, dim_out=%zu.", max_size, | 254 | + KERNEL_LOG_ERROR("shape mismatch, max_dim_in=%zu, dim_out=%zu.", max_size, shape_out_.size()); |
| 270 | - shape_out_.size()); | 255 | + return KERNEL_STATUS_PARAM_INVALID; |
| 271 | - return KERNEL_STATUS_PARAM_INVALID; | 256 | + } |
| 272 | - } | 257 | + for (size_t i = 0; i < max_size; ++i) { |
| 273 | - for (size_t i = 0; i < max_size; ++i) { | 258 | + if (shape_out_[i] != std::max({x_reshape_[i], y_reshape_[i], z_reshape_[i]})) { |
| 274 | - if (shape_out_[i] != | 259 | + KERNEL_LOG_ERROR("shape mismatch, index=%zu, dim_x=%ld, dim_y=%ld, dim_z=%ld" |
| 275 | - std::max({x_reshape_[i], y_reshape_[i], z_reshape_[i]})) { | 260 | + "dim_out=%ld.", |
| 276 | - KERNEL_LOG_ERROR( | 261 | + i, x_reshape_[i], y_reshape_[i], z_reshape_[i], shape_out_[i]); |
| 277 | - "shape mismatch, index=%zu, dim_x=%ld, dim_y=%ld, dim_z=%ld" | 262 | + return KERNEL_STATUS_PARAM_INVALID; |
| 278 | - "dim_out=%ld.", | 263 | + } |
| 279 | - i, x_reshape_[i], y_reshape_[i], z_reshape_[i], shape_out_[i]); | ||
| 280 | - return KERNEL_STATUS_PARAM_INVALID; | ||
| 281 | } | 264 | } |
| 282 | - } | ||
| 283 | 265 | ||
| 284 | - // genarate broarcast info | 266 | + // genarate broarcast info |
| 285 | - if (SelectV2BcastInfo(max_size) != KERNEL_STATUS_OK) { | 267 | + if (SelectV2BcastInfo(max_size) != KERNEL_STATUS_OK) { |
| 286 | - KERNEL_LOG_ERROR("SelectV2 genarate broarcast info failed."); | 268 | + KERNEL_LOG_ERROR("SelectV2 genarate broarcast info failed."); |
| 287 | - return KERNEL_STATUS_PARAM_INVALID; | 269 | + return KERNEL_STATUS_PARAM_INVALID; |
| 288 | - } | 270 | + } |
| 289 | - return KERNEL_STATUS_OK; | 271 | + return KERNEL_STATUS_OK; |
| 290 | } | 272 | } |
| 291 | 273 | ||
| 292 | -KernelStatus Selectv2CpuKernel::SelectV2BcastInfo(size_t max_size) { | 274 | +KernelStatus Selectv2CpuKernel::SelectV2BcastInfo(size_t max_size) |
| 293 | - // genarate broarcast info | 275 | +{ |
| 294 | - x_bcast_.resize(max_size, kNoBroadcastValue); | 276 | + // genarate broarcast info |
| 295 | - y_bcast_.resize(max_size, kNoBroadcastValue); | 277 | + x_bcast_.resize(max_size, kNoBroadcastValue); |
| 296 | - z_bcast_.resize(max_size, kNoBroadcastValue); | 278 | + y_bcast_.resize(max_size, kNoBroadcastValue); |
| 297 | - for (size_t i = 0; i < max_size; ++i) { | 279 | + z_bcast_.resize(max_size, kNoBroadcastValue); |
| 298 | - // no need broadcast | 280 | + for (size_t i = 0; i < max_size; ++i) { |
| 299 | - if ((x_reshape_[i] == y_reshape_[i]) && (y_reshape_[i] == z_reshape_[i])) { | 281 | + // no need broadcast |
| 300 | - continue; | 282 | + if ((x_reshape_[i] == y_reshape_[i]) && (y_reshape_[i] == z_reshape_[i])) { |
| 301 | - } | 283 | + continue; |
| 284 | + } | ||
| 302 | 285 | ||
| 303 | - if (SelectV2BcastCheck(x_reshape_[i], y_reshape_[i], z_reshape_[i]) != | 286 | + if (SelectV2BcastCheck(x_reshape_[i], y_reshape_[i], z_reshape_[i]) != KERNEL_STATUS_OK) { |
| 304 | - KERNEL_STATUS_OK) { | 287 | + KERNEL_LOG_ERROR("Broadcast not support, dim_x[%zu]=%ld, dim_y[%zu]=%ld.", i, x_reshape_[i], i, |
| 305 | - KERNEL_LOG_ERROR("Broadcast not support, dim_x[%zu]=%ld, dim_y[%zu]=%ld.", | 288 | + y_reshape_[i]); |
| 306 | - i, x_reshape_[i], i, y_reshape_[i]); | 289 | + return KERNEL_STATUS_PARAM_INVALID; |
| 307 | - return KERNEL_STATUS_PARAM_INVALID; | 290 | + } |
| 291 | + if (x_reshape_[i] == kNoBroadcastValue) { | ||
| 292 | + x_bcast_[i] = std::max(y_reshape_[i], z_reshape_[i]); | ||
| 293 | + } | ||
| 294 | + if (y_reshape_[i] == kNoBroadcastValue) { | ||
| 295 | + y_bcast_[i] = std::max(x_reshape_[i], z_reshape_[i]); | ||
| 296 | + } | ||
| 297 | + if (z_reshape_[i] == kNoBroadcastValue) { | ||
| 298 | + z_bcast_[i] = std::max(x_reshape_[i], y_reshape_[i]); | ||
| 299 | + } | ||
| 308 | } | 300 | } |
| 309 | - if (x_reshape_[i] == kNoBroadcastValue) { | 301 | + return KERNEL_STATUS_OK; |
| 310 | - x_bcast_[i] = std::max(y_reshape_[i], z_reshape_[i]); | ||
| 311 | - } | ||
| 312 | - if (y_reshape_[i] == kNoBroadcastValue) { | ||
| 313 | - y_bcast_[i] = std::max(x_reshape_[i], z_reshape_[i]); | ||
| 314 | - } | ||
| 315 | - if (z_reshape_[i] == kNoBroadcastValue) { | ||
| 316 | - z_bcast_[i] = std::max(x_reshape_[i], y_reshape_[i]); | ||
| 317 | - } | ||
| 318 | - } | ||
| 319 | - return KERNEL_STATUS_OK; | ||
| 320 | } | 302 | } |
| 321 | 303 | ||
| 322 | -KernelStatus Selectv2CpuKernel::SelectV2BcastCheck(const int64_t x, | 304 | +KernelStatus Selectv2CpuKernel::SelectV2BcastCheck(const int64_t x, const int64_t y, const int64_t z) const |
| 323 | - const int64_t y, | 305 | +{ |
| 324 | - const int64_t z) const { | 306 | + std::unordered_set<int64_t> set_tmp{x, y, z}; |
| 325 | - std::unordered_set<int64_t> set_tmp{x, y, z}; | 307 | + if (set_tmp.size() != kNoRepeatElements) { |
| 326 | - if (set_tmp.size() != kNoRepeatElements) { | 308 | + return KERNEL_STATUS_PARAM_INVALID; |
| 327 | - return KERNEL_STATUS_PARAM_INVALID; | 309 | + } |
| 328 | - } | 310 | + if (x != 1 && y != 1 && z != 1) { |
| 329 | - if (x != 1 && y != 1 && z != 1) { | 311 | + return KERNEL_STATUS_PARAM_INVALID; |
| 330 | - return KERNEL_STATUS_PARAM_INVALID; | 312 | + } |
| 331 | - } | 313 | + return KERNEL_STATUS_OK; |
| 332 | - return KERNEL_STATUS_OK; | ||
| 333 | } | 314 | } |
| 334 | 315 | ||
| 335 | -void Selectv2CpuKernel::SelectV2GetBcastVec(SelectV2BCalcInfo& calc_info) const { | 316 | +void Selectv2CpuKernel::SelectV2GetBcastVec(SelectV2BCalcInfo& calc_info) const |
| 336 | - calc_info.reshape_0 = std::move(x_reshape_); | 317 | +{ |
| 337 | - calc_info.reshape_1 = std::move(y_reshape_); | 318 | + calc_info.reshape_0 = std::move(x_reshape_); |
| 338 | - calc_info.reshape_2 = std::move(z_reshape_); | 319 | + calc_info.reshape_1 = std::move(y_reshape_); |
| 339 | - calc_info.shape_out = std::move(shape_out_); | 320 | + calc_info.reshape_2 = std::move(z_reshape_); |
| 340 | - calc_info.bcast_0 = std::move(x_bcast_); | 321 | + calc_info.shape_out = std::move(shape_out_); |
| 341 | - calc_info.bcast_1 = std::move(y_bcast_); | 322 | + calc_info.bcast_0 = std::move(x_bcast_); |
| 342 | - calc_info.bcast_2 = std::move(z_bcast_); | 323 | + calc_info.bcast_1 = std::move(y_bcast_); |
| 324 | + calc_info.bcast_2 = std::move(z_bcast_); | ||
| 343 | } | 325 | } |
| 344 | -REGISTER_CPU_KERNEL(kSelectV2, Selectv2CpuKernel); | 326 | +OPS_MATH_REGISTER_CPU_KERNELV2(kSelectV2, Selectv2CpuKernel); |
| 345 | -} // namespace aicpu | 327 | +} // namespace aicpu |
| @@ -0,0 +1,36 @@ | |||
| 1 | +/** | ||
| 2 | + * Copyright (c) 2026 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 | +namespace ops { | ||
| 15 | +class SelectV2 : public OpDef { | ||
| 16 | +public: | ||
| 17 | + explicit SelectV2(const char* name) : OpDef(name) | ||
| 18 | + { | ||
| 19 | + this->Input("condition").DataType({ge::DT_BOOL}); | ||
| 20 | + this->Input("then").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT, ge::DT_FLOAT16, | ||
| 21 | + ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8, ge::DT_UINT16, | ||
| 22 | + ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL}); | ||
| 23 | + this->Input("else").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT, ge::DT_FLOAT16, | ||
| 24 | + ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8, ge::DT_UINT16, | ||
| 25 | + ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL}); | ||
| 26 | + this->Output("result").DataType({ge::DT_COMPLEX128, ge::DT_COMPLEX64, ge::DT_DOUBLE, ge::DT_FLOAT, | ||
| 27 | + ge::DT_FLOAT16, ge::DT_INT16, ge::DT_INT32, ge::DT_INT64, ge::DT_INT8, | ||
| 28 | + ge::DT_UINT16, ge::DT_UINT32, ge::DT_UINT64, ge::DT_UINT8, ge::DT_BOOL}); | ||
| 29 | + | ||
| 30 | + ApplyMathAicpuDefaultCfg(*this); | ||
| 31 | + this->AICPU().ExtendCfgInfo(OP_INFO_OPS_FLAG.c_str(), OPEN_OPS_FLAG.c_str()); | ||
| 32 | + } | ||
| 33 | +}; | ||
| 34 | + | ||
| 35 | +OP_ADD(SelectV2); | ||
| 36 | +} // namespace ops | ||
| @@ -12,4 +12,4 @@ | |||
| 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") | 12 | set(SUPPORT_COMPUTE_UNIT "ascend950" "mc62") |
| 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") | 14 | set(SUPPORT_TILING_DIR "arch35" "arch35") |
| 15 | -add_all_modules_sources(OPTYPE square ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | 15 | +add_all_modules_sources(OPTYPE square ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE) |
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | + | ||
| 15 | 16 | ||
| 16 | 17 | ||
| 17 | 18 | ||
| @@ -40,9 +41,9 @@ const char* const kSquare{"Square"}; | |||
| 40 | namespace aicpu { | 41 | namespace aicpu { |
| 41 | namespace detail { | 42 | namespace detail { |
| 42 | template <typename T> | 43 | template <typename T> |
| 43 | -typename std::enable_if< | 44 | +typename std::enable_if<std::is_same<T, std::complex<std::float_t>>::value || |
| 44 | - std::is_same<T, std::complex<std::float_t>>::value || std::is_same<T, std::complex<std::double_t>>::value, | 45 | + std::is_same<T, std::complex<std::double_t>>::value, |
| 45 | - void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) | 46 | + void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) |
| 46 | { | 47 | { |
| 47 | T* inner_input = input + begin; | 48 | T* inner_input = input + begin; |
| 48 | T* inner_output = output + begin; | 49 | T* inner_output = output + begin; |
| @@ -56,8 +57,8 @@ typename std::enable_if< | |||
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | template <typename T> | 59 | template <typename T> |
| 59 | -typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, double_t>::value, void>:: | 60 | +typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, double_t>::value, |
| 60 | - type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) | 61 | + void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) |
| 61 | { | 62 | { |
| 62 | int64_t length = end - begin; | 63 | int64_t length = end - begin; |
| 63 | Eigen::TensorMap<Eigen::Tensor<T, 1>, Eigen::Aligned> tensor_x(input + begin, length); | 64 | Eigen::TensorMap<Eigen::Tensor<T, 1>, Eigen::Aligned> tensor_x(input + begin, length); |
| @@ -66,9 +67,9 @@ typename std::enable_if<std::is_same<T, int32_t>::value || std::is_same<T, doubl | |||
| 66 | } | 67 | } |
| 67 | 68 | ||
| 68 | template <typename T> | 69 | template <typename T> |
| 69 | -typename std::enable_if< | 70 | +typename std::enable_if<std::is_same<T, int64_t>::value || std::is_same<T, float_t>::value || |
| 70 | - std::is_same<T, int64_t>::value || std::is_same<T, float_t>::value || std::is_same<T, Eigen::half>::value, | 71 | + std::is_same<T, Eigen::half>::value, |
| 71 | - void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) | 72 | + void>::type inline ComputeKernel(T* input, T* output, int64_t begin, int64_t end) |
| 72 | { | 73 | { |
| 73 | T* inner_input = input + begin; | 74 | T* inner_input = input + begin; |
| 74 | T* inner_output = output + begin; | 75 | T* inner_output = output + begin; |
| @@ -124,9 +125,8 @@ inline std::uint32_t ComputeSquare(const CpuKernelContext& ctx, const int64_t pa | |||
| 124 | inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx) | 125 | inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx) |
| 125 | { | 126 | { |
| 126 | if (ctx.Input(0)->GetDataType() != ctx.Output(0)->GetDataType()) { | 127 | if (ctx.Input(0)->GetDataType() != ctx.Output(0)->GetDataType()) { |
| 127 | - KERNEL_LOG_ERROR( | 128 | + KERNEL_LOG_ERROR("The data type of the input [%s] need be the same as the ouput [%s].", |
| 128 | - "The data type of the input [%s] need be the same as the ouput [%s].", | 129 | + DTypeStr(ctx.Input(0)->GetDataType()).c_str(), DTypeStr(ctx.Output(0)->GetDataType()).c_str()); |
| 129 | - DTypeStr(ctx.Input(0)->GetDataType()).c_str(), DTypeStr(ctx.Output(0)->GetDataType()).c_str()); | ||
| 130 | return KERNEL_STATUS_PARAM_INVALID; | 130 | return KERNEL_STATUS_PARAM_INVALID; |
| 131 | } | 131 | } |
| 132 | KERNEL_CHECK_NULLPTR(ctx.Input(0)->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get input data failed.") | 132 | KERNEL_CHECK_NULLPTR(ctx.Input(0)->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get input data failed.") |
| @@ -134,18 +134,16 @@ inline std::uint32_t SquareExtraCheck(const CpuKernelContext& ctx) | |||
| 134 | std::vector<int64_t> input_dims = ctx.Input(0)->GetTensorShape()->GetDimSizes(); | 134 | std::vector<int64_t> input_dims = ctx.Input(0)->GetTensorShape()->GetDimSizes(); |
| 135 | std::vector<int64_t> output_dims = ctx.Output(0)->GetTensorShape()->GetDimSizes(); | 135 | std::vector<int64_t> output_dims = ctx.Output(0)->GetTensorShape()->GetDimSizes(); |
| 136 | if (input_dims.size() != output_dims.size()) { | 136 | if (input_dims.size() != output_dims.size()) { |
| 137 | - KERNEL_LOG_ERROR( | 137 | + KERNEL_LOG_ERROR("The data dim of the input size [%lu] need be the same as the output " |
| 138 | - "The data dim of the input size [%lu] need be the same as the output " | 138 | + "size [%lu].", |
| 139 | - "size [%lu].", | 139 | + input_dims.size(), output_dims.size()); |
| 140 | - input_dims.size(), output_dims.size()); | ||
| 141 | return KERNEL_STATUS_PARAM_INVALID; | 140 | return KERNEL_STATUS_PARAM_INVALID; |
| 142 | } | 141 | } |
| 143 | for (size_t index = 0; index < input_dims.size(); index++) { | 142 | for (size_t index = 0; index < input_dims.size(); index++) { |
| 144 | if (input_dims[index] != output_dims[index]) { | 143 | if (input_dims[index] != output_dims[index]) { |
| 145 | - KERNEL_LOG_ERROR( | 144 | + KERNEL_LOG_ERROR("The data dim[%lu]=%ld of the input need be the same as the output " |
| 146 | - "The data dim[%lu]=%ld of the input need be the same as the output " | 145 | + "dim[%lu]=%ld.", |
| 147 | - "dim[%lu]=%ld.", | 146 | + index, input_dims[index], index, output_dims[index]); |
| 148 | - index, input_dims[index], index, output_dims[index]); | ||
| 149 | return KERNEL_STATUS_PARAM_INVALID; | 147 | return KERNEL_STATUS_PARAM_INVALID; |
| 150 | } | 148 | } |
| 151 | } | 149 | } |
| @@ -187,5 +185,5 @@ std::uint32_t SquareCpuKernel::Compute(CpuKernelContext& ctx) | |||
| 187 | return detail::SquareCheck(ctx) ? KERNEL_STATUS_PARAM_INVALID : detail::SquareCompute(ctx); | 185 | return detail::SquareCheck(ctx) ? KERNEL_STATUS_PARAM_INVALID : detail::SquareCompute(ctx); |
| 188 | } | 186 | } |
| 189 | 187 | ||
| 190 | -REGISTER_CPU_KERNEL(kSquare, SquareCpuKernel); | 188 | +OPS_MATH_REGISTER_CPU_KERNELV2(kSquare, SquareCpuKernel); |
| 191 | } // namespace aicpu | 189 | } // namespace aicpu |
| @@ -12,4 +12,4 @@ | |||
| 12 | set(SUPPORT_COMPUTE_UNIT "ascend950") | 12 | set(SUPPORT_COMPUTE_UNIT "ascend950") |
| 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 | 13 | # 设置每种芯片类型对应的tiling文件目录,即采用op_host目录下哪个文件夹下的tiling文件编译 |
| 14 | set(SUPPORT_TILING_DIR "arch35") | 14 | set(SUPPORT_TILING_DIR "arch35") |
| 15 | -add_all_modules_sources(OPTYPE squared_difference ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE) | 15 | +add_all_modules_sources(OPTYPE squared_difference ACLNNTYPE aclnn_exclude COMPUTE_UNIT ${SUPPORT_COMPUTE_UNIT} TILING_DIR ${SUPPORT_TILING_DIR} DISABLE_IN_OPP TRUE HOSTCPU TRUE) |
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | + | ||
| 12 | 13 | ||
| 13 | 14 | ||
| 14 | 15 | ||
| @@ -37,8 +38,8 @@ const int64_t kParallelDataNumSameShapeMid = 35 * 1024; | |||
| 37 | namespace aicpu { | 38 | namespace aicpu { |
| 38 | uint32_t SquaredDifferenceCpuKernel::Compute(CpuKernelContext& ctx) | 39 | uint32_t SquaredDifferenceCpuKernel::Compute(CpuKernelContext& ctx) |
| 39 | { | 40 | { |
| 40 | - KERNEL_HANDLE_ERROR( | 41 | + KERNEL_HANDLE_ERROR(NormalCheck(ctx, kInputNum, kOutputNum), |
| 41 | - NormalCheck(ctx, kInputNum, kOutputNum), "SquaredDifference check input and output number failed."); | 42 | + "SquaredDifference check input and output number failed."); |
| 42 | KERNEL_HANDLE_ERROR(SquaredDifferenceCheck(ctx), "SquaredDifference check params failed."); | 43 | KERNEL_HANDLE_ERROR(SquaredDifferenceCheck(ctx), "SquaredDifference check params failed."); |
| 43 | DataType data_type = ctx.Input(0)->GetDataType(); | 44 | DataType data_type = ctx.Input(0)->GetDataType(); |
| 44 | switch (data_type) { | 45 | switch (data_type) { |
| @@ -85,15 +86,13 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCheck(const CpuKernelConte | |||
| 85 | KERNEL_CHECK_NULLPTR(output->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get output data failed") | 86 | KERNEL_CHECK_NULLPTR(output->GetData(), KERNEL_STATUS_PARAM_INVALID, "Get output data failed") |
| 86 | DataType input0_type = input_0->GetDataType(); | 87 | DataType input0_type = input_0->GetDataType(); |
| 87 | DataType input1_type = input_1->GetDataType(); | 88 | DataType input1_type = input_1->GetDataType(); |
| 88 | - KERNEL_CHECK_FALSE( | 89 | + KERNEL_CHECK_FALSE((input0_type == input1_type), KERNEL_STATUS_PARAM_INVALID, |
| 89 | - (input0_type == input1_type), KERNEL_STATUS_PARAM_INVALID, | 90 | + "The data type of input0 [%s] need be same with " |
| 90 | - "The data type of input0 [%s] need be same with " | 91 | + "input1 [%s].", |
| 91 | - "input1 [%s].", | 92 | + DTypeStr(input0_type).c_str(), DTypeStr(input1_type).c_str()) |
| 92 | - DTypeStr(input0_type).c_str(), DTypeStr(input1_type).c_str()) | 93 | + KERNEL_LOG_DEBUG("SquaredDifferenceCpuKernel[%s], input0: size[%lu];" |
| 93 | - KERNEL_LOG_DEBUG( | 94 | + "input1: size[%lu], output: size[%lu].", |
| 94 | - "SquaredDifferenceCpuKernel[%s], input0: size[%lu];" | 95 | + ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), output->GetDataSize()); |
| 95 | - "input1: size[%lu], output: size[%lu].", | ||
| 96 | - ctx.GetOpType().c_str(), input_0->GetDataSize(), input_1->GetDataSize(), output->GetDataSize()); | ||
| 97 | 96 | ||
| 98 | return KERNEL_STATUS_OK; | 97 | return KERNEL_STATUS_OK; |
| 99 | } | 98 | } |
| @@ -104,8 +103,8 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCheck(const CpuKernelConte | |||
| 104 | // 3. input2 is a 1D tensor with only one element or input2 is scalar | 103 | // 3. input2 is a 1D tensor with only one element or input2 is scalar |
| 105 | // 4. the shapes of input1 and input2 are different | 104 | // 4. the shapes of input1 and input2 are different |
| 106 | template <typename T> | 105 | template <typename T> |
| 107 | -void SquaredDifferenceCpuKernel::SpecialCompute( | 106 | +void SquaredDifferenceCpuKernel::SpecialCompute(BcastShapeType type, int64_t start, int64_t end, const T* input1, |
| 108 | - BcastShapeType type, int64_t start, int64_t end, const T* input1, const T* input2, T* output) | 107 | + const T* input2, T* output) |
| 109 | { | 108 | { |
| 110 | switch (type) { | 109 | switch (type) { |
| 111 | case BcastShapeType::SAME_SHAPE: | 110 | case BcastShapeType::SAME_SHAPE: |
| @@ -228,8 +227,8 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCompute(const CpuKernelCon | |||
| 228 | auto input1_shape = input1_tensor->GetTensorShape()->GetDimSizes(); | 227 | auto input1_shape = input1_tensor->GetTensorShape()->GetDimSizes(); |
| 229 | int64_t input1_elements_nums = input1_tensor->NumElements(); | 228 | int64_t input1_elements_nums = input1_tensor->NumElements(); |
| 230 | 229 | ||
| 231 | - bool is_no_need_bcast = | 230 | + bool is_no_need_bcast = (input0_shape == input1_shape) || (input0_elements_nums == 1) || |
| 232 | - (input0_shape == input1_shape) || (input0_elements_nums == 1) || (input1_elements_nums == 1); | 231 | + (input1_elements_nums == 1); |
| 233 | if (is_no_need_bcast) { | 232 | if (is_no_need_bcast) { |
| 234 | return NoBcastCompute<T>(ctx); | 233 | return NoBcastCompute<T>(ctx); |
| 235 | } else { | 234 | } else { |
| @@ -243,5 +242,5 @@ uint32_t SquaredDifferenceCpuKernel::SquaredDifferenceCompute(const CpuKernelCon | |||
| 243 | } | 242 | } |
| 244 | } | 243 | } |
| 245 | 244 | ||
| 246 | -REGISTER_CPU_KERNEL(kSquaredDifference, SquaredDifferenceCpuKernel); | 245 | +OPS_MATH_REGISTER_CPU_KERNELV2(kSquaredDifference, SquaredDifferenceCpuKernel); |
| 247 | -} // namespace aicpu | 246 | +} // namespace aicpu |