// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "lite/backends/xpu/builder.h" #include "lite/kernels/xpu/bridges/registry.h" namespace paddle { namespace lite { namespace kernels { namespace xpu { namespace bridges { node_map_type MulConverter(const std::shared_ptr op, graph_ctx_type* graph_ctx, const node_map_type& input_nodes) { auto scope = op->scope(); auto op_info = op->op_info(); auto op_type = op_info->Type(); auto unique_op_type = lite::xpu::UniqueName(op_type); LOG(INFO) << "[XPU] Converting " + op_type + "..."; // check context CHECK(graph_ctx != nullptr); CHECK(graph_ctx->builder != nullptr); CHECK(graph_ctx->params != nullptr); // get input, and attributes auto x_var_name = op_info->Input("X").front(); auto y_var_name = op_info->Input("Y").front(); auto y_tensor = scope->FindMutableTensor(y_var_name); auto y_dims = y_tensor->dims(); CHECK_EQ(y_dims.size(), 2) << "xpu now only support y_dims.size() == 2"; auto x_num_col_dims = op_info->GetAttr("x_num_col_dims"); CHECK_EQ(x_num_col_dims, 1) << "xpu now only support x_num_col_dims == 1"; auto y_num_col_dims = op_info->GetAttr("x_num_col_dims"); CHECK_EQ(y_num_col_dims, 1) << "xpu now only support y_num_col_dims == 1"; // create x node std::shared_ptr x_node = nullptr; x_node = std::make_shared( graph_ctx->builder->CreateBatchFlatten(*input_nodes.at(x_var_name))); graph_ctx->builder->SetLayer(unique_op_type + "/X"); // transpose y DDimLite y_dims_t(std::vector{1, 1}); y_dims_t[0] = y_dims[1]; y_dims_t[1] = y_dims[0]; auto y_var_name_t = unique_op_type + "/Y"; Tensor* y_tensor_t = new Tensor(); y_tensor_t->Resize(y_dims_t); auto y_data_t = y_tensor_t->mutable_data(); auto y_data = y_tensor->mutable_data(); for (int i = 0; i < y_dims_t[0]; i++) { for (int j = 0; j < y_dims_t[1]; j++) { y_data_t[i * y_dims_t[1] + j] = y_data[j * y_dims_t[0] + i]; } } // create y node std::shared_ptr y_const_node = nullptr; y_const_node = std::make_shared(graph_ctx->builder->CreateTensor( y_var_name_t, lite::xpu::CvtShape(y_dims_t), ::xtcl::Float(32))); auto y_const_tensor = lite::xpu::CvtTensor(y_tensor_t); graph_ctx->params->emplace(std::make_pair(y_var_name_t, *y_const_tensor)); delete y_tensor_t; // create mul node and set params from op std::shared_ptr mul_node = nullptr; mul_node = std::make_shared( graph_ctx->builder->CreateDense(*x_node, static_cast(y_dims[1]), ::xtcl::NullValue<::xtcl::DataType>(), *y_const_node)); graph_ctx->builder->SetLayer(unique_op_type); // output converted nodes node_map_type output_nodes; output_nodes[op_info->Output("Out").front()] = mul_node; return output_nodes; } } // namespace bridges } // namespace xpu } // namespace kernels } // namespace lite } // namespace paddle REGISTER_XPU_BRIDGE(mul, paddle::lite::kernels::xpu::bridges::MulConverter);