| 217 | } |
| 218 | |
| 219 | void exec_binary( |
| 220 | HandleImpl* handle, const TensorND& lhs, const TensorND& rhs, |
| 221 | _megdnn_tensor_out dst, const param::Elemwise::Mode& mode, |
| 222 | const WorkspaceBundle& wk_bundle) { |
| 223 | auto cnnl_handler = handle->cnnl_handle(); |
| 224 | auto dtype_dest = dst.layout.dtype.enumv(); |
| 225 | CnnlTensorDescriptor lhs_desc, rhs_desc, output_desc; |
| 226 | lhs_desc.set(lhs.layout); |
| 227 | rhs_desc.set(rhs.layout); |
| 228 | output_desc.set(dst.layout); |
| 229 | |
| 230 | Workspace cnnl_wk = wk_bundle.get_workspace(0); |
| 231 | Workspace lhs_contig_wk, rhs_contig_wk; |
| 232 | lhs_contig_wk = wk_bundle.get_workspace(1); |
| 233 | rhs_contig_wk = wk_bundle.get_workspace(2); |
| 234 | void *lhs_ptr, *rhs_ptr; |
| 235 | CnnlTensorDescriptor lhs_contig_desc, rhs_contig_desc; |
| 236 | auto contiguous_src = [&]() { |
| 237 | lhs_ptr = to_contiguous( |
| 238 | cnnl_handler, lhs, lhs_desc, lhs_contig_desc, lhs_contig_wk); |
| 239 | rhs_ptr = to_contiguous( |
| 240 | cnnl_handler, rhs, rhs_desc, rhs_contig_desc, rhs_contig_wk); |
| 241 | }; |
| 242 | switch (mode) { |
| 243 | case Mode::ADD: { // float, half, int32 |
| 244 | megdnn_assert( |
| 245 | check_dtype_float_ieee(dtype_dest) || |
| 246 | dtype_dest == megdnn::DTypeEnum::Int32, |
| 247 | "Cambricon unsupport elemwise mode:%d with dtype:%d", |
| 248 | static_cast<int>(mode), static_cast<int>(dtype_dest)); |
| 249 | contiguous_src(); |
| 250 | if (dtype_dest == megdnn::DTypeEnum::Int32) { |
| 251 | opTensorRun<int32_t>( |
| 252 | cnnl_handler, cnnlOpTensorDesc_t::CNNL_OP_TENSOR_ADD, |
| 253 | lhs_contig_desc, lhs_ptr, rhs_contig_desc, rhs_ptr, output_desc, |
| 254 | dst.raw_ptr(), dst.layout.dtype.enumv(), cnnl_wk); |
| 255 | } else { |
| 256 | opTensorRun<float>( |
| 257 | cnnl_handler, cnnlOpTensorDesc_t::CNNL_OP_TENSOR_ADD, |
| 258 | lhs_contig_desc, lhs_ptr, rhs_contig_desc, rhs_ptr, output_desc, |
| 259 | dst.raw_ptr(), dst.layout.dtype.enumv(), cnnl_wk); |
| 260 | } |
| 261 | break; |
| 262 | } |
| 263 | case Mode::MUL: { // float, half, int32 |
| 264 | megdnn_assert( |
| 265 | check_dtype_float_ieee(dtype_dest) || |
| 266 | dtype_dest == megdnn::DTypeEnum::Int32, |
| 267 | "Cambricon unsupport elemwise mode:%d with dtype:%d", |
| 268 | static_cast<int>(mode), static_cast<int>(dtype_dest)); |
| 269 | contiguous_src(); |
| 270 | if (dtype_dest == megdnn::DTypeEnum::Int32) { |
| 271 | opTensorRun<int32_t>( |
| 272 | cnnl_handler, cnnlOpTensorDesc_t::CNNL_OP_TENSOR_MUL, |
| 273 | lhs_contig_desc, lhs_ptr, rhs_contig_desc, rhs_ptr, output_desc, |
| 274 | dst.raw_ptr(), dst.layout.dtype.enumv(), cnnl_wk); |
| 275 | } else { |
| 276 | opTensorRun<float>( |
no test coverage detected