1 #include "caffe2/operators/reshape_op.h" 2 #include "caffe2/utils/math.h" 6 REGISTER_CPU_OPERATOR(
Reshape, ReshapeOp<float, CPUContext>);
11 .TensorInferenceFunction(
12 [](
const OperatorDef& def,
const vector<TensorShape>& in) {
13 vector<TensorShape> out(2);
16 out[1].set_data_type(TensorProto::INT64);
17 out[1].add_dims(in[0].dims_size());
19 ArgumentHelper helper(def);
20 if (!helper.HasArgument(
"shape")) {
25 "New shape must be specified by either the input blob or the " 27 out[0].set_unknown_shape(
true);
33 "New shape must not be specified by the input blob and the " 34 "argument `shape` at the same time.");
37 auto actualNewShape = helper.GetRepeatedArgument<int64_t>(
"shape");
41 for (
int i = 0; i < actualNewShape.size(); ++i) {
45 "The dimensions in argument `shape` " 46 "must not be a negative number.");
48 if (actualNewShape[i] == 0) {
52 "Argument `shape` has a dimension set to zero that exceeds " 53 "the original dimension size.");
54 actualNewShape[i] = in[0].dims(i);
60 int64_t totalSize = 1;
61 for (
const auto d : in[0].dims()) {
66 for (
int i = 0; i < actualNewShape.size(); ++i) {
67 const auto dim = actualNewShape[i];
71 "Argument `shape` has more than one missing dimension.");
78 if (unknownIdx != -1) {
80 totalSize % size == 0,
81 "Argument `shape` does not agree with the input data.",
87 actualNewShape[unknownIdx] = totalSize / size;
92 "Argument `shape` does not agree with the input data.",
100 out[0].set_data_type(in[0].data_type());
101 for (
const auto d : actualNewShape) {
106 .AllowInplace({{0, 0}})
108 Reshape the input tensor similar to numpy's 109 [reshape](https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html). 111 Takes a tensor as input and an optional tensor specifying the new shape. When 112 the second input is absent, an extra argument shape must be specified. Outputs 113 the reshaped tensor as well as the original shape. 115 At most one dimension of the new shape can be -1. In this case, the value is 116 inferred from the size of the tensor and the remaining dimensions. A dimension 117 could also be 0, in which case the actual dimension value is going to be copied 118 from the input tensor. 122 - https://github.com/pytorch/pytorch/blob/master/caffe2/operators/reshape_op.cc 126 <summary> <b>Example</b> </summary> 131 workspace.ResetWorkspace() 133 op = core.CreateOperator( 136 ["reshaped", "old_shape"], 140 workspace.FeedBlob("data", (np.random.randint(100, size=(6)))) 141 print("data:", workspace.FetchBlob("data")) 142 workspace.RunOperatorOnce(op) 143 print("reshaped:", workspace.FetchBlob("reshaped")) 144 print("old_shape:", workspace.FetchBlob("old_shape")) 150 data: [86 60 85 96 7 37] 162 "*(type: Tuple(int))* New shape. Do not set if using " 163 "`new_shape` input.")
164 .Input(0,
"data",
"*(type: Tensor)* Input tensor.")
168 "*(type: Tensor`<int>`)* [OPTIONAL] Tensor containing new shape.")
169 .Output(0,
"reshaped",
"*(type: Tensor)* Reshaped output tensor.")
173 "*(type: Tensor`<int>`)* Tensor containing old shape of `data`.")
174 .InheritOnnxSchema();
176 class GetReshapeGradient :
public GradientMakerBase {
177 using GradientMakerBase::GradientMakerBase;
178 vector<OperatorDef> GetGradientDefs()
override {
179 return SingleGradientDef(
182 vector<string>{GO(0), O(1)},
183 vector<string>{GI(0),
"_" + GI(0) +
"_dims"});
187 bool CopyArguments()
const override {
192 REGISTER_GRADIENT(
Reshape, GetReshapeGradient);
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...