1 #ifndef CAFFE2_OPERATORS_NUMPY_TILE_OP_H_ 2 #define CAFFE2_OPERATORS_NUMPY_TILE_OP_H_ 4 #include "caffe2/core/common_omp.h" 5 #include "caffe2/core/context.h" 6 #include "caffe2/core/logging.h" 7 #include "caffe2/core/operator.h" 8 #include "caffe2/utils/math.h" 13 template <
class Context>
16 USE_OPERATOR_CONTEXT_FUNCTIONS;
17 template <
class... Args>
23 const auto& input =
Input(0);
24 const auto& repeats =
Input(1);
28 CAFFE_ENFORCE_EQ(repeats.dim(), 1,
"repeats input must be a 1-d tensor");
32 "repeats input have the same" 33 " number of elements as `inputs` has dimensions.");
34 const int64_t *repeats_data = repeats.template data<int64_t>();
35 for (
size_t i = 0; i < repeats.numel(); ++i) {
36 CAFFE_ENFORCE_GE(repeats_data[i], 0);
39 auto* output = Output(0);
44 Tensor *src = &buffer, *dst = output;
46 vector<int64_t> output_dims(input.sizes().vec());
47 for (
size_t i = 0; i < repeats.numel(); ++i) {
48 if (repeats_data[i] == 1) {
52 const auto outer_dim = src->size_to_dim(i);
54 const auto inner_dim = src->size_from_dim(i);
56 dst->Resize(outer_dim, inner_dim * repeats_data[i]);
66 const char* src_data =
static_cast<const char*
>(src->raw_data());
67 char* dst_data =
static_cast<char*
>(dst->raw_mutable_data(src->dtype()));
78 output_dims[i] *= repeats_data[i];
79 dst->Reshape(output_dims);
88 output->CopyFrom(*src);
100 const char* input_data,
102 for (
auto i = 0; i < outer_dim; ++i) {
103 for (
auto t = 0; t < num_tiles; ++t) {
104 context_.CopyItemsSameDevice(meta, inner_dim, input_data, output_data);
105 output_data += inner_dim * item_size;
107 input_data += inner_dim * item_size;
111 Tensor buffer{Context::GetDeviceType()};
116 #endif // CAFFE2_OPERATORS_NUMPY_TILE_OP_H_
const Tensor & Input(int idx, DeviceType type=Context::GetDeviceType())
Retrieve a non-owning reference to the input at position 'idx' for this operator. ...
A global dictionary that holds information about what Caffe2 modules have been loaded in the current ...
bool RunOnDevice() override