Caffe2 - C++ API
A deep learning, cross platform ML framework
tile_op.cc
1 
17 #include "caffe2/operators/tile_op.h"
18 
19 namespace caffe2 {
20 
21 REGISTER_CPU_OPERATOR(Tile, TileOp<CPUContext>);
22 REGISTER_CPU_OPERATOR(TileGradient, TileGradientOp<float, CPUContext>);
23 
24 OPERATOR_SCHEMA(Tile)
25  .NumInputs(1, 3)
26  .NumOutputs(1)
27  .TensorInferenceFunction(
28  [](const OperatorDef& def, const vector<TensorShape>& in) {
29  vector<TensorShape> out(1);
30  out[0] = TensorShape(in[0]);
31  ArgumentHelper helper(def);
32 
33  auto tiles = helper.GetSingleArgument<int32_t>("tiles", 1);
34  auto axis = helper.GetSingleArgument<int32_t>("axis", 0);
35  if (in.size() > 1) {
36  // Tile or axis is specified as input; we can't determine
37  // the size
38  out[0].set_unknown_shape(true);
39  } else {
40  const auto canonical_axis =
41  canonical_axis_index_(axis, out[0].dims().size());
42  out[0].set_dims(
43  canonical_axis, out[0].dims().Get(canonical_axis) * tiles);
44  }
45  return out;
46  })
47  .SetDoc(R"DOC(
48 Constructs a tensor by tiling a given tensor along a specified axis.
49 
50 This operation creates a new tensor by replicating the input tensor 'tiles'
51 times along dimension 'axis'. The output tensor's 'axis'th dimension has
52 input.dims(axis) * tiles elements, and the values of input are replicated
53 'tiles' times along the 'axis'th dimension.
54 For example, tiling [[a b c d]] by tile=2, axis=0 produces
55 [[a b c d], [a b c d]].
56 )DOC")
57  .Arg("tiles", "Number of replicas")
58  .Arg("axis", "Axis to replicate along")
59  .Input(0, "data", "The input tensor.")
60  .Input(1, "tiles", "(optional) Number of replicas (overrides argument)")
61  .Input(2, "axis", "(optional) Axis to replicate along (overrides argument)")
62  .Output(
63  0,
64  "tiled_data",
65  "Tensor that will contain input replicated along the given axis.");
66 
67 OPERATOR_SCHEMA(TileGradient).NumInputs(1, 3).NumOutputs(1);
68 
69 class GetTileGradient : public GradientMakerBase {
70  using GradientMakerBase::GradientMakerBase;
71  vector<OperatorDef> GetGradientDefs() override {
72  // Check whether the tiles/axis information was
73  // passed through input arguments
74  vector<std::string> g_inputs({GO(0)});
75  if (Def().input_size() > 1) {
76  g_inputs.push_back(I(1));
77  }
78  if (Def().input_size() > 2) {
79  g_inputs.push_back(I(2));
80  }
81  return SingleGradientDef(
82  "TileGradient", "", g_inputs, vector<string>{GI(0)});
83  }
84 };
85 
86 REGISTER_GRADIENT(Tile, GetTileGradient);
87 
88 } // namespace caffe2
Copyright (c) 2016-present, Facebook, Inc.
static vector< OperatorDef > SingleGradientDef(const Args &...args)
a helper function to allow one to create one single operator def, which is usually the case for many ...