trt_op_converter_pass.cc 4.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (c) 2022 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/infrt/dialect/tensorrt/trt_op_converter_pass.h"
W
Wilber 已提交
15 16

#include <glog/logging.h>
17 18
#include <mlir/IR/Builders.h>
#include <mlir/Transforms/DialectConversion.h>
W
Wilber 已提交
19 20

#include "paddle/infrt/dialect/dense_tensor.h"
21
#include "paddle/infrt/dialect/pd/ir/pd_ops.h"
W
Wilber 已提交
22 23
#include "paddle/infrt/dialect/phi/ir/infrt_phi_tensor.h"
#include "paddle/infrt/dialect/phi/ir/phi_base.h"
S
Shang Zhizhou 已提交
24
#include "paddle/infrt/dialect/tensorrt/trt_dialect_types.h"
W
Wilber 已提交
25
#include "paddle/infrt/dialect/tensorrt/trt_ops.h"
26 27 28 29 30 31

namespace infrt {
namespace trt {

#include "paddle/infrt/dialect/tensorrt/pd_lower_to_trt.cpp.inc"  // NOLINT

S
Shang Zhizhou 已提交
32
struct PD2TRT_GraphLower : public ::mlir::RewritePattern {
33
  explicit PD2TRT_GraphLower(::mlir::MLIRContext *context)
S
Shang Zhizhou 已提交
34 35 36
      : ::mlir::RewritePattern("pd.graph", 1, context, {"trt.create_engine"}) {}
  ::mlir::LogicalResult matchAndRewrite(
      ::mlir::Operation *op, ::mlir::PatternRewriter &rewriter) const override {
37
    auto casted_op = ::llvm::dyn_cast<infrt::pd::GraphOp>(op);
S
Shang Zhizhou 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50
    ::mlir::Operation::operand_range inputs = casted_op.inputs();
    auto ods_loc = rewriter.getFusedLoc(op->getLoc());
    CreateEngineOp create_engine_op;
    // inputs
    ::mlir::SmallVector<::mlir::Value, 4> trt_inputs;
    for (auto v : inputs) {
      trt_inputs.push_back(v);
    }
    create_engine_op = rewriter.create<CreateEngineOp>(
        ods_loc,
        ::llvm::SmallVector<mlir::Type, 4>(1, EngineType::get()),
        trt_inputs,
        true /*run_once*/);
W
Wilber 已提交
51 52 53 54 55
    auto &block = create_engine_op.body().emplaceBlock();
    block.getOperations().splice(block.begin(),
                                 casted_op.getBody()->getOperations(),
                                 casted_op.getBody()->begin(),
                                 casted_op.getBody()->end());
S
Shang Zhizhou 已提交
56

W
Wilber 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    // trt.compute
    ::llvm::SmallVector<::mlir::Value, 4> replace_values2;
    auto ctx_op = rewriter.create<::infrt::phi::CreateGPUContextOp>(
        ods_loc,
        infrt::phi::ContextType::get(rewriter.getContext(),
                                     infrt::TargetType::GPU));
    auto compute_op = rewriter.create<EngineComputeOp>(
        ods_loc,
        ::infrt::DenseTensorListType::get(rewriter.getContext()),
        create_engine_op.engine(),
        ctx_op.output());
    auto tensor_list_val = compute_op.outputs();
    for (size_t i = 0; i < casted_op.getNumResults(); ++i) {
      auto res = casted_op->getResult(i);
      auto int_attr = mlir::IntegerAttr::get(
          mlir::IntegerType::get(rewriter.getContext(), 32), i);
      auto get_tensor_op = rewriter.create<::infrt::dt::TensorListGetTensorOp>(
          ods_loc, res.getType(), tensor_list_val, int_attr);
      replace_values2.push_back(get_tensor_op.output());
S
Shang Zhizhou 已提交
76
    }
W
Wilber 已提交
77 78
    ctx_op->moveBefore(ctx_op->getBlock(), ctx_op->getBlock()->begin());
    rewriter.replaceOp(op, replace_values2);
S
Shang Zhizhou 已提交
79 80 81 82
    return ::mlir::success();
  }
};

83 84 85
void TRTOpConverterPass::runOnOperation() {
  // The first thing to define is the conversion target. This will define the
  // final target for this lowering.
86
  ::mlir::ConversionTarget target(getContext());
87 88 89 90 91

  // We define the specific operations, or dialects, that are legal targets for
  // this lowering. In our case, we are lowering to TensorRTDialect from
  // PaddleDialect
  target.addLegalDialect<TensorRTDialect>();
W
Wilber 已提交
92 93 94
  target.addLegalDialect<::infrt::phi::PHIDialect>();
  target.addLegalDialect<::infrt::dt::DTDialect>();
  target.addLegalDialect<phi::PHIDenseTensorDialect>();
95 96 97

  // Now that the conversion target has been defined, we just need to provide
  // the set of patterns that will lower the TensorRT operations.
98
  ::mlir::RewritePatternSet patterns(&getContext());
99
  populateWithGenerated(patterns);
S
Shang Zhizhou 已提交
100
  patterns.add<PD2TRT_GraphLower>(&getContext());
101 102 103 104

  // With the target and rewrite patterns defined, we can now attempt the
  // conversion. The conversion will signal failure if any of our `illegal`
  // operations were not converted successfully.
105
  if (::mlir::failed(
106 107 108 109 110 111
          applyPartialConversion(getOperation(), target, std::move(patterns))))
    signalPassFailure();
}

}  // namespace trt
}  // namespace infrt