From 5df99cdaa97df3aa5c938fe1b19236dc83e912a8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=91=D0=B0=D1=80?= =?utf8?q?=D0=B0=D0=BD=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2/AI=20Tools=20Lab=20/S?= =?utf8?q?RR/Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Tue, 3 Sep 2019 20:04:14 +0300 Subject: [PATCH] [mir_caffe2] Do not insert Transposes (#7139) Remove insertion of Transpose operations, set the data format on operations instead. Signed-off-by: Sergei Barannikov --- compiler/mir-caffe2-importer/caffe2_op_creator.cpp | 81 ++++++++++------------ compiler/mir-caffe2-importer/caffe2_op_creator.h | 4 -- 2 files changed, 37 insertions(+), 48 deletions(-) diff --git a/compiler/mir-caffe2-importer/caffe2_op_creator.cpp b/compiler/mir-caffe2-importer/caffe2_op_creator.cpp index 46b0125..fdf509a 100644 --- a/compiler/mir-caffe2-importer/caffe2_op_creator.cpp +++ b/compiler/mir-caffe2-importer/caffe2_op_creator.cpp @@ -214,20 +214,6 @@ static std::vector getWindowSize(const ::caffe2::OperatorDef &op, return {kernel_h, kernel_w}; } -mir::Operation::Output *Caffe2OpCreator::convertCaffeToMIR(mir::Operation::Output *arg) -{ - // NCHW -> NHWC - auto transpose = createOp(arg, std::vector{0, 2, 3, 1}); - return transpose->getOutput(0); -} - -mir::Operation::Output *Caffe2OpCreator::convertMIRToCaffe(mir::Operation::Output *arg) -{ - // NHWC -> NCHW - auto transpose = createOp(arg, std::vector{0, 3, 1, 2}); - return transpose->getOutput(0); -} - // // Check functions // @@ -325,15 +311,19 @@ std::vector Caffe2OpCreator::convertAdd(const std::vector &inputs, const ::caffe2::OperatorDef &op) { + assert(inputs.size() == 2); + auto lhs = inputs[0]; + auto rhs = inputs[1]; + if (getSingleArgument(op, "broadcast", 0) != 0) { // FIXME This only works when 'axis' == 1 and the second input is 1-D. - auto result = createOp(convertCaffeToMIR(inputs[0]), inputs[1])->getOutput(0); - - return {convertMIRToCaffe(result)}; + rhs = createOp(rhs, Shape{1, rhs->getShape().dim(0), 1, 1})->getOutput(0); + auto result = createOp(lhs, rhs)->getOutput(0); + return {result}; } - auto result = createOp(inputs[0], inputs[1])->getOutput(0); + auto result = createOp(lhs, rhs)->getOutput(0); return {result}; } @@ -351,11 +341,9 @@ Caffe2OpCreator::convertAveragePool(const std::vector std::vector pad_before, pad_after; std::tie(pad_before, pad_after) = getPadding(op); - input = convertCaffeToMIR(input); auto result = createOp(input, window_size, strides, pad_before, pad_after, - false, mir::DataFormat::NHWC) + false, DataFormat::NCHW) ->getOutput(0); - result = convertMIRToCaffe(result); return {result}; } @@ -386,8 +374,8 @@ Caffe2OpCreator::convertConv(const std::vector &inputs // TODO handle properly kernel with layer multiplier auto transposed_tensor = mir::transposeTensor<0, 1, 3, 2>(kernel_tensor); auto kernel = createOp(transposed_tensor)->getOutput(0); - result = createOp(convertCaffeToMIR(inputs[0]), kernel, stride_shape, - pad_before, pad_after) + result = createOp(inputs[0], kernel, stride_shape, pad_before, + pad_after, DataFormat::NCHW) ->getOutput(0); } else @@ -397,8 +385,8 @@ Caffe2OpCreator::convertConv(const std::vector &inputs kernel_tensor = fixGroupedKernel(num_groups, kernel_tensor); kernel_tensor = transposeTensor<3, 0, 1, 2>(kernel_tensor); auto kernel = createOp(kernel_tensor)->getOutput(0); - result = createOp(convertCaffeToMIR(inputs[0]), kernel, stride_shape, pad_before, - pad_after) + result = createOp(inputs[0], kernel, stride_shape, pad_before, pad_after, + DataFormat::NCHW) ->getOutput(0); } @@ -407,7 +395,7 @@ Caffe2OpCreator::convertConv(const std::vector &inputs result = createOp(result, inputs[2])->getOutput(0); } - return {convertMIRToCaffe(result)}; + return {result}; } std::vector @@ -470,11 +458,9 @@ Caffe2OpCreator::convertMaxPool(const std::vector &inp std::vector pad_before, pad_after; std::tie(pad_before, pad_after) = getPadding(op); - input = convertCaffeToMIR(input); auto result = createOp(input, window_size, strides, pad_before, pad_after, - mir::DataFormat::NHWC) + DataFormat::NCHW) ->getOutput(0); - result = convertMIRToCaffe(result); return {result}; } @@ -482,15 +468,19 @@ std::vector Caffe2OpCreator::convertMul(const std::vector &inputs, const ::caffe2::OperatorDef &op) { + assert(inputs.size() == 2); + auto lhs = inputs[0]; + auto rhs = inputs[1]; + if (getSingleArgument(op, "broadcast", 0) != 0) { // FIXME This only works when `axis` == 1 and the second input is 1-D. - auto result = createOp(convertCaffeToMIR(inputs[0]), inputs[1])->getOutput(0); - - return {convertMIRToCaffe(result)}; + rhs = createOp(rhs, Shape{1, rhs->getShape().dim(0), 1, 1})->getOutput(0); + auto result = createOp(lhs, rhs)->getOutput(0); + return {result}; } - auto result = createOp(inputs[0], inputs[1])->getOutput(0); + auto result = createOp(lhs, rhs)->getOutput(0); return {result}; } @@ -505,17 +495,17 @@ std::vector Caffe2OpCreator::convertResizeNearest(const std::vector &inputs, const ::caffe2::OperatorDef &op) { - // assume NCHW and convert to MIR (NHWC) std::vector scales(4); assert(inputs[0]->getShape().rank() == 4 && "only 4d tensors is supported"); - scales[0] = 1; - // default to noop - scales[1] = getSingleArgument(op, "height_scale", 1.0f); - scales[2] = getSingleArgument(op, "width_scale", 1.0f); - scales[3] = 1; - auto resize = createOp(convertCaffeToMIR(inputs[0]), - ops::ResizeOp::ResizeMethod::nearestNeighbor, scales); - return {convertMIRToCaffe(resize->getOutput(0))}; + // Assuming NCHW format. + scales[0] = 1.0f; + scales[1] = 1.0f; + scales[2] = getSingleArgument(op, "height_scale", 1.0f); + scales[3] = getSingleArgument(op, "width_scale", 1.0f); + auto result = + createOp(inputs[0], ops::ResizeOp::ResizeMethod::nearestNeighbor, scales) + ->getOutput(0); + return {result}; } std::vector @@ -569,20 +559,23 @@ Caffe2OpCreator::convertSpatialBN(const std::vector &i bias_data.at(idx) *= -1; auto mean = createOp(mean_tensor)->getOutput(0); - auto result = createOp(convertCaffeToMIR(inputs[0]), mean)->getOutput(0); + mean = createOp(mean, Shape{1, mean->getShape().dim(0), 1, 1})->getOutput(0); + auto result = createOp(inputs[0], mean)->getOutput(0); // res2 = res1 * scale / (var + epsilon) Tensor multiplier(scale_tensor); for (auto &idx : ShapeRange(scale_tensor.getShape())) multiplier.at(idx) /= std::sqrt(*reinterpret_cast(var_tensor.at(idx)) + eps); auto scale = createOp(scale_tensor)->getOutput(0); + scale = createOp(scale, Shape{1, scale->getShape().dim(0), 1, 1})->getOutput(0); result = createOp(result, scale)->getOutput(0); // overall_res = res2 + bias auto bias = createOp(bias_tensor)->getOutput(0); + bias = createOp(bias, Shape{1, bias->getShape().dim(0), 1, 1})->getOutput(0); result = createOp(result, bias)->getOutput(0); - return {convertMIRToCaffe(result)}; + return {result}; } std::vector diff --git a/compiler/mir-caffe2-importer/caffe2_op_creator.h b/compiler/mir-caffe2-importer/caffe2_op_creator.h index 57424a2..686c6d2 100644 --- a/compiler/mir-caffe2-importer/caffe2_op_creator.h +++ b/compiler/mir-caffe2-importer/caffe2_op_creator.h @@ -104,10 +104,6 @@ public: private: mir::Graph *_graph = nullptr; - mir::Operation::Output *convertCaffeToMIR(mir::Operation::Output *arg); - - mir::Operation::Output *convertMIRToCaffe(mir::Operation::Output *arg); - template mir::Operation *createOp(Types &&... args); }; -- 2.7.4