#ifndef CAFFE2_OPERATORS_PAD_OP_H_ #define CAFFE2_OPERATORS_PAD_OP_H_ #include "caffe2/core/context.h" #include "caffe2/core/logging.h" #include "caffe2/core/operator.h" #include "caffe2/operators/conv_pool_op_base.h" #include "caffe2/utils/math.h" namespace caffe2 { // Padding mode similar to numpy. enum class PadMode { CONSTANT = 0, // pad constant values, with string "constant" REFLECT = 1, // pads with reflect values, with string "reflect" EDGE = 2, // pads with the edge values, with string "edge" }; CAFFE2_API PadMode StringToPadMode(const string&); template class PadImageOp final : public ConvPoolOpBase { public: USE_CONV_POOL_BASE_FUNCTIONS(Context); template explicit PadImageOp(Args&&... args) : ConvPoolOpBase(std::forward(args)...), mode_(StringToPadMode( this->template GetSingleArgument("mode", "constant"))), value_(static_cast( this->template GetSingleArgument("value", 0.0))) { CAFFE_ENFORCE( legacy_pad_ == LegacyPadding::NOTSET, "Padding layer only supports explicit pad values."); CAFFE_ENFORCE( dilation_h() == 1 && dilation_w() == 1, "Pooling op does not support dilation right now."); CAFFE_ENFORCE( stride_h() == 1 && stride_w() == 1, "Pooling op does not support stride right now."); // Pad op does not use kernel sizes, so we set it to 1 for computing the // output size. kernel_.assign(pads_.size() / 2, 1); } ~PadImageOp() {} bool RunOnDeviceWithOrderNCHW() override; bool RunOnDeviceWithOrderNHWC() override; static std::vector PadTensorInference( const OperatorDef& def, const vector& in); private: PadMode mode_; T value_; // Input: X // Output: Y }; template class PadImageGradientOp final : public ConvPoolOpBase { public: USE_CONV_POOL_BASE_FUNCTIONS(Context); template explicit PadImageGradientOp(Args&&... args) : ConvPoolOpBase(std::forward(args)...), mode_(StringToPadMode( this->template GetSingleArgument("mode", "constant"))) { CAFFE_ENFORCE( legacy_pad_ == LegacyPadding::NOTSET, "Padding layer only supports explicit pad values."); CAFFE_ENFORCE( dilation_h() == 1 && dilation_w() == 1, "Pooling op does not support dilation right now."); // Pad op does not use kernel sizes, so we set it to 1 for computing the // output size. kernel_.assign(pads_.size() / 2, 1); } ~PadImageGradientOp() {} bool RunOnDeviceWithOrderNCHW() override; bool RunOnDeviceWithOrderNHWC() override; private: PadMode mode_; // Input: dY // Output: dX }; } // namespace caffe2 #endif // CAFFE2_OPERATORS_PAD_OP_H_