// Copyright (c) 2024 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 "test/cpp/pir/custom_engine/custom_engine_op.h" #include "paddle/fluid/pir/dialect/operator/utils/utils.h" namespace paddle { namespace dialect { const char *FakeEngineOp::attributes_name[2] = {"input_names", "output_names"}; OpInfoTuple FakeEngineOp::GetOpInfo() { std::vector inputs = { OpInputInfo("x", "pir::VectorType", false, false, false, false)}; std::vector attributes = { paddle::dialect::OpAttributeInfo( "input_names", "pir::ArrayAttribute", ""), paddle::dialect::OpAttributeInfo( "output_names", "pir::ArrayAttribute", "")}; std::vector outputs = { OpOutputInfo("out", "pir::VectorType", false, false)}; paddle::dialect::OpRunTimeInfo run_time_info = OpRunTimeInfo("", {}, "", {}, {}, {}, {}, {}); return std::make_tuple( inputs, attributes, outputs, run_time_info, "fake_engine"); } #define ADD_VEC_ATTRIBUTE(type, name) \ std::vector name##_tmp; \ name##_tmp.reserve(name.size()); \ for (const auto &v : name) { \ name##_tmp.push_back(type::get(pir::IrContext::Instance(), v)); \ } \ pir::Attribute attr_##name = \ pir::ArrayAttribute::get(pir::IrContext::Instance(), name##_tmp); \ argument.AddAttribute(#name, attr_##name) #define VERIFY_ATTRIBUTE(type, name) \ PADDLE_ENFORCE_GT( \ attributes.count(#name), \ 0, \ common::errors::InvalidArgument(#name " does not exist.")); \ PADDLE_ENFORCE_EQ(attributes.at(#name).isa(), \ true, \ common::errors::InvalidArgument( \ "Type of attribute: " #name " is not " #type)) void FakeEngineOp::Build(pir::Builder &builder, // NOLINT pir::OperationArgument &argument, // NOLINT pir::Value x, std::vector input_names, std::vector output_names, std::vector> outputs_shape, std::vector outputs_dtype) { VLOG(4) << "Start build FakeEngineOp"; VLOG(4) << "Builder construction inputs"; std::vector argument_inputs = {x}; argument.AddInputs(argument_inputs); VLOG(4) << "Builder construction attributes"; ADD_VEC_ATTRIBUTE(pir::StrAttribute, input_names); ADD_VEC_ATTRIBUTE(pir::StrAttribute, output_names); VLOG(4) << "Builder construction outputs"; std::vector argument_outputs; std::vector out_types; for (size_t i = 0; i < static_cast(outputs_shape.size()); i++) { if (outputs_dtype[i] == phi::DataType::UNDEFINED) { out_types.push_back(pir::Type()); } else { out_types.push_back(pir::DenseTensorType::get( pir::IrContext::Instance(), TransToIrDataType(outputs_dtype[i]), phi::DDim(outputs_shape[i].data(), outputs_shape[i].size()), phi::DataLayout::kNCHW, phi::LoD(), 0)); } } pir::Type out_vector_type = pir::VectorType::get(pir::IrContext::Instance(), out_types); argument_outputs.push_back(out_vector_type); argument.AddOutputs(argument_outputs.begin(), argument_outputs.end()); argument.AddRegion(nullptr); ::pir::PassStopGradientsDefaultly(argument); } void FakeEngineOp::VerifySig() { VLOG(4) << "Start Verifying inputs, outputs and attributes for: " "FakeEngineOp."; VLOG(4) << "Verifying inputs:"; { auto input_size = num_operands(); PADDLE_ENFORCE_EQ(input_size, 1, common::errors::InvalidArgument( "The size of inputs must be equal to 1.")); PADDLE_ENFORCE_EQ((*this)->operand_source(0).type().isa(), true, common::errors::InvalidArgument( "Type validation failed for the 0th input, got %s.", (*this)->operand_source(0).type())); if (auto vec_type = (*this)->operand_source(0).type().dyn_cast()) { for (size_t i = 0; i < vec_type.size(); ++i) { PADDLE_ENFORCE_EQ( vec_type[i].isa(), true, common::errors::InvalidArgument( "Type validation failed for the 0th input, got %s.", (*this)->operand_source(0).type())); } } } VLOG(4) << "Verifying attributes:"; { auto &attributes = this->attributes(); VERIFY_ATTRIBUTE(pir::ArrayAttribute, input_names); VERIFY_ATTRIBUTE(pir::ArrayAttribute, output_names); } VLOG(4) << "Verifying outputs:"; { auto output_size = num_results(); PADDLE_ENFORCE_EQ(output_size, 1, common::errors::InvalidArgument( "The size of outputs must be equal to 1.")); auto output_type = (*this)->result(0).type(); PADDLE_ENFORCE_EQ(output_type.isa(), true, common::errors::InvalidArgument( "Type validation failed for the 0th output.")); } VLOG(4) << "End Verifying for: FakeEngineOp."; } pir::Block *FakeEngineOp::block() { pir::Region ®ion = (*this)->region(0); if (region.empty()) region.emplace_back(); return ®ion.front(); } pir::Block *FakeEngineOp::block() const { pir::Region ®ion = (*this)->region(0); PADDLE_ENFORCE_EQ(region.empty(), false, ::common::errors::Unavailable( "Required CustomEngineOp's region must not be empty.")); return ®ion.front(); } } // namespace dialect } // namespace paddle IR_DEFINE_EXPLICIT_TYPE_ID(paddle::dialect::FakeEngineOp)