trt_op_converter_pass.cc 5.3 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

namespace infrt {
namespace trt {

30 31 32 33 34 35 36 37 38 39 40 41 42 43
#ifdef INFRT_WITH_TRT

#define STRING_TO_ENUM_TYPE(enum_type) enum_type
#define STRING_TO_ENUM_VALUE(enum_value) enum_value
#include <NvInfer.h>

#else  // INFRT_WITH_TRT

#define STRING_TO_ENUM_TYPE(enum_type) std::string
#define STRING_TO_ENUM_VALUE(enum_value) #enum_value

#endif  // INFRT_WITH_TRT

template <typename T>
44 45 46
::mlir::IntegerAttr createNvinferEnumAttr(
    ::mlir::PatternRewriter &rewriter,  // NOLINT
    T enum_value) {
47 48 49 50 51
  return rewriter.getSI32IntegerAttr((int32_t)enum_value);
}

template <>
::mlir::IntegerAttr createNvinferEnumAttr<std::string>(
52
    ::mlir::PatternRewriter &rewriter, std::string enum_value) {  // NOLINT
53 54 55 56
  (void)enum_value;
  return rewriter.getSI32IntegerAttr(-1);
}

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

S
Shang Zhizhou 已提交
59
struct PD2TRT_GraphLower : public ::mlir::RewritePattern {
60
  explicit PD2TRT_GraphLower(::mlir::MLIRContext *context)
61 62
      : ::mlir::RewritePattern(
            "infrt.graph", 1, context, {"trt.create_engine"}) {}
S
Shang Zhizhou 已提交
63 64
  ::mlir::LogicalResult matchAndRewrite(
      ::mlir::Operation *op, ::mlir::PatternRewriter &rewriter) const override {
65
    auto casted_op = ::llvm::dyn_cast<::infrt::GraphOp>(op);
S
Shang Zhizhou 已提交
66 67 68 69 70 71 72 73 74 75 76 77 78
    ::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 已提交
79 80 81 82 83
    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 已提交
84

W
Wilber 已提交
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
    // 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 已提交
104
    }
W
Wilber 已提交
105 106
    ctx_op->moveBefore(ctx_op->getBlock(), ctx_op->getBlock()->begin());
    rewriter.replaceOp(op, replace_values2);
S
Shang Zhizhou 已提交
107 108 109 110
    return ::mlir::success();
  }
};

111 112 113
void TRTOpConverterPass::runOnOperation() {
  // The first thing to define is the conversion target. This will define the
  // final target for this lowering.
114
  ::mlir::ConversionTarget target(getContext());
115 116 117 118 119

  // 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 已提交
120 121 122
  target.addLegalDialect<::infrt::phi::PHIDialect>();
  target.addLegalDialect<::infrt::dt::DTDialect>();
  target.addLegalDialect<phi::PHIDenseTensorDialect>();
123 124 125

  // Now that the conversion target has been defined, we just need to provide
  // the set of patterns that will lower the TensorRT operations.
126
  ::mlir::RewritePatternSet patterns(&getContext());
127
  populateWithGenerated(patterns);
S
Shang Zhizhou 已提交
128
  patterns.add<PD2TRT_GraphLower>(&getContext());
129 130 131 132

  // 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.
133
  if (::mlir::failed(
134 135 136 137 138 139
          applyPartialConversion(getOperation(), target, std::move(patterns))))
    signalPassFailure();
}

}  // namespace trt
}  // namespace infrt