diff --git a/paddle/fluid/ir/dialect/kernel_dialect.cc b/paddle/fluid/ir/dialect/kernel_dialect.cc index c5fabe07732f12239d47645d41209d829bda9b05..f3b1a6e36ab7441606fd267cc1e36f53d217c769 100644 --- a/paddle/fluid/ir/dialect/kernel_dialect.cc +++ b/paddle/fluid/ir/dialect/kernel_dialect.cc @@ -41,6 +41,7 @@ PaddleKernelDialect::PaddleKernelDialect(ir::IrContext *context) void PaddleKernelDialect::initialize() { RegisterTypes(); + RegisterTypes(); RegisterOps(); RegisterAttributes(); diff --git a/paddle/fluid/ir/dialect/kernel_type.cc b/paddle/fluid/ir/dialect/kernel_type.cc index 59009eab2b17dfbf98fd615017a950c4a77d5a84..d54b360647e70fc31062bbf92fadc1eb3f595dcd 100644 --- a/paddle/fluid/ir/dialect/kernel_type.cc +++ b/paddle/fluid/ir/dialect/kernel_type.cc @@ -41,7 +41,32 @@ const size_t& AllocatedDenseTensorType::offset() const { return storage()->dense_tensor_type_.offset(); } +const phi::Place& AllocatedSelectedRowsType::place() const { + return storage()->place_; +} + +const ir::Type& AllocatedSelectedRowsType::dtype() const { + return storage()->selected_rows_type_.dtype(); +} + +const phi::DDim& AllocatedSelectedRowsType::dims() const { + return storage()->selected_rows_type_.dims(); +} + +const phi::DataLayout& AllocatedSelectedRowsType::data_layout() const { + return storage()->selected_rows_type_.data_layout(); +} + +const phi::LoD& AllocatedSelectedRowsType::lod() const { + return storage()->selected_rows_type_.lod(); +} + +const size_t& AllocatedSelectedRowsType::offset() const { + return storage()->selected_rows_type_.offset(); +} + } // namespace dialect } // namespace paddle IR_DEFINE_EXPLICIT_TYPE_ID(paddle::dialect::AllocatedDenseTensorType) +IR_DEFINE_EXPLICIT_TYPE_ID(paddle::dialect::AllocatedSelectedRowsType) diff --git a/paddle/fluid/ir/dialect/kernel_type.h b/paddle/fluid/ir/dialect/kernel_type.h index 3bbae7f7f24683d40e5edc936b63b90670fcaae3..9d2d4061c7e6ff2d070245182b8a1f1c183789d0 100644 --- a/paddle/fluid/ir/dialect/kernel_type.h +++ b/paddle/fluid/ir/dialect/kernel_type.h @@ -20,9 +20,7 @@ namespace paddle { namespace dialect { -/// -/// \brief Define built-in parametric types. -/// + class AllocatedDenseTensorType : public ir::Type { public: using Type::Type; @@ -64,7 +62,49 @@ class AllocatedDenseTensorType : public ir::Type { const size_t &offset() const; }; +class AllocatedSelectedRowsType : public ir::Type { + public: + using Type::Type; + + DECLARE_TYPE_UTILITY_FUNCTOR(AllocatedSelectedRowsType, + AllocatedSelectedRowsTypeStorage); + + static AllocatedSelectedRowsType get(ir::IrContext *ctx, + const phi::Place &place, + dialect::SelectedRowsType type) { + return ir::TypeManager::template get( + ctx, place, type); + } + + static AllocatedSelectedRowsType get(ir::IrContext *ctx, + const phi::Place &place, + const ir::Type &dtype, + const phi::DDim &dims, + const phi::DataLayout &layout, + const phi::LoD &lod, + size_t offset) { + dialect::SelectedRowsType dense_tensor_type = + dialect::SelectedRowsType::get(ctx, dtype, dims, layout, lod, offset); + + return ir::TypeManager::template get( + ctx, place, dense_tensor_type); + } + + const phi::Place &place() const; + + const ir::Type &dtype() const; + + const phi::DDim &dims() const; + + const phi::DataLayout &data_layout() const; + + const phi::LoD &lod() const; + + const size_t &offset() const; +}; + } // namespace dialect } // namespace paddle IR_DECLARE_EXPLICIT_TYPE_ID(paddle::dialect::AllocatedDenseTensorType) +IR_DECLARE_EXPLICIT_TYPE_ID(paddle::dialect::AllocatedSelectedRowsType) diff --git a/paddle/fluid/ir/dialect/kernel_type_storage.h b/paddle/fluid/ir/dialect/kernel_type_storage.h index 2dcdc598426f6d1525f3d50f1b49c0951a561d90..59070f75f939206c7e61f0257c4027373ad397ac 100644 --- a/paddle/fluid/ir/dialect/kernel_type_storage.h +++ b/paddle/fluid/ir/dialect/kernel_type_storage.h @@ -88,5 +88,67 @@ struct AllocatedDenseTensorTypeStorage : public ir::TypeStorage { dialect::DenseTensorType dense_tensor_type_; }; +/// +/// \brief Define Parametric TypeStorage for AllocatedSelectedRowsTypeStorage. +/// +/// +struct AllocatedSelectedRowsTypeStorage : public ir::TypeStorage { + using Place = phi::Place; + /// + /// \brief Declare ParamKey according to parameter type. + /// + using ParamKey = std::tuple; + + AllocatedSelectedRowsTypeStorage(const phi::Place& place, + const dialect::SelectedRowsType& type) + : place_(place), selected_rows_type_(type) {} + + /// + /// \brief Each derived TypeStorage must define a Construct method, which + /// StorageManager uses to construct a derived TypeStorage. + /// + static AllocatedSelectedRowsTypeStorage* Construct(const ParamKey& key) { + return new AllocatedSelectedRowsTypeStorage(std::get<0>(key), + std::get<1>(key)); + } + + /// + /// \brief Each derived TypeStorage must provide a HashValue method. + /// + static std::size_t HashValue(const ParamKey& key) { + std::size_t hash_value = 791; + // hash place + hash_value = ir::hash_combine(hash_value, std::get<0>(key).HashValue()); + + // hash dtype + auto selected_rows_type = std::get<1>(key); + hash_value = ir::hash_combine(hash_value, + dialect::DenseTensorTypeStorage::HashValue( + dialect::DenseTensorTypeStorage::ParamKey( + selected_rows_type.dtype(), + selected_rows_type.dims(), + selected_rows_type.data_layout(), + selected_rows_type.lod(), + selected_rows_type.offset()))); + return hash_value; + } + + /// + /// \brief Each derived TypeStorage needs to overload operator==. + /// + bool operator==(const ParamKey& key) const { + return ParamKey(place_, selected_rows_type_) == key; + } + + ParamKey GetAsKey() const { return ParamKey(place_, selected_rows_type_); } + + /// + /// \brief AllocatedSelectedRowsTypeStorage include five parameters: place, + /// SelectedRowsType + /// + phi::Place place_; + dialect::SelectedRowsType selected_rows_type_; +}; + } // namespace dialect } // namespace paddle diff --git a/paddle/fluid/ir/dialect/pd_dialect.cc b/paddle/fluid/ir/dialect/pd_dialect.cc index bc78e6ac5a4439852f665d432009f6a1e6f859b6..33869a7fc3d42a01b0943fa9e3a93f2fa12ea57b 100644 --- a/paddle/fluid/ir/dialect/pd_dialect.cc +++ b/paddle/fluid/ir/dialect/pd_dialect.cc @@ -111,15 +111,23 @@ void PaddleDialect::initialize() { } void PaddleDialect::PrintType(ir::Type type, std::ostream &os) const { - DenseTensorType tensor_type = type.dyn_cast(); - - os << "tensor<"; - for (auto d : phi::vectorize(tensor_type.dims())) { - os << d; - os << "x"; + if (auto tensor_type = type.dyn_cast()) { + os << "tensor<"; + for (auto d : phi::vectorize(tensor_type.dims())) { + os << d; + os << "x"; + } + tensor_type.dtype().Print(os); + os << ">"; + } else if (auto selected_rows_type = type.dyn_cast()) { + os << "selectedrows<"; + for (auto d : phi::vectorize(selected_rows_type.dims())) { + os << d; + os << "x"; + } + selected_rows_type.dtype().Print(os); + os << ">"; } - tensor_type.dtype().Print(os); - os << ">"; } void PaddleDialect::PrintAttribute(ir::Attribute attr, std::ostream &os) const { diff --git a/paddle/fluid/ir/dialect/pd_op.yaml b/paddle/fluid/ir/dialect/pd_op.yaml index 1242a3634963c6c3fb78951ede668d015a410c27..8160a636ddcb6a40898085e202122945ff9c1bf6 100644 --- a/paddle/fluid/ir/dialect/pd_op.yaml +++ b/paddle/fluid/ir/dialect/pd_op.yaml @@ -187,10 +187,10 @@ no_need_buffer: null data_transform: null infer_meta: - func: UnchangedInferMeta + func: EmbeddingGradSparseInferMeta param: [weight] kernel: - func: [embedding_grad_sparse] + func: [embedding_sparse_grad] param: [x, weight, out_grad, padding_idx, sparse] backend: null layout: null @@ -198,7 +198,7 @@ ordered: false candidates: [weight] to_complex_flag: [false] - dispatch: {embedding_grad_sparse: null} + dispatch: {embedding_sparse_grad: null} force_backend: null inplace: null view: null diff --git a/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.cc b/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.cc index 9a7da7aa831c15ce884380b27dde94f5f795574d..d5b31b9a04b623b5e3cd42eba0d8e97623d025f7 100644 --- a/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.cc +++ b/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.cc @@ -104,6 +104,8 @@ void BuildValue(ir::Value value, var->GetMutable(); } else if (value.type().isa()) { var->GetMutable(); + } else if (value.type().isa()) { + var->GetMutable(); } else if (value.type().isa()) { auto tensor_array = var->GetMutable(); for (size_t i = 0; i < value.type().dyn_cast().size(); diff --git a/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.h b/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.h index 77dbb98daa3f9faf1e3879c83f667620518f64b1..917c7270217f205924a8af66f329652ae6da41f1 100644 --- a/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.h +++ b/paddle/fluid/ir/phi_kernel_adaptor/phi_kernel_util.h @@ -258,6 +258,23 @@ void BuildPhiContext( } else if (attr_type_name == "ir::ArrayAttribute") { auto array_list = attr_map[t].dyn_cast().data(); + std::vector vec_res; + if (array_list.size() > 0) { + PADDLE_ENFORCE_EQ( + array_list[0].isa(), + true, + phi::errors::PreconditionNotMet( + "Element in array list MUST be ir::Int64Attribute ")); + + for (size_t i = 0; i < array_list.size(); ++i) { + vec_res.push_back( + array_list[i].dyn_cast().data()); + } + } + ctx->EmplaceBackAttr(vec_res); + } else if (attr_type_name == "ir::ArrayAttribute") { + auto array_list = attr_map[t].dyn_cast().data(); + std::vector vec_res; if (array_list.size() > 0) { PADDLE_ENFORCE_EQ( @@ -300,13 +317,19 @@ void BuildPhiContext( for (size_t i = 0; i < op->num_results(); ++i) { ir::Value out_ptr = op->result(i); auto name = name_map.at(out_ptr); - if (out_ptr.type()) { - ctx->EmplaceBackOutput(OutType(const_cast( - &(inner_scope->FindVar(name)->Get())))); - } else { + auto out_type = out_ptr.type(); + if (!out_type) { phi::DenseTensor* ptr = nullptr; OutType out_ptr(ptr); ctx->EmplaceBackOutput(out_ptr); + } else if (out_type.isa()) { + ctx->EmplaceBackOutput(OutType(const_cast( + &(scope->Var(name)->Get())))); + } else if (out_type.isa()) { + ctx->EmplaceBackOutput(OutType(const_cast( + &(scope->Var(name)->Get())))); + } else { + PADDLE_THROW("not support type"); } if (output_map != nullptr) { diff --git a/paddle/fluid/ir/transforms/pd_op_to_kernel_pass.cc b/paddle/fluid/ir/transforms/pd_op_to_kernel_pass.cc index 17ed6dd381c0649bc8ad261ca1a0e5f9ebdc3946..2e008217796288edaae597fe03b29be12285167d 100644 --- a/paddle/fluid/ir/transforms/pd_op_to_kernel_pass.cc +++ b/paddle/fluid/ir/transforms/pd_op_to_kernel_pass.cc @@ -252,6 +252,13 @@ std::unique_ptr PdOpLowerToKernelPass(ir::Program* prog) { ir::Type t1 = ir::VectorType::get(ctx, vec_inner_types); op_output_types.push_back(t1); + } else if (result_type.isa()) { + auto allocated_selected_rows_dtype = + paddle::dialect::AllocatedSelectedRowsType::get( + ctx, + phi::TransToPhiPlace(kernel_key.backend()), + result_type.dyn_cast()); + op_output_types.push_back(allocated_selected_rows_dtype); } else { PADDLE_THROW(phi::errors::Unimplemented( "Result type only support DenseTensorType and VectorType")); @@ -322,6 +329,8 @@ std::unique_ptr PdOpLowerToKernelPass(ir::Program* prog) { } } else if (new_in_type.isa()) { // [ todo need update here, support combine data transfomer] + } else if (new_in_type.isa()) { + // do nothing here } else { PADDLE_THROW(phi::errors::Unimplemented( "only support allocated dense tensor type for now")); diff --git a/paddle/fluid/ir_adaptor/translator/op_translator.cc b/paddle/fluid/ir_adaptor/translator/op_translator.cc index 4b3a242394cbd38748b067e10088aee2c88a8e51..03a94a14d72662d29c7dbc5b499dc5a46cc2eb00 100644 --- a/paddle/fluid/ir_adaptor/translator/op_translator.cc +++ b/paddle/fluid/ir_adaptor/translator/op_translator.cc @@ -894,6 +894,41 @@ struct RnnOpTranscriber : public OpTranscriber { }; }; +struct EmbeddingGradOpTranscriber : public OpTranscriber { + void HandleNonexistentAttribute(ir::IrContext* ctx, + ir::AttributeMap* attribute_map, + const OpAttributeInfo& info) override { + if (info.name == "padding_idx") { + (*attribute_map)[info.name] = ir::Int64Attribute::get(ctx, -1); + } else if (info.name == "sparse") { + (*attribute_map)[info.name] = ir::BoolAttribute::get(ctx, false); + } + } + + ir::OpInfo LoopkUpOpInfo(ir::IrContext* ctx, const OpDesc& op_desc) override { + std::string target_op_name = + kTargetDialectPrefix + OpNameCompatibleMapping(op_desc.Type()); + + bool is_sparse = paddle::get(op_desc.GetAttr("is_sparse")); + + if (is_sparse) { + target_op_name = "pd.embedding_grad_sparse"; + } else { + target_op_name = "pd.embedding_grad_dense"; + } + VLOG(6) << "[op name normalizing: " << op_desc.Type() << " to " + << target_op_name; + auto op_info = ctx->GetRegisteredOpInfo(target_op_name); + if (!op_info) { + IR_THROW("Op %d should have corresponding OpInfo %d", + op_desc.Type(), + target_op_name); + } + + return op_info; + } +}; + struct FeedOpTranscriber : public OpTranscriber { ir::AttributeMap TranslateOpAttribute( ir::IrContext* ctx, @@ -960,6 +995,7 @@ OpTranslator::OpTranslator() { special_handlers["fetch_v2"] = FetchOpTranscriber(); special_handlers["cast"] = CastOpTranscriber(); special_handlers["lookup_table_v2"] = EmbeddingOpTranscriber(); + special_handlers["lookup_table_v2_grad"] = EmbeddingGradOpTranscriber(); special_handlers["assign_value"] = AssignValueOpTranscriber(); special_handlers["increment"] = IncrementOpTranscriber(); special_handlers["rnn"] = RnnOpTranscriber(); diff --git a/paddle/fluid/ir_adaptor/translator/program_translator.cc b/paddle/fluid/ir_adaptor/translator/program_translator.cc index 4e9775f7e9f8335ae2709720974524041379085b..3e2d88c7a4ec9c08d87248a476b051535da4b794 100644 --- a/paddle/fluid/ir_adaptor/translator/program_translator.cc +++ b/paddle/fluid/ir_adaptor/translator/program_translator.cc @@ -59,7 +59,6 @@ void ProgramTranslator::Translate() { platform::errors::PreconditionNotMet( "Not support multi block ProgramDesc translated, now has %d blocks", legacy_program_->Size())); - for (size_t block_idx = 0; block_idx < legacy_program_->Size(); block_idx++) { const BlockDesc& block = legacy_program_->Block(block_idx); GetParameterForSingleBlock(block); diff --git a/paddle/fluid/ir_adaptor/translator/translate.cc b/paddle/fluid/ir_adaptor/translator/translate.cc index bdfc79d7bc3b576e63aef4e08254212f5f45d185..c4cc91f5a1479bd31e36262f593e4517ba60ef11 100644 --- a/paddle/fluid/ir_adaptor/translator/translate.cc +++ b/paddle/fluid/ir_adaptor/translator/translate.cc @@ -32,7 +32,6 @@ std::unique_ptr TranslateLegacyProgramToProgram( ir::IrContext* ctx = ir::IrContext::Instance(); ctx->GetOrRegisterDialect(); auto program = std::make_unique(ctx); - translator::ProgramTranslator program_translator(&legacy_program, program.get()); program_translator.Translate(); diff --git a/paddle/fluid/ir_adaptor/translator/type_translator.cc b/paddle/fluid/ir_adaptor/translator/type_translator.cc index 00f0f5976b7c96866db193834af1c9231b59d099..1b92ff2f74cc6343449ca8c7f9ea85849d29a9cc 100644 --- a/paddle/fluid/ir_adaptor/translator/type_translator.cc +++ b/paddle/fluid/ir_adaptor/translator/type_translator.cc @@ -28,6 +28,8 @@ using VarDesc = paddle::framework::VarDesc; using VarType = paddle::framework::proto::VarType; using DenseTensorType = paddle::dialect::DenseTensorType; using DenseTensorTypeStorage = paddle::dialect::DenseTensorTypeStorage; +using SelectedRowsType = paddle::dialect::SelectedRowsType; +using SelectedRowsTypeStorage = paddle::dialect::SelectedRowsTypeStorage; TypeTranslator::TypeTranslator() { handlers = { @@ -105,7 +107,17 @@ TypeTranslator::TypeTranslator() { VLOG(10) << "[vartype translating]" << "[" << var_desc.Name() << "] from SELECTED_ROWS"; - return this->operator[](VarType::LOD_TENSOR)(ctx, var_desc); + ir::Type dtype = + this->operator[](var_desc.GetDataType())(ctx, var_desc); + + SelectedRowsTypeStorage::Dim dim = phi::make_ddim(var_desc.GetShape()); + SelectedRowsTypeStorage::DataLayout layout = + SelectedRowsTypeStorage::DataLayout::UNDEFINED; + SelectedRowsTypeStorage::LoD lod = {}; + size_t offset = 0; + ir::Type SelectedRows = + SelectedRowsType::get(ctx, dtype, dim, layout, lod, offset); + return SelectedRows; }}, }; } diff --git a/paddle/phi/api/yaml/legacy_ops.yaml b/paddle/phi/api/yaml/legacy_ops.yaml index a4b0fa02d6920eb03dda1d24b914d7c06ea58329..d2add2e0a26b7f1e92fc7b290a0d4086fb652221 100755 --- a/paddle/phi/api/yaml/legacy_ops.yaml +++ b/paddle/phi/api/yaml/legacy_ops.yaml @@ -253,6 +253,16 @@ data_type : weight backward : embedding_grad +- op : embedding_grad_dense + args : (Tensor x, Tensor weight, Tensor out_grad, int64_t padding_idx=-1, bool sparse=false) + output : Tensor(weight_grad) + infer_meta : + func : UnchangedInferMeta + param : [weight] + kernel : + func : embedding_grad + data_type : weight + - op : empty args : (IntArray shape, DataType dtype=DataType::FLOAT32, Place place=CPUPlace()) output: Tensor(out) diff --git a/paddle/phi/api/yaml/op_compat.yaml b/paddle/phi/api/yaml/op_compat.yaml index e964afc0405b81a88f6a4d0e0a955a98e942683f..01baacdf3f6323c7b91196ce57728413e9350788 100755 --- a/paddle/phi/api/yaml/op_compat.yaml +++ b/paddle/phi/api/yaml/op_compat.yaml @@ -882,6 +882,8 @@ {x : Ids, weight : W} outputs : out : Out + attrs : + sparse : is_sparse manual_signature : [embedding_grad] extra : attrs : [bool is_sparse = false, bool is_distributed = false, bool remote_prefetch = false, diff --git a/paddle/phi/infermeta/unary.cc b/paddle/phi/infermeta/unary.cc index aaea2e8094ba1d4a998b36a0f42b79f5119fb251..9b69dcfdd8008645a096345bc73862a0c2fca451 100644 --- a/paddle/phi/infermeta/unary.cc +++ b/paddle/phi/infermeta/unary.cc @@ -884,6 +884,11 @@ void EigInferMeta(const MetaTensor& x, MetaTensor* out_w, MetaTensor* out_v) { out_v->set_dtype(out_dtype); } +void EmbeddingGradSparseInferMeta(const MetaTensor& x, MetaTensor* out) { + out->set_dims(x.dims()); + out->set_dtype(x.dtype()); +} + void EighInferMeta(const MetaTensor& x, const std::string& uplo, MetaTensor* out_w, diff --git a/paddle/phi/infermeta/unary.h b/paddle/phi/infermeta/unary.h index f0257fb75a22e6a1f81686c773a6ca99a555fccb..d03caa048b591c5d4be86a0e399c4d1da87fc208 100644 --- a/paddle/phi/infermeta/unary.h +++ b/paddle/phi/infermeta/unary.h @@ -149,6 +149,8 @@ void DistBroadcastInferMeta(const MetaTensor& x, MetaTensor* out); void DistReduceInferMeta(const MetaTensor& x, MetaTensor* out); +void EmbeddingGradSparseInferMeta(const MetaTensor& x, MetaTensor* out); + void EigInferMeta(const MetaTensor& x, MetaTensor* out_w, MetaTensor* out_v); void EighInferMeta(const MetaTensor& x, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ae097ef6d9b725e3ab41c68f0b3f72e2573ced78..20de0a13a6ff0042f26b5291b39dc4614b5ff36a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -227,14 +227,6 @@ if(TARGET standalone_executor_test) endif() endif() -if(TARGET standalone_executor_new_ir_test) - if(NOT WIN32) - set_tests_properties( - standalone_executor_new_ir_test - PROPERTIES ENVIRONMENT "FLAGS_enable_new_ir_in_executor=true") - endif() -endif() - if(TARGET layer_test) add_dependencies(layer_test jit_download_program) add_dependencies(layer_test_new jit_download_program) diff --git a/test/cpp/new_executor/CMakeLists.txt b/test/cpp/new_executor/CMakeLists.txt index fa7c462b9927f6b32a01bbdb853dd6735bfbfbe6..63804dd0e611edcb903ff34f98eb5acf27f313ea 100644 --- a/test/cpp/new_executor/CMakeLists.txt +++ b/test/cpp/new_executor/CMakeLists.txt @@ -1,10 +1,3 @@ -if(NOT WIN32) - cc_test( - standalone_executor_new_ir_test - SRCS standalone_executor_new_ir_test.cc - DEPS phi_kernel_adaptor pd_dialect ir) -endif() - # skip win32 since wget is not installed by default on windows machine. set(OPS diff --git a/test/cpp/new_executor/standalone_executor_new_ir_test.cc b/test/cpp/new_executor/standalone_executor_new_ir_test.cc deleted file mode 100644 index 858d96d4434453f574132b4155bb3f0f20ca6e46..0000000000000000000000000000000000000000 --- a/test/cpp/new_executor/standalone_executor_new_ir_test.cc +++ /dev/null @@ -1,285 +0,0 @@ -// Copyright (c) 2021 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 "paddle/fluid/framework/new_executor/standalone_executor.h" - -#include - -#include -#include -#include - -#include "paddle/phi/core/kernel_registry.h" - -#include "paddle/fluid/ir/dialect/pd_dialect.h" -#include "paddle/fluid/ir/dialect/pd_op.h" -#include "paddle/fluid/ir/transforms/pd_op_to_kernel_pass.h" -#include "paddle/ir/core/builder.h" -#include "paddle/ir/core/ir_context.h" -#include "paddle/ir/core/program.h" - -#include "paddle/fluid/ir/dialect/pd_type.h" - -#include "paddle/fluid/platform/init_phi.h" - -DECLARE_FILE_SYMBOLS(kernel_dialect); - -PD_DECLARE_KERNEL(full, CPU, ALL_LAYOUT); -PD_DECLARE_KERNEL(full_int_array, CPU, ALL_LAYOUT); -PD_DECLARE_KERNEL(uniform, CPU, ALL_LAYOUT); -PD_DECLARE_KERNEL(add, CPU, ALL_LAYOUT); -PD_DECLARE_KERNEL(sqrt, CPU, ALL_LAYOUT); - -bool simple_cmp(float a, float b) { return std::abs((a - b) / a) < 1e-5; } - -namespace paddle { -namespace framework { - -TEST(StandaloneExecutor, run) { - ir::IrContext* ctx = ir::IrContext::Instance(); - ir::Program program((ctx)); - - ctx->GetOrRegisterDialect(); - - ir::Builder builder = ir::Builder(ctx, program.block()); - - paddle::dialect::FullOp op1 = builder.Build( - std::vector{2, 2}, 1.0, phi::DataType::FLOAT32, phi::CPUPlace()); - - paddle::dialect::FullOp op2 = builder.Build( - std::vector{2, 2}, 1.0, phi::DataType::FLOAT32, phi::CPUPlace()); - - builder.Build(op1->result(0), op2->result(0)); - - auto kernel_program = paddle::dialect::PdOpLowerToKernelPass(&program); - - kernel_program->Print(std::cout); - - auto place = platform::CPUPlace(); - Scope scope; - - InterpreterCore test_core(place, std::move(kernel_program), &scope); - - test_core.Run({}); - - auto out_tensor = test_core.local_scope() == nullptr - ? scope.FindVar("inner_var_2")->Get() - : test_core.local_scope() - ->FindVar("inner_var_2") - ->Get(); - - bool res0 = simple_cmp(out_tensor.data()[0], 2.0); - bool res1 = simple_cmp(out_tensor.data()[1], 2.0); - bool res2 = simple_cmp(out_tensor.data()[2], 2.0); - bool res3 = simple_cmp(out_tensor.data()[3], 2.0); - - EXPECT_EQ(res0, true); - EXPECT_EQ(res1, true); - EXPECT_EQ(res2, true); - EXPECT_EQ(res3, true); -} - -TEST(StandaloneExecutor, run_2) { - ir::IrContext* ctx = ir::IrContext::Instance(); - ctx->GetOrRegisterDialect(); - ir::Program program(ctx); - ir::Builder builder(ctx, program.block()); - ir::Block* block = program.block(); - - // Def: A = paddle::dialect::UniformOp(std::vector shape, - // phi::DataType dtype, float min, float max, int seed, phi::Place place) - paddle::dialect::UniformOp uniform1 = - builder.Build(std::vector{2, 2}, - phi::DataType::FLOAT32, - 0.0, - 1.0, - 2, - phi::CPUPlace()); - EXPECT_EQ(uniform1->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 4u); - - // Def: B = paddle::dialect::UniformOp(...) - paddle::dialect::UniformOp uniform2 = - builder.Build(std::vector{2, 2}, - phi::DataType::FLOAT32, - 0.0, - 1.0, - 2, - phi::CPUPlace()); - EXPECT_EQ(uniform2->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 8u); - - // Def: C = paddle::dialect::AddOp(ir::OpResult x_, ir::OpResult y_) - paddle::dialect::AddOp add = builder.Build( - uniform1->result(0), uniform2->result(0)); - EXPECT_EQ(add->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 9u); - - paddle::dialect::ScaleOp scale = - builder.Build(add->result(0), 1.0, 0.0, true); - - EXPECT_EQ(scale->result(0).type().isa(), - true); - - auto kernel_program = paddle::dialect::PdOpLowerToKernelPass(&program); - - auto place = platform::CPUPlace(); - Scope scope; - - InterpreterCore test_core(place, std::move(kernel_program), &scope); - - test_core.Run({}); - - auto out_tensor = test_core.local_scope() == nullptr - ? scope.FindVar("inner_var_10")->Get() - : test_core.local_scope() - ->FindVar("inner_var_10") - ->Get(); - - bool res0 = simple_cmp(out_tensor.data()[0], 1.80721); - bool res1 = simple_cmp(out_tensor.data()[1], 1.70047); - bool res2 = simple_cmp(out_tensor.data()[2], 1.56764); - bool res3 = simple_cmp(out_tensor.data()[3], 1.85063); - std::cerr << out_tensor.data()[0] << "\t" - << out_tensor.data()[1] << "\t" - << out_tensor.data()[2] << "\t" - << out_tensor.data()[3] << std::endl; - EXPECT_EQ(res0, true); - EXPECT_EQ(res1, true); - EXPECT_EQ(res2, true); - EXPECT_EQ(res3, true); -} - -#ifdef PADDLE_WITH_CUDA -TEST(StandaloneExecutor, data_transfer) { - ir::IrContext* ctx = ir::IrContext::Instance(); - ctx->GetOrRegisterDialect(); - ir::Program program(ctx); - ir::Builder builder(ctx, program.block()); - ir::Block* block = program.block(); - - // Def: A = paddle::dialect::UniformOp(std::vector shape, - // phi::DataType dtype, float min, float max, int seed, phi::Place place) - paddle::dialect::UniformOp uniform1 = - builder.Build(std::vector{1}, - phi::DataType::FLOAT32, - 0.0, - 1.0, - 2, - phi::CPUPlace()); - EXPECT_EQ(uniform1->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 4u); - - // Def: B = paddle::dialect::UniformOp(...) - paddle::dialect::UniformOp uniform2 = - builder.Build(std::vector{100, 100}, - phi::DataType::FLOAT32, - 0.0, - 1.0, - 2, - phi::CPUPlace()); - EXPECT_EQ(uniform2->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 8u); - - // Def: C = paddle::dialect::AddOp(ir::OpResult x_, ir::OpResult y_) - paddle::dialect::AddOp add = builder.Build( - uniform1->result(0), uniform2->result(0)); - EXPECT_EQ(add->result(0).type().isa(), - true); - EXPECT_EQ(block->size(), 9u); - - program.Print(std::cout); - - auto kernel_program = paddle::dialect::PdOpLowerToKernelPass(&program); - - kernel_program->Print(std::cout); - - auto place = platform::CPUPlace(); - Scope scope; - - InterpreterCore test_core(place, std::move(kernel_program), &scope); - - test_core.Run({}); - - auto out_tensor = test_core.local_scope() == nullptr - ? scope.FindVar("inner_var_9")->Get() - : test_core.local_scope() - ->FindVar("inner_var_9") - ->Get(); - - auto& pool = phi::DeviceContextPool::Instance(); - phi::DenseTensor out; - phi::DeviceContext* dev_ctx = pool.Get(out_tensor.place()); - phi::Copy(*dev_ctx, out_tensor, place, true, &out); - - bool res0 = simple_cmp(out.data()[0], 0.903649); - bool res1 = simple_cmp(out.data()[1], 1.07367); - bool res2 = simple_cmp(out.data()[2], 1.10631); - bool res3 = simple_cmp(out.data()[3], 1.68683); - std::cerr << out.data()[0] << "\t" << out.data()[1] << "\t" - << out.data()[2] << "\t" << out.data()[3] - << std::endl; - EXPECT_EQ(res0, true); - EXPECT_EQ(res1, true); - EXPECT_EQ(res2, true); - EXPECT_EQ(res3, true); -} -#endif - -TEST(StandaloneExecutor, run_inplace_sqrt) { - ir::IrContext* ctx = ir::IrContext::Instance(); - ir::Program program((ctx)); - ctx->GetOrRegisterDialect(); - ir::Builder builder = ir::Builder(ctx, program.block()); - - paddle::dialect::FullOp full = builder.Build( - std::vector{2, 2}, 4.0, phi::DataType::FLOAT32, phi::CPUPlace()); - - builder.Build(full->result(0)); - - auto kernel_program = paddle::dialect::PdOpLowerToKernelPass(&program); - - kernel_program->Print(std::cout); - - auto place = platform::CPUPlace(); - Scope scope; - InterpreterCore test_core(place, std::move(kernel_program), &scope); - test_core.Run({}); - - auto out_tensor = test_core.local_scope() == nullptr - ? scope.FindVar("inner_var_0")->Get() - : test_core.local_scope() - ->FindVar("inner_var_0") - ->Get(); - - bool res0 = simple_cmp(out_tensor.data()[0], 2.0); - bool res1 = simple_cmp(out_tensor.data()[1], 2.0); - bool res2 = simple_cmp(out_tensor.data()[2], 2.0); - bool res3 = simple_cmp(out_tensor.data()[3], 2.0); - - EXPECT_EQ(scope.kids().size(), 1u); - EXPECT_EQ(scope.kids().front()->Size(), 1u); - EXPECT_EQ(res0, true); - EXPECT_EQ(res1, true); - EXPECT_EQ(res2, true); - EXPECT_EQ(res3, true); -} - -} // namespace framework -} // namespace paddle diff --git a/test/ir/new_ir/test_standalone_new_ir.py b/test/ir/new_ir/test_standalone_new_ir.py index ca924467d4e97bc8b55624b6e527c48b9d061c6f..41ee5151d69ab7a413c969f17259dc81bfb78015 100644 --- a/test/ir/new_ir/test_standalone_new_ir.py +++ b/test/ir/new_ir/test_standalone_new_ir.py @@ -89,6 +89,28 @@ class TestFeedOp(unittest.TestCase): np.testing.assert_array_equal(out[0], gold_res) +class TestSelectedRows(unittest.TestCase): + def test_with_new_ir(self): + place = paddle.CPUPlace() + exe = paddle.static.Executor(place) + + main_program = paddle.static.Program() + new_scope = paddle.static.Scope() + with paddle.static.scope_guard(new_scope): + with paddle.static.program_guard(main_program): + w = paddle.uniform([10, 10], dtype="float32") + w.stop_gradient = False + id = paddle.ones([2], dtype="int32") + t = paddle.nn.functional.embedding(id, w, sparse=True) + loss = paddle.mean(t) + paddle.static.gradients(loss, w) + + out = exe.run( + main_program, + fetch_list=[loss.name], + ) + + class TestAddGradOp(unittest.TestCase): def test_with_new_ir(self): place = paddle.CPUPlace()