return op;
}
+ /**
+ * @brief Copies `old_op` with new inputs and registers it into graph.
+ */
+ Operation* copyOpWithInputs(Operation* old_op, const std::vector<Operation::Output*>& inputs) {
+ assert(inputs.size() == old_op->getNumInputs());
+ auto op = old_op->copyWithInputs(inputs);
+ op->setId(_lastNodeId++);
+ op->setName(old_op->getName());
+ registerOp(op);
+ return op;
+ }
+
void accept(IVisitor* visitor);
/**
Output* _producer;
};
-
virtual ~Operation() = default;
Type getType() const { return _type; }
void accept(IVisitor* v);
+ virtual Operation* copyWithInputs(const std::vector<Output*>& inputs) = 0;
+
protected:
Operation(Type type, const std::vector<Output*>& inputs, std::size_t num_outputs = 1);
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new BatchNormOp(inputs[0], _movingAvgFraction, _eps, _spatial);
+ }
+
/**
* @return The epsilon value to use to avoid division by zero.
*/
// Infer output shape.
setOutputShape(0, getInputShape(0));
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new BiasAddOp(inputs[0], inputs[1]);
+ }
};
} // namespace ops
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new CappedReluOp(inputs[0], _cap);
+ }
+
float getCap() const { return _cap; }
private:
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ConcatOp(inputs, _axis);
+ };
+
int32_t getAxis() const {
if (_axis < 0) {
// Negative axis is used to index starting from the last element of the shape
const TensorVariant& getValue() const { return _value; }
+ Operation* copyWithInputs(const std::vector<mir::Operation::Output*>& input) override {
+ assert(false && "Copying constants is not allowed!");
+ (void) input;
+ return nullptr;
+ }
+
private:
TensorVariant _value;
};
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new Conv2DOp(inputs[0], inputs[1], _strides, _paddingBefore, _paddingAfter);
+ };
+
const Shape& getStrides() const { return _strides; }
const std::vector<int32_t>& getPaddingBefore() const { return _paddingBefore; }
inferPaddings();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new DeConv2DOp(inputs[0], inputs[1], _strides, _paddingAfter);
+ };
+
const Shape& getStrides() const { return _strides; }
PaddingType getPaddingType() const { return _paddingType; }
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new DepthwiseConv2DOp(inputs[0], inputs[1], _strides, _paddingBefore, _paddingAfter);
+ }
+
const Shape& getStrides() const { return _strides; }
const std::vector<int32_t>& getPaddingBefore() const { return _paddingBefore; }
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new DropoutOp(inputs[0], _rate);
+ }
+
/**
* @return The ratio of random dropout
*/
inferOutputShapes();
};
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ElementwiseOp(inputs, _opType);
+ }
+
bool getBroadcast() const { return _needsBroadcast; }
private:
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new EluOp(inputs[0], _alpha);
+ }
+
float getAlpha() const { return _alpha; }
private:
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new FullyConnectedOp(inputs[0], inputs[1]);
+ }
+
private:
void inferOutputShapes();
};
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new GatherOp(inputs[0], inputs[1], _axis);
+ }
+
int32_t getAxis() const { return _axis; }
private:
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new GemmOp(inputs[0], inputs[1], inputs[2]);
+ }
+
private:
void inferOutputShapes();
};
explicit InputOp(const Shape& shape) : Operation(Type::input, {}) {
setOutputShape(0, shape);
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& input) override {
+ assert(false && "copying graph input is not allowed");
+ (void) input;
+ return nullptr;
+ }
};
} // namespace ops
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new LeakyReluOp(inputs[0], _alpha);
+ }
+
float getAlpha() const {
return _alpha;
}
class OutputOp : public Operation {
public:
explicit OutputOp(Output* input) : Operation(Type::output, {input}) {}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new OutputOp(inputs[0]);
+ }
};
} // namespace ops
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new PadOp(inputs[0], _numDims, _paddings, _scalarValue);
+ }
+
/**
* @param dim Dimension number
* @return Pair of paddings for dimension
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new PoolOp(inputs[0],_poolingType, _windowShape,_strides,
+ _paddingBefore,_paddingAfter, _borderType);
+ };
+
BorderType getBorderType() const { return _borderType; }
PoolingType getPoolingType() const { return _poolingType; }
setOutputShape(0, output_shape);
};
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ReduceFOp(inputs[0], _reduceDims, _keepDims, _funcType);
+ }
+
const std::vector<int32_t>& getReductionDims() { return _reduceDims; };
bool getKeepDims() const { return _keepDims; };
// Infer output shape.
setOutputShape(0, getInputShape(0));
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& arg) override {
+ return new ReluOp(arg[0]);
+ }
};
} // namespace ops
setOutputShape(0, output_shape);
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ReshapeOp(inputs[0], getOutputShape(0));
+ }
};
} // namespace ops
setOutputShape(0, output_shape);
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ResizeOp(inputs[0], _mode, getOutputShape(0));
+ }
+
ResizeOp(Output* arg, ResizeMethod mode, const Shape& output_shape)
: Operation(Type::resizeIm, {arg}), _mode(mode) {
// Calculate scales based on given shape.
// Infer output shape.
setOutputShape(0, getInputShape(0));
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new ScaleOp(inputs[0], inputs[1]);
+ }
};
} // namespace ops
// Infer output shape.
setOutputShape(0, getInputShape(0));
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new SigmoidOp(inputs[0]);
+ }
};
} // namespace ops
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new SliceOp(inputs[0], _starts, _sizes);
+ }
+
const Shape& getStarts() { return _starts; }
const Shape& getSizes() { return _sizes; }
setOutputShape(0, getInputShape(0));
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new SoftmaxOp(inputs[0], _axis);
+ }
+
int32_t getAxis() const {
if (_axis < 0) {
// Negative axis is used to index starting from the last element of the shape
explicit SqrtOp(Output* arg) : Operation(Type::sqrt, {arg}) {
setOutputShape(0, getInputShape(0));
};
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new SqrtOp(inputs[0]);
+ }
};
} // namespace ops
inferOutputShapes();
}
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new SqueezeOp(inputs[0], _dims_to_squeeze);
+ }
+
void inferOutputShapes();
int32_t getNumSqueezeDims() const { return static_cast<int32_t>(_dims_to_squeeze.size()); }
// Infer output shape.
setOutputShape(0, getInputShape(0));
}
+
+ Operation* copyWithInputs(const std::vector<Output*>& inputs) override {
+ return new TanhOp(inputs[0]);
+ }
};
} // namespace ops
const std::vector<std::size_t>& getAxisOrder() const { return _axisOrder; }
+ Operation* copyWithInputs(const std::vector<Output*>& arg) override {
+ return new TransposeOp(arg[0], _axisOrder);
+ }
+
private:
void inferOutputShapes();
{
TensorVariant::TensorVariant(DTYPE dtype, const Shape& shape)
- : _dtype(dtype), _shape(shape), _strides(shape.rank()) {
+ : _dtype(dtype), _strides(shape.rank()), _shape(shape) {
switch (dtype) {
case DTYPE::FLOAT32:
_elementSize = sizeof(float);