int kernel_h(0), kernel_w(0);
if (is_global_pooling) {
- auto& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& input_shape = inputs[0].getShape();
assert(input_shape.rank() == 4 && "getWindowShape() inputs must be of rank 4");
kernel_h = input_shape.dim(2);
kernel_w = input_shape.dim(3);
const MIRTensors& mir_tensors) {
auto weights_tensor = transposeTensor<1, 0>(mir_tensors.at(op.input(1)));
- auto& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& input_shape = inputs[0].getShape();
// Transform input into 2-D tensor by flattening axes
Shape shape{input_shape.dim(0), input_shape.numElements() / input_shape.dim(0)};
const ::caffe2::OperatorDef& op) {
// assume NCHW and convert to MIR (NHWC)
std::vector<float> scales(4);
- assert(inputs[0].op->getOutputShape(0).rank() == 4 && "only 4d tensors is supported");
+ 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);
}
std::vector<IODescriptor> Caffe2OpCreator::convertSum(const std::vector<IODescriptor>& inputs) {
- auto& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& input_shape = inputs[0].getShape();
for (auto& in : inputs)
- assert(input_shape == in.op->getOutputShape(inputs[0].index) && "All Sum inputs must have same shape");
+ assert(input_shape == in.getShape() && "All Sum inputs must have same shape");
auto op = createOp<ops::ElementwiseOp>("Elementwise_Add", inputs, ops::ElementwiseOp::OpType::add);
return {op->getOutput(0)};
/// @brief Split arg into @p num_parts equal parts along @p axis axis.
std::vector<mir::IODescriptor>
CaffeOpCreator::createSplit(mir::IODescriptor arg, int32_t num_parts, int32_t axis) {
- const auto& arg_shape = arg.op->getOutputShape(arg.index);
+ const auto& arg_shape = arg.getShape();
assert(axis >= 0 && axis < arg_shape.rank());
int32_t part_size = arg_shape.dim(axis) / num_parts;
CaffeOpCreator::createFullyConnected(const mir::IODescriptor& input,
const mir::IODescriptor& weights,
int32_t axis) {
- const auto& input_shape = input.op->getOutputShape(input.index);
- const auto& weights_shape = weights.op->getOutputShape(weights.index);
+ const auto& input_shape = input.getShape();
+ const auto& weights_shape = weights.getShape();
assert(axis >= 0 && axis < input_shape.rank());
assert(weights_shape.rank() == 2);
Shape strides;
std::vector<int32_t> padding_before, padding_after;
- const auto& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& input_shape = inputs[0].getShape();
convertPoolingParam(opts, input_shape, window_shape, strides, padding_before, padding_after);
ops::PoolOp::PoolingType pool_type = getPoolingType(opts);
// CPP and ACL backends are able to perform Softmax only along the last axis.
// FIXME Do it in backends.
- if (inputs[0].op->getOutputShape(inputs[0].index).rank() == 4) {
+ if (inputs[0].getShape().rank() == 4) {
// For now, we only account for the most common case.
if (params.axis() != 1)
throw PassException("Softmax: unsupported axis");
auto cont = inputs[1];
assert(inputs.size() == 2);
- const auto& x_shape = x.op->getOutputShape(x.index);
+ const auto& x_shape = x.getShape();
const int32_t seq_length = x_shape.dim(0);
const int32_t batch_size = x_shape.dim(1);
const int32_t hidden_size = params.num_output();
vec[i] = pair;
}
auto result =
- createOp<ops::PadOp>(inputs[0], inputs[0].op->getOutputShape(0).rank(), vec, scalar);
+ createOp<ops::PadOp>(inputs[0], inputs[0].getShape().rank(), vec, scalar);
return {result->getOutput(0)};
}
pool_type = ops::PoolOp::PoolingType::AVG;
// GlobalAveragePool is equivalent to AveragePool with kernel size equal
// to the spatial dimension of input tensor
- cdata.kernel_shape = {t_input.op->getOutputShape(0).dim(1),
- t_input.op->getOutputShape(0).dim(2)};
- cdata.strides_shape = Shape{1, 1};
+ cdata.kernel_shape = {t_input.getShape().dim(1), t_input.getShape().dim(2)};
+ cdata.strides_shape = {1, 1};
break;
}
case ONNXOpCode::opAveragePool:
const onnx::NodeProto& onnx_node) {
auto* axes = findAttribute(onnx_node, "axes");
assert(axes && axes->ints_size());
- const Shape& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const Shape& input_shape = inputs[0].getShape();
const int out_rank = input_shape.rank() + axes->ints_size();
Shape out_shape(out_rank);
auto ints_iterator = axes->ints().begin();
auto* scales = dynamic_cast<mir::ops::ConstantOp*>(inputs[1].op);
assert(scales && "Weights could be a constant tensor only");
auto scales_tensor = Tensor<float>(scales->getValue());
- int rank = inputs[0].op->getOutputShape(0).rank();
+ int rank = inputs[0].getShape().rank();
assert(scales_tensor.getShape().numElements() == rank &&
"The number of elements of 'scales' should be the same as the rank of input 'X'"
);
float value;
std::tie(found, value) = getFloatAttribute(onnx_node, "scale");
float scale_val = found ? value : 1.0;
- const auto& shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& shape = inputs[0].getShape();
auto scale_tensor = createTensor(scale_val, shape);
auto scale = createOp<ops::ConstantOp>(scale_tensor)->getOutput(0);
auto result = createOp<ops::ScaleOp>(inputs[0], scale);
std::vector<IODescriptor>
ONNXOpCreator::convertShape(const std::vector<mir::IODescriptor>& inputs) {
- const auto& input_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& input_shape = inputs[0].getShape();
int size = input_shape.rank();
Shape output_shape{size};
std::vector<float> data(static_cast<std::size_t>(size));
- for (int i; i < size; i++) {
+ for (int i = 0; i < size; i++) {
data[i] = input_shape.dim(i);
}
TensorVariant tensor(DTYPE::FLOAT32, output_shape, data.data());
// 1. Prepare input matrix A
// Flatten the shape by dim(0)
- const auto& in_shape = inputs[0].op->getOutputShape(inputs[0].index);
+ const auto& in_shape = inputs[0].getShape();
mir::Shape shape0{in_shape.dim(0), in_shape.numElements() / in_shape.dim(0)};
- auto input_a = createOp<ops::ReshapeOp>(inputs[0], shape0);
+ auto input_a = createOp<ops::ReshapeOp>(inputs[0], shape0)->getOutput(0);
if (trans_a)
- input_a = createOp<ops::TransposeOp>(input_a->getOutput(0), std::vector<std::size_t>{1, 0});
+ input_a = createOp<ops::TransposeOp>(input_a, std::vector<std::size_t>{1, 0})->getOutput(0);
if (alpha_val != 1.0) {
- auto alpha_tensor = createTensor(alpha_val, input_a->getOutputShape(0));
+ auto alpha_tensor = createTensor(alpha_val, input_a.getShape());
auto alpha = createOp<ops::ConstantOp>(alpha_tensor)->getOutput(0);
- input_a = createOp<ops::ScaleOp>(input_a->getOutput(0), alpha);
+ input_a = createOp<ops::ScaleOp>(input_a, alpha)->getOutput(0);
}
// 2. Prepare input matrix B
if (trans_b)
input_b = createOp<ops::TransposeOp>(input_b, std::vector<std::size_t>{1, 0})->getOutput(0);
// Number of cols in tensor A must be equal to number of rows in tensor B
- assert(input_a->getOutput(0).op->getOutputShape(0).dim(1) ==
- input_b.op->getOutputShape(0).dim(0));
- Shape mult_a_b({input_a->getOutputShape(0).dim(0),
- input_b.op->getOutputShape(input_b.index).dim(1)});
+ assert(input_a.getShape().dim(1) == input_b.getShape().dim(0));
+ Shape mult_a_b{input_a.getShape().dim(0), input_b.getShape().dim(1)};
// 3. Prepare input matrix C
//
auto input_c = inputs[2];
- auto beta_tensor = createTensor(beta_val, input_c.op->getOutputShape(0));
+ auto beta_tensor = createTensor(beta_val, input_c.getShape());
// TODO: check 'broadcast' attribute here
- if ((mult_a_b.rank() == 2) && (input_c.op->getOutputShape(0).rank() == 1)) {
+ if ((mult_a_b.rank() == 2) && (input_c.getShape().rank() == 1)) {
beta_tensor = TensorVariant(beta_tensor, mult_a_b);
}
auto beta = createOp<ops::ConstantOp>(beta_tensor)->getOutput(0);
std::vector<IODescriptor> descriptors = {beta, input_c};
- auto c_mult = createOp<ops::ElementwiseOp>(descriptors, ops::ElementwiseOp::OpType::mul);
- assert(c_mult->getOutputShape(0) == mult_a_b);
- auto result = createOp<ops::GemmOp>(input_a->getOutput(0), input_b, c_mult->getOutput(0));
+ auto c_mult = createOp<ops::ElementwiseOp>(descriptors,
+ ops::ElementwiseOp::OpType::mul)->getOutput(0);
+ assert(c_mult.getShape() == mult_a_b);
+ auto result = createOp<ops::GemmOp>(input_a, input_b, c_mult);
return {result->getOutput(0)};
}