[nnc] Refactor nnc Shape and related classes (#1645)
authorEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Tue, 9 Oct 2018 11:15:55 +0000 (14:15 +0300)
committerРоман Михайлович Русяев/AI Tools Lab /SRR/Staff Engineer/삼성전자 <r.rusyaev@samsung.com>
Tue, 9 Oct 2018 11:15:55 +0000 (14:15 +0300)
Number of warnings minimized,
Replace unsigned ints with signed in Model IR
Move num_elements and AUTO_DIM into Shape class

Signed-off-by: Efimov Alexander <a.efimov@samsung.com>
50 files changed:
contrib/nnc/core/modelIR/Deserializer.cpp
contrib/nnc/core/modelIR/Index.cpp
contrib/nnc/core/modelIR/Serializer.cpp
contrib/nnc/core/modelIR/Shape.cpp
contrib/nnc/core/modelIR/ShapeInference.cpp
contrib/nnc/include/core/modelIR/ExternalRegion.h
contrib/nnc/include/core/modelIR/Index.h
contrib/nnc/include/core/modelIR/Region.h
contrib/nnc/include/core/modelIR/Shape.h
contrib/nnc/include/core/modelIR/ShapeInference.h
contrib/nnc/include/core/modelIR/ShapeRange.h
contrib/nnc/include/core/modelIR/TensorUtil.h
contrib/nnc/include/core/modelIR/TensorVariant.h
contrib/nnc/include/core/modelIR/operations/concat_op.h
contrib/nnc/include/core/modelIR/operations/conv_2d_op.h
contrib/nnc/include/core/modelIR/operations/depthwise_conv2d_op.h
contrib/nnc/include/core/modelIR/operations/pool_op.h
contrib/nnc/include/core/modelIR/operations/softmax_op.h
contrib/nnc/include/pass/PassException.h
contrib/nnc/include/passes/common_frontend/shape_helper.h
contrib/nnc/include/support/CommandLine.h
contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp
contrib/nnc/passes/common_frontend/shape_helper.cpp
contrib/nnc/passes/interpreter/interpreter_pass.cpp
contrib/nnc/passes/interpreter/ops/Concat.h
contrib/nnc/passes/interpreter/ops/Depthwise_conv_2D.cpp
contrib/nnc/passes/interpreter/ops/FullyConnected.h
contrib/nnc/passes/interpreter/ops/OperationImpl.h
contrib/nnc/passes/interpreter/ops/Pool.cpp
contrib/nnc/passes/interpreter/ops/Reduce.h
contrib/nnc/passes/interpreter/ops/Reshape.h
contrib/nnc/passes/interpreter/ops/Softmax.h
contrib/nnc/passes/interpreter/ops/common.cpp
contrib/nnc/passes/interpreter/ops/conv_2D.cpp
contrib/nnc/passes/interpreter/ops/conv_FFT.cpp
contrib/nnc/passes/soft_backend/SBSerializer.cpp
contrib/nnc/passes/soft_backend/code_snippets/cpp_operations.def
contrib/nnc/passes/tflite_frontend/tflite_dump_visitor.cpp
contrib/nnc/passes/tflite_frontend/tflite_ir_visitor.cpp
contrib/nnc/passes/tflite_frontend/tflite_ir_visitor.h
contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp
contrib/nnc/tests/interpreter/op_info_util.cpp
contrib/nnc/unittests/core/ShapeIndex.cpp [new file with mode: 0644]
contrib/nnc/unittests/core/ShapeInference.cpp
contrib/nnc/unittests/core/ShapeRange.cpp
contrib/nnc/unittests/core/deserializer.cpp
contrib/nnc/unittests/core/serializer.cpp
contrib/nnc/unittests/soft_backend/CPPOperations.cpp
contrib/nnc/unittests/soft_backend/Generator.cpp
contrib/nnc/unittests/support/CommandLineTest.cpp

index b91efef..2a99c90 100644 (file)
@@ -96,7 +96,7 @@ static TensorVariant deserializeFromMessage(const proto::TensorProto& object_as_
   default:
     throw std::logic_error("Deserializer<TensorVariant>: received unsupported data type");
   }
-  assert(raw_data_size / element_size == num_elements(shape));
+  assert(raw_data_size / element_size == static_cast<size_t>(shape.numElements()));
   std::shared_ptr<char> data(raw_data, std::default_delete<char[]>());
   return TensorVariant(shape, data, tv_dtype, element_size);
 }
index 6efb9dd..78f2ae2 100644 (file)
@@ -23,31 +23,31 @@ namespace nnc
 namespace mir
 {
 
-Index::Index(std::initializer_list<uint32_t> &&l) : _indices{l}
+Index::Index(std::initializer_list<int32_t> &&l) : _indices{l}
 {
   // DO NOTHING
 }
 
-uint32_t Index::rank(void) const { return _indices.size(); }
-Index &Index::resize(uint32_t size)
+int32_t Index::rank(void) const { return _indices.size(); }
+Index &Index::resize(int32_t size)
 {
   _indices.resize(size);
   return *this;
 }
 
-Index &Index::fill(uint32_t index)
+Index &Index::fill(int32_t index)
 {
   std::fill(_indices.begin(), _indices.end(), index);
   return (*this);
 }
 
-uint32_t &Index::at(uint32_t axis) { return _indices.at(axis); }
-uint32_t Index::at(uint32_t axis) const { return _indices.at(axis); }
+int32_t &Index::at(int32_t axis) { return _indices[(axis < 0) ? (_indices.size() + axis) : axis]; }
+int32_t Index::at(int32_t axis) const { return _indices[(axis < 0) ? (_indices.size() + axis) : axis]; }
 
 std::ostream &operator<<(std::ostream &s, const Index &sh)
 {
   s << "[ ";
-  for (uint32_t i = 0; i < sh.rank(); ++i)
+  for (int32_t i = 0; i < sh.rank(); ++i)
   {
     if (i != 0 )
       s << ", ";
index b61b95c..a7da433 100644 (file)
@@ -36,8 +36,8 @@ std::string Serializer<Shape>::getSerializedObject (const Shape& shape)
 {
   proto::TensorShapeProto shapeProto;
 
-  uint32_t rank = shape.rank();
-  for (uint32_t i = 0; i < rank; i++) {
+  int32_t rank = shape.rank();
+  for (int32_t i = 0; i < rank; i++) {
     shapeProto.add_dims(shape.dim(i));
   }
 
@@ -58,7 +58,7 @@ static proto::TensorProto serializeTensorContent(const Tensor<T>& tensor)
 
   tp.set_dtype(dtype);
 
-  size_t data_size = num_elements(tensor.getShape());
+  size_t data_size = tensor.getShape().numElements();
   auto tensor_data = new T[data_size];
   size_t i = 0;
   ShapeRange shapeRange(tensor.getShape());
index fdac281..8867e6b 100644 (file)
 #include "core/modelIR/Shape.h"
 
 #include <algorithm>
+#include <cassert>
 
 namespace nnc
 {
 namespace mir
 {
 
-Shape::Shape(std::initializer_list<uint32_t> &&l) : _dims{l}
+Shape::Shape(std::initializer_list<int32_t> &&l) : _dims{l}
 {
   // DO NOTHING
 }
 
-uint32_t Shape::rank(void) const { return _dims.size(); }
-Shape &Shape::resize(uint32_t size)
+int32_t Shape::rank() const { return _dims.size(); }
+Shape &Shape::resize(int32_t size)
 {
   _dims.resize(size);
   return *this;
 }
 
-uint32_t &Shape::dim(uint32_t axis) { return _dims.at(axis); }
-uint32_t Shape::dim(uint32_t axis) const { return _dims.at(axis); }
+int32_t &Shape::dim(int32_t axis)
+{
+  return _dims.at((axis < 0) ? (_dims.size() + axis) : axis);
+}
 
-Shape &Shape::squeeze(void)
+int32_t Shape::dim(int32_t axis) const
 {
-  _dims.erase(std::remove(_dims.begin(), _dims.end(), 1), _dims.end());
-  return *this;
+  return _dims.at((axis < 0) ? (_dims.size() + axis) : axis);
 }
 
-uint64_t num_elements(const Shape &shape)
+int32_t Shape::numElements() const
 {
-  if (shape.rank() == 0)
+  if (rank() == 0)
   {
     return 0;
   }
 
-  uint64_t res = 1;
+  int32_t res = 1;
 
-  for (uint32_t axis = 0; axis < shape.rank(); ++axis)
+  for (int32_t axis = 0; axis < rank(); ++axis)
   {
-    res *= shape.dim(axis);
+    assert(dim(axis) != Shape::AUTO_DIM);
+    res *= dim(axis);
   }
 
   return res;
 }
 
-Shape squeeze(const Shape &shape)
-{
-  Shape res{shape};
-  res.squeeze();
-  return res;
-}
-
-bool operator==(const Shape &lhs, const Shape &rhs)
+bool Shape::equal(const Shape &rhs) const
 {
-  if (lhs.rank() != rhs.rank())
+  if (rank() != rhs.rank())
   {
     return false;
   }
 
-  for (uint32_t axis = 0; axis < lhs.rank(); ++axis)
+  int32_t r = rank();
+  for (int32_t axis = 0; axis < r; ++axis)
   {
-    if (lhs.dim(axis) != rhs.dim(axis))
+    if (dim(axis) != rhs.dim(axis))
     {
       return false;
     }
@@ -88,14 +85,17 @@ bool operator==(const Shape &lhs, const Shape &rhs)
 
 std::ostream &operator<<(std::ostream &s, const Shape &sh)
 {
-  uint32_t rank = sh.rank();
+  int32_t rank = sh.rank();
   s << "[";
 
-  for (uint32_t axis = 0; axis < rank; ++axis)
+  for (int32_t axis = 0; axis < rank; ++axis)
   {
     if (axis != 0)
       s << ", ";
-    s << sh.dim(axis);
+    if (sh.dim(axis) == Shape::AUTO_DIM)
+      s << "AUTO";
+    else
+      s << sh.dim(axis);
   }
   s << "]";
   return s;
index a3e29ae..ef6add9 100644 (file)
@@ -52,7 +52,7 @@ void fillHWShapesForPaddedOperations(Op &op, const Shape &windowShape, Shape &ou
   switch (pType)
   {
   case ops::PaddingType::Same:
-    for (uint32_t d = 0; d < inRank - 1; ++d)
+    for (int32_t d = 0; d < inRank - 1; ++d)
     {
       outShape.dim(d) = (inShape.dim(d) - 1) / strides.dim(d) + 1;
       int pad_along_axis;
@@ -70,13 +70,13 @@ void fillHWShapesForPaddedOperations(Op &op, const Shape &windowShape, Shape &ou
     }
     break;
   case ops::PaddingType::Valid:
-    for (uint32_t d = 0; d < inRank - 1; ++d)
+    for (int32_t d = 0; d < inRank - 1; ++d)
     {
       op.setPadding(d, 0);
     }
     // FALLTHROUGH
   case ops::PaddingType::Custom:
-    for (uint32_t d = 0; d < inRank - 1; ++d)
+    for (int32_t d = 0; d < inRank - 1; ++d)
     {
       outShape.dim(d) = (inShape.dim(d) + 2*op.getPadding(d) - windowShape.dim(d)) / strides.dim(d) + 1;
     }
@@ -93,17 +93,17 @@ void ShapeInference::visit(INode::Ref node, ops::ConcatOp &op)
 {
   fillInputShapes(node, op);
 
-  uint32_t axis = op.getAxis();
+  int32_t axis = op.getAxis();
   Shape outShape;
   outShape.resize(op.getInputShape(0).rank());
 
-  for (uint32_t d = 0; d < outShape.rank(); ++d)
+  for (int32_t d = 0; d < outShape.rank(); ++d)
   {
     outShape.dim(d) = op.getInputShape(0).dim(d);
   }
   outShape.dim(axis) = 0;
 
-  for (uint32_t i = 0; i < op.getNumInputs(); ++i)
+  for (size_t i = 0; i < op.getNumInputs(); ++i)
   {
     outShape.dim(axis) += op.getInputShape(i).dim(axis);
   }
@@ -134,7 +134,7 @@ void ShapeInference::visit(INode::Ref node, ops::VariableOp &op)
 
 void ShapeInference::fillInputShapes(INode::Ref node, OpDescription &op)
 {
-  uint32_t i = 0;
+  size_t i = 0;
   for (auto &in : node->getPrevNodes())
   {
     const Shape &inShape = in.node->getOperation()->getOutputShape(in.index);
@@ -161,7 +161,7 @@ void ShapeInference::visit(INode::Ref node, ops::PoolOp &op)
   Shape outShape;
   auto &windowShape = op.getWindowShape();
   auto &inShape = op.getInputShape(0);
-  const uint32_t inRank = inShape.rank();
+  const int32_t inRank = inShape.rank();
   // Assuming input tensor is 3-dimensional. Will support more general cases when needed.
   assert(inRank == 3);
 
@@ -176,13 +176,14 @@ void ShapeInference::visit(INode::Ref node, ops::FullyConnectedOp &op)
   fillInputShapes(node, op);
   const Shape &inShape = op.getInputShape(0);
   const Shape &wShape = op.getWeights().getShape();
-  const uint32_t weightsRank = wShape.rank();
-  const uint32_t inRank = inShape.rank();
+  const int32_t weightsRank = wShape.rank();
+  const int32_t inRank = inShape.rank();
 
   assert(weightsRank >= 2);
   assert(inRank == weightsRank);
   assert(inShape.dim(inRank - 1) == wShape.dim(weightsRank - 2));
-  for (uint32_t i = 0; i < weightsRank - 2; ++i)
+  (void)inRank;
+  for (int32_t i = 0; i < weightsRank - 2; ++i)
   {
     assert(wShape.dim(i) == inShape.dim(i));
   }
@@ -232,20 +233,20 @@ void ShapeInference::visit(INode::Ref node, ops::ReshapeOp &op)
   auto& inShape = op.getInputShape(0);
   auto outShape = op.getOutputShape(0);
 
-  auto inElementsNum = num_elements(inShape);
-  uint32_t outElementsNum = 1;
+  auto inElementsNum = inShape.numElements();
+  int32_t outElementsNum = 1;
   //can't use num_elements due to -1 in input shape and Shape using unsigned ints for dimensions
-  for( uint32_t d = 0; d < outShape.rank(); ++d ) {
+  for( int32_t d = 0; d < outShape.rank(); ++d ) {
     auto dim = outShape.dim(d);
-    if( dim != AUTO_DIM) {
+    if( dim != Shape::AUTO_DIM) {
       outElementsNum *= dim;
     }
   }
 
-  for( uint32_t d = 0; d < outShape.rank(); ++d ) {
+  for( int32_t d = 0; d < outShape.rank(); ++d ) {
     auto& dim = outShape.dim(d);
-    if( dim ==  AUTO_DIM ) {
-      dim = static_cast<uint32_t>(inElementsNum / outElementsNum);
+    if( dim == Shape::AUTO_DIM ) {
+      dim = static_cast<int32_t>(inElementsNum / outElementsNum);
     }
   }
 
index a5d94ec..f0c2252 100644 (file)
@@ -27,18 +27,18 @@ namespace mir
 template <typename T> class ExternalRegion final : public Region<T>
 {
 public:
-  ExternalRegion(T *base, uint32_t size) : _base{base}, _size{size}
+  ExternalRegion(T *base, int32_t size) : _base{base}, _size{size}
   {
     // DO NOTHING
   }
 
 public:
-  T *base(void) override { return _base; }
-  uint32_t size(void) const override { return _size; }
+  T *base() override { return _base; }
+  int32_t size() const override { return _size; }
 
 private:
   T *const _base;
-  uint32_t const _size;
+  int32_t const _size;
 };
 
 } // namespace mir
index 4319858..cf39585 100644 (file)
@@ -31,23 +31,19 @@ class Index
 {
 public:
   Index() = default;
-  Index(std::initializer_list<uint32_t> &&l);
+  Index(std::initializer_list<int32_t> &&l);
 
-public:
-  uint32_t rank(void) const;
+  int32_t rank(void) const;
 
-public:
-  Index &resize(uint32_t size);
+  Index &resize(int32_t size);
 
-public:
-  Index &fill(uint32_t index);
+  Index &fill(int32_t index);
 
-public:
-  uint32_t &at(uint32_t axis);
-  uint32_t at(uint32_t axis) const;
+  int32_t &at(int32_t axis);
+  int32_t at(int32_t axis) const;
 
 private:
-  std::vector<uint32_t> _indices;
+  std::vector<int32_t> _indices;
 };
 
 std::ostream &operator<<(std::ostream &s, const Index &sh);
index 96978bc..af3fd43 100644 (file)
@@ -18,6 +18,7 @@
 #define _NNC_CORE_LINALG_REGION_H_
 
 #include <cstdint>
+#include "Shape.h"
 
 namespace nnc
 {
@@ -29,9 +30,9 @@ struct Region
 {
   virtual ~Region() = default;
 
-  virtual T *base(void) = 0;
+  virtual T *base() = 0;
 
-  virtual uint32_t size(void) const = 0;
+  virtual int32_t size() const = 0;
 };
 
 } // namespace mir
index 5839e78..fe40b3c 100644 (file)
@@ -30,31 +30,37 @@ namespace mir
 class Shape
 {
 public:
+  static const auto AUTO_DIM = static_cast<int32_t>(-1);
+
   Shape() = default;
-  Shape(std::initializer_list<uint32_t> &&l);
+  Shape(std::initializer_list<int32_t> &&l);
 
-public:
-  uint32_t rank(void) const;
+  int32_t rank() const;
 
-public:
-  Shape &resize(uint32_t size);
+  Shape &resize(int32_t size);
 
-public:
-  uint32_t &dim(uint32_t axis);
-  uint32_t dim(uint32_t axis) const;
+  int32_t &dim(int32_t axis);
+  int32_t dim(int32_t axis) const;
 
-public:
-  Shape &squeeze(void);
+  int32_t numElements() const;
+
+  bool operator==(const Shape& rhs) const
+  {
+    return equal(rhs);
+  }
+
+  bool operator!=(const Shape& rhs) const
+  {
+    return !equal(rhs);
+  }
 
 private:
-  std::vector<uint32_t> _dims;
-};
 
-uint64_t num_elements(const Shape &);
+  bool equal(const Shape& rhs) const;
 
-Shape squeeze(const Shape &);
+  std::vector<int32_t> _dims;
+};
 
-bool operator==(const Shape &, const Shape &);
 std::ostream &operator<<(std::ostream &s, const Shape &sh);
 
 } // namespace mir
index 7e37f07..e50752c 100644 (file)
@@ -28,8 +28,6 @@ namespace mir
 
 class ShapeInference : public IVisitor {
  public:
-  static const auto AUTO_DIM = std::numeric_limits<uint32_t>::max();
-
   void visit(INode::Ref node, ops::ConcatOp &op) override;
   void visit(INode::Ref node, ops::Conv2DOp &op) override;
   void visit(INode::Ref node, ops::DepthwiseConv2DOp &op) override;
index 882fb25..fb7f05e 100644 (file)
@@ -33,8 +33,8 @@ class ShapeIter :
   ShapeIter& operator++() {
     auto* pidx = &_index.at(0);
     auto* pshape = &_shape.dim(0);
-    auto rank = _shape.rank();
-    int c = rank - 1;
+    int32_t rank = _shape.rank();
+    int32_t c = rank - 1;
     pidx[c]++;
     while( (pidx[c] > pshape[c] - 1) && (c > 0) ) {
       pidx[c] = 0;
@@ -61,12 +61,12 @@ class ShapeIter :
   }
 
  private:
-  explicit ShapeIter(Shape &_shape, uint32_t pos) : _pos(pos), _shape(_shape) {
+  explicit ShapeIter(Shape &_shape, int32_t pos) : _pos(pos), _shape(_shape) {
     _index.resize(_shape.rank());
     _index.fill(0);
   }
 
-  uint32_t _pos;
+  int32_t _pos;
   Index _index;
   Shape& _shape;
 
@@ -83,18 +83,16 @@ class ShapeRange {
   }
 
   ShapeIter end() {
-    uint32_t _end = 1;
-    for( uint32_t d = 0; d < _shape.rank(); ++d ) _end *= _shape.dim(d);
-    return ShapeIter(_shape, _end);
+    return ShapeIter(_shape, _shape.numElements());
   }
 
   bool contains(const Index& idx) {
     assert(idx.rank() == _shape.rank());
-    bool res = true;
-    for(uint32_t d = 0; d < idx.rank(); ++d ) {
-      res &= idx.at(d) < _shape.dim(d);
+    for(int32_t d = 0; d < idx.rank(); ++d ) {
+      if ((idx.at(d) >= _shape.dim(d)) || (idx.at(d) < 0))
+        return false;
     }
-    return res;
+    return true;
   }
 
  private:
index 0037229..14d7831 100644 (file)
@@ -37,7 +37,7 @@ transposeTensor(std::shared_ptr <TensorVariant> tensor)
   const Shape &inShape = tensor->getShape();
   Shape targetShape{inShape.dim(Ints)...};
 
-  uint64_t size = num_elements(targetShape);
+  auto size = targetShape.numElements();
 
   std::shared_ptr<char> convertedTensorData(new char[size * tensor->getElementSize()],
                                             [](char *d) { delete[] d; });
index 3c6d510..b53431c 100644 (file)
@@ -62,7 +62,7 @@ public:
  private:
   DTYPE _dtype;
   std::shared_ptr<char> _data;
-  uint_fast32_t _strides[MAX_DIMENSIONS];
+  int_fast32_t _strides[MAX_DIMENSIONS];
   size_t _rank;
   Shape _shape;
 
index 22b3ab5..3ad4c55 100644 (file)
 #ifndef _NNC_CORE_IR_MODEL_CONCAT_OP_H_
 #define _NNC_CORE_IR_MODEL_CONCAT_OP_H_
 
+#include <limits>
+
 #include "core/modelIR/operations/operation.h"
+#include "core/modelIR/Shape.h"
 
 namespace nnc
 {
@@ -26,18 +29,21 @@ namespace mir
 namespace ops
 {
 
+/**
+ * @brief Description of tensor concatenation operation.
+ */
 class ConcatOp : public OpDescription
 {
 public:
-  ConcatOp(int num_inputs, int axis) : OpDescription(num_inputs, 1), _axis(axis) {}
+  ConcatOp(int num_inputs, int32_t axis) : OpDescription(num_inputs, 1), _axis(axis) {}
 
-  unsigned int getAxis() const
+  int32_t getAxis() const
   {
     if (_axis < 0)
     {
       // Negative axis is used to index starting from the last element of the shape
       // -1 means last element, -2 means second from end, like in python
-      int res = _axis + getInputShape(0).rank();
+      int32_t res = _axis + getInputShape(0).rank();
       assert(res >= 0);
       return res;
     }
@@ -45,7 +51,8 @@ public:
   }
 
 private:
-  int _axis;
+  /// @brief The axis along which to concatenate, may be negative to index from the end
+  int32_t _axis;
 };
 
 } // namespace ops
index c80c718..b99de46 100644 (file)
@@ -48,15 +48,15 @@ public:
 
   PaddingType getPaddingType() const { return _padding; }
 
-  int getPadding(int dim) const { return _pads[dim]; }
+  int32_t getPadding(int32_t dim) const { return _pads[dim]; }
 
-  void setPadding(int dim, int pad) { _pads[dim] = pad; }
+  void setPadding(int32_t dim, int32_t pad) { _pads[dim] = pad; }
 
 private:
   const TensorVariant _kernel;
   Shape _strides;
   PaddingType _padding;
-  std::vector<int> _pads;
+  std::vector<int32_t> _pads;
 };
 
 } // namespace ops
index 2c63cf5..04d00d3 100644 (file)
@@ -47,15 +47,15 @@ public:
 
   PaddingType getPaddingType() const { return _padding; }
 
-  int getPadding(int dim) const { return _pads[dim]; }
+  int32_t getPadding(int32_t dim) const { return _pads[dim]; }
 
-  void setPadding(int dim, int pad) { _pads[dim] = pad; }
+  void setPadding(int32_t dim, int32_t pad) { _pads[dim] = pad; }
 
 private:
   const TensorVariant _kernel;
   Shape _strides;
   PaddingType _padding;
-  std::vector<int> _pads;
+  std::vector<int32_t> _pads;
 };
 
 } // namespace ops
index adc0d53..8dda6cb 100644 (file)
@@ -65,9 +65,9 @@ public:
 
   const Shape &getStrides() const { return _strides; }
 
-  int getPadding(int dim) const { return _pads[dim]; }
+  int32_t getPadding(int32_t dim) const { return _pads[dim]; }
 
-  void setPadding(int dim, int pad) { _pads[dim] = pad; }
+  void setPadding(int32_t dim, int32_t pad) { _pads[dim] = pad; }
 
 private:
   PaddingType _padding;
@@ -75,7 +75,7 @@ private:
   BorderType _borderType;
   Shape _windowShape;
   Shape _strides;
-  std::vector<int> _pads;
+  std::vector<int32_t> _pads;
 };
 
 } // namespace ops
index 9334692..934e445 100644 (file)
@@ -18,6 +18,7 @@
 #define _NNC_CORE_IR_MODEL_SOFTMAX_H_
 
 #include "core/modelIR/operations/operation.h"
+#include "core/modelIR/Shape.h"
 
 namespace nnc
 {
@@ -26,18 +27,21 @@ namespace mir
 namespace ops
 {
 
+/**
+ * @brief description of softmax operation.
+ */
 class SoftmaxOp : public OpDescription
 {
 public:
-  explicit SoftmaxOp(int axis) : OpDescription(1, 1), _axis(axis) {}
+  explicit SoftmaxOp(int32_t axis) : OpDescription(1, 1), _axis(axis) {}
 
-  int getAxis() const
+  int32_t getAxis() const
   {
     if (_axis < 0)
     {
       // Negative axis is used to index starting from the last element of the shape
       // -1 means last element, -2 means second from end, like in python
-      int res = _axis + getInputShape(0).rank();
+      int32_t res = _axis + getInputShape(0).rank();
       assert(res >= 0);
       return res;
     }
@@ -45,7 +49,8 @@ public:
   }
 
 private:
-  int _axis;
+  /// @brief The axis along which to concatenate, may be negative to index from the end
+  int32_t _axis;
 };
 
 } // namespace ops
index 4c56083..54a99ab 100644 (file)
@@ -30,10 +30,10 @@ class PassException : public std::exception
 {
 public:
   PassException() = default;
-  PassException(const PassException &) noexcept {};
+  PassException(const PassException &) = default;
 
-  PassException(const std::string &msg) : _msg(msg) {};
-  PassException(const char *msg) : _msg(msg) {};
+  explicit PassException(const std::string &msg) : _msg(msg) {};
+  explicit PassException(const char *msg) : _msg(msg) {};
 
   /**
    * @brief get message describes reason why exception was thrown
index 8250ee0..e7d6f84 100644 (file)
@@ -35,7 +35,7 @@ template<typename Iterable>
 mir::Shape ShapeHelper::createShape(const Iterable &iter, std::size_t size)
 {
   mir::Shape sh;
-  sh.resize(static_cast<uint32_t>(size));
+  sh.resize(static_cast<int32_t>(size));
 
   unsigned int i = 0;
   for (auto dim : iter)
index 9672501..45a233c 100644 (file)
@@ -493,11 +493,13 @@ Option<T>::Option(const std::vector<std::string> &optnames,
 
   this->setRawValue(default_val);
 
+#ifndef NDEBUG
   // check that separators are valid symbols
   for ( const auto &s : _seps )
   {
     assert((s == '=' || s == ':') && "invalid option separators");
   }
+#endif // NDEBUG
 
   // save checker
   _checker = checker;
index 2bba6d2..a5ee162 100644 (file)
@@ -58,11 +58,11 @@ static inline bool has2DStride(const OptsType& opts)
   return opts.has_stride_h();
 }
 
-static inline Shape getStrideFromOneValue(bool hasStride, unsigned int stride)
+static inline Shape getStrideFromOneValue(bool hasStride, uint32_t stride)
 {
   if (hasStride)
   {
-    return Shape{stride, stride, 1};
+    return Shape{static_cast<int32_t>(stride), static_cast<int32_t>(stride), 1};
   }
   else
   {
@@ -70,9 +70,9 @@ static inline Shape getStrideFromOneValue(bool hasStride, unsigned int stride)
   }
 }
 
-static inline Shape getStrideFromTwoValues(unsigned int stride1, unsigned int stride2)
+static inline Shape getStrideFromTwoValues(uint32_t stride1, uint32_t stride2)
 {
-  return Shape{stride1, stride2, 1};
+  return Shape{static_cast<int32_t>(stride1), static_cast<int32_t>(stride2), 1};
 }
 
 template <typename OptsType>
@@ -124,11 +124,11 @@ __attribute__ ((unused)) static Shape getPoolWindowShape(const PoolingParameter
 
   if (opts.has_kernel_h())
   {
-    return Shape{opts.kernel_h(), opts.kernel_w(), 1};
+    return Shape{static_cast<int32_t>(opts.kernel_h()), static_cast<int32_t>(opts.kernel_w()), 1};
   }
   else if (opts.has_kernel_size())
   {
-    return Shape{opts.kernel_size(), opts.kernel_size(), 1};
+    return Shape{static_cast<int32_t>(opts.kernel_size()), static_cast<int32_t>(opts.kernel_size()), 1};
   }
   else
   {
@@ -207,7 +207,7 @@ static std::shared_ptr<IrTensor> fixGroupedKernel(int groups, std::shared_ptr<Ir
   // here creates unfolded kernel with shape [H, W, inputChannels, outputChannels]
   Shape unfoldKernelShape(kernelShape);
   unfoldKernelShape.dim(kernelInChanNum) = inChannels;
-  auto bufferSize = num_elements(unfoldKernelShape) * foldedKernel->getElementSize();
+  auto bufferSize = unfoldKernelShape.numElements() * foldedKernel->getElementSize();
   std::shared_ptr<char> buffer(new char[bufferSize], std::default_delete<char[]>());
   size_t dataSize = foldedKernel->getElementSize();
   std::shared_ptr<IrTensor> unfoldKernel =
@@ -314,8 +314,8 @@ std::vector<INode::Ref> OpCreator::createFullyConnected(InputOps &inputs, InputP
   // Add Reshape operation to make sure the input for FC operation has shape [1, fcInputSize]
   // It is needed because Caffe InnerProduct layer takes NCHW input and flattens the CHW part.
   auto outputs = createOp<ops::ReshapeOp>(inputs);
-  uint32_t fcInputSize = static_cast<uint32_t>(
-                                 num_elements(params[0]->getShape())) / opts.num_output();
+  int32_t fcInputSize = static_cast<int32_t>(
+                                 params[0]->getShape().numElements()) / opts.num_output();
   outputs[0]->getOperation()->setOutputShape(0, {1, fcInputSize});
 
   auto fcOutputs = createOp<ops::FullyConnectedOp>(outputs, std::move(*params[0]));
@@ -415,7 +415,7 @@ std::vector<INode::Ref> OpCreator::createReshape(InputOps inputs, InputParams pa
 
   Shape newShape = ShapeHelper::createShape(opts.shape().dim(), opts.shape().dim_size());
 
-  for (unsigned int i = 0; i < newShape.rank(); ++i)
+  for (int32_t i = 0; i < newShape.rank(); ++i)
   {
     if (newShape.dim(i) == 0)
       throw PassException("Reshape layer zero shape values are not supported yet");
index d3d2c25..69605ff 100644 (file)
@@ -33,7 +33,7 @@ mir::Shape &ShapeHelper::cutOffBatchDim(mir::Shape &shape)
                         "code needs some restructuring"};
   }
 
-  for (unsigned int i = 0; i < shape.rank() - 1; ++i)
+  for (int32_t i = 0; i < shape.rank() - 1; ++i)
   {
     shape.dim(i) = shape.dim(i + 1);
   }
index b2cf753..358c112 100644 (file)
@@ -64,10 +64,10 @@ static void writeTensorToHDF5File(TensorVariant *tensor, std::string tensorName,
 {
   // Prepare shape, rank, dims, numElems
   Shape shape = tensor->getShape();
-  const auto rank = shape.rank();
+  const int32_t rank = shape.rank();
   hsize_t dims[rank];
-  uint64_t numElems = 1;
-  for (uint32_t axis = 0; axis < rank; ++axis) {
+  size_t numElems = 1;
+  for (int32_t axis = 0; axis < rank; ++axis) {
     dims[axis] = shape.dim(axis);
     numElems *= shape.dim(axis);
   }
@@ -153,8 +153,8 @@ TensorVariant InterpreterPass::loadInput(const Shape &shape)
 
   int is_error = fseek(f, 0L, SEEK_END);
   assert(!is_error);
-  auto len = ftell(f);
-  auto tensorSize = num_elements(shape) * sizeof(float);
+  auto len = static_cast<int64_t>(ftell(f));
+  auto tensorSize = static_cast<int64_t>(shape.numElements() * sizeof(float));
 
   // Check size
   if (len != tensorSize) {
@@ -167,6 +167,7 @@ TensorVariant InterpreterPass::loadInput(const Shape &shape)
   auto data = new char[len];
   auto rlen = fread(data, len, 1, f);
   assert(rlen == 1);
+  (void)rlen;
   is_error = fclose(f);
   assert(is_error != EOF &&  "Can not close file!");
   (void)is_error;
index 518b040..998d363 100644 (file)
@@ -26,14 +26,14 @@ template <typename T> class Concat : public Fill<T>
 {
 public:
   explicit Concat(const std::vector<mir::TensorVariant> &inputs, const mir::Shape &outputShape,
-                  unsigned int axis)
+                  int32_t axis)
       : Fill<T>(outputShape, getSingleFunction(inputs, axis))
   {
   }
 
 private:
   const std::function<T(const mir::Index &)> getSingleFunction(const std::vector<mir::TensorVariant> &inputs,
-                                                          unsigned int axis)
+                                                               int32_t axis)
   {
     std::vector<mir::Tensor<T>> inputAccessors;
     for (auto &in : inputs)
@@ -43,7 +43,7 @@ private:
 
     return std::function<T(const mir::Index &)>([inputAccessors, axis](const mir::Index &id) -> T {
       unsigned int mi = 0;
-      uint32_t along_axis = id.at(axis);
+      int32_t along_axis = id.at(axis);
 
       while (along_axis >= inputAccessors.at(mi).getShape().dim(axis))
       {
index cb77bff..a712fae 100644 (file)
@@ -31,7 +31,7 @@ std::vector<TensorVariant> DepthwiseConv2D::operator()()
   Tensor<float> resAccessor(res);
 
   Shape strides({_strides.dim(0), _strides.dim(1), _strides.dim(2)});
-  Index pads({(uint32_t)_op.getPadding(0), (uint32_t)_op.getPadding(1), 0u});
+  Index pads({_op.getPadding(0), _op.getPadding(1), 0u});
 
   Shape outShape = res.getShape();
   outShape.dim(2) = 1;
@@ -43,7 +43,7 @@ std::vector<TensorVariant> DepthwiseConv2D::operator()()
   inIdx.resize(outShape.rank());
 
   auto kernelShape = _kernel.getShape();
-  uint32_t channelMultiplierDim = kernelShape.rank() - 1;
+  int32_t channelMultiplierDim = kernelShape.rank() - 1;
   int channelMultiplier = kernelShape.dim(channelMultiplierDim);
 
   for (auto &outIdx : outRange)
index 2cf882e..0ff905e 100644 (file)
@@ -39,24 +39,25 @@ public:
 
     mir::Tensor<T> weights(_op.getWeights());
     const mir::Shape &wShape = weights.getShape();
-    uint32_t wRank = wShape.rank();
+    int32_t wRank = wShape.rank();
 
     const mir::Shape &inShape = _input.getShape();
-    uint32_t inRank = inShape.rank();
+    int32_t inRank = inShape.rank();
 
     assert(inShape.dim(inRank - 1) == wShape.dim(wRank - 2));
+    (void)inRank;
 
-    const uint32_t len = wShape.dim(wRank - 2);
+    const auto len = wShape.dim(wRank - 2);
 
-    uint32_t row;
-    uint32_t col;
+    int32_t row;
+    int32_t col;
     for (auto &outIdx : outRange)
     {
       mir::Index tIdx = outIdx;
       T& outputElement = accessor.at(outIdx);
       col = tIdx.at(wRank - 1);
       row = tIdx.at(wRank - 2);
-      for (uint32_t i = 0u; i < len; ++i)
+      for (int32_t i = 0; i < len; ++i)
       {
         tIdx.at(wRank - 1) = i;
         const T& in = _input.at(tIdx);
index 9ab4753..bf91d2f 100644 (file)
@@ -36,7 +36,7 @@ protected:
   mir::TensorVariant allocate_tensor(const mir::Shape &shape)
   {
     size_t data_size = 1;
-    for (uint32_t i = 0; i < shape.rank(); ++i)
+    for (int32_t i = 0; i < shape.rank(); ++i)
     {
       data_size *= shape.dim(i);
     }
index 35fa789..7e2adee 100644 (file)
@@ -39,14 +39,14 @@ std::vector<TensorVariant> Pool::operator()()
   Tensor<float> resAccessor(res);
 
   Shape strides({_op.getStrides().dim(0), _op.getStrides().dim(1), 1u});
-  Index pads({(uint32_t)_op.getPadding(0), (uint32_t)_op.getPadding(1), 0u});
+  Index pads({_op.getPadding(0), _op.getPadding(1), 0u});
 
   const Shape &outShape = resAccessor.getShape();
   ShapeRange outRange(outShape);
 
   ShapeRange inRange(_input.getShape());
 
-  float initialValue;
+  float initialValue = 0.0f;
   switch (_op.getPoolingType())
   {
     case PoolOp::PoolingType::MAX:
@@ -69,7 +69,7 @@ std::vector<TensorVariant> Pool::operator()()
     {
       translate(inIdx, outIdx, kIdx, strides, pads);
 
-      float in;
+      float in = 0.0f;
       if(inRange.contains(inIdx)) {
         avgDenominator++;
         in = _input.at(inIdx);
@@ -110,7 +110,12 @@ float Pool::poolingFunc(float prev, float val)
     return prev + val;
   case PoolOp::PoolingType::MIN:
     return (val < prev) ? val : prev;
+  default:
+    assert(false && "Unsupported pooling type");
   }
+  // This should not happen
+  // Should throw, but it is too expensive
+  return 0.0f;
 }
 
 } // namespace nnc
index 18900de..d5485f9 100644 (file)
@@ -32,7 +32,7 @@ namespace nnc
 template <typename T> class Reduce : public OperationImpl<T>
 {
 public:
-  Reduce(const mir::Shape &inputShape, const mir::Shape &outputShape, const mir::TensorVariant &input, uint32_t axis,
+  Reduce(const mir::Shape &inputShape, const mir::Shape &outputShape, const mir::TensorVariant &input, int32_t axis,
          std::function<T(const T &, const T &)> reduceFunc)
       : _inShape(inputShape), _outputShape(outputShape), _input(input), _axis(axis),
         _reduceFunc(reduceFunc)
@@ -45,8 +45,8 @@ public:
     return Fill<T>(_outputShape, [this](const mir::Index &id) {
       T element = T();
       mir::Index inputId = id;
-      uint32_t end = _inShape.dim(_axis);
-      for (uint32_t i = 0; i < end; ++i)
+      int32_t end = _inShape.dim(_axis);
+      for (int32_t i = 0; i < end; ++i)
       {
         inputId.at(_axis) = i;
         element = _reduceFunc(element, _input.at(inputId));
@@ -59,7 +59,7 @@ private:
   const mir::Shape &_inShape;
   const mir::Shape &_outputShape;
   const mir::Tensor<T> _input;
-  const uint32_t _axis;
+  const int32_t _axis;
   const std::function<T(T, T)> _reduceFunc;
 };
 
index bba1d8a..87515f8 100644 (file)
@@ -30,7 +30,7 @@ template <typename T> class Reshape : public OperationImpl<T>
 public:
   Reshape(const mir::TensorVariant &input, const mir::ops::ReshapeOp &op) : _input(input), _op(op)
   {
-    assert(num_elements(_op.getInputShape(0)) == num_elements(_op.getOutputShape(0)));
+    assert(_op.getInputShape(0).numElements() == _op.getOutputShape(0).numElements());
   }
 
   std::vector<mir::TensorVariant> operator()() override
index 0a52d6d..42545e0 100644 (file)
@@ -32,7 +32,7 @@ namespace nnc
 class Softmax : public OperationImpl<float>
 {
 public:
-  Softmax(const mir::Shape &inputShape, const mir::TensorVariant &input, uint32_t axis)
+  Softmax(const mir::Shape &inputShape, const mir::TensorVariant &input, int32_t axis)
       : _inShape(inputShape), _axis(axis), _input(input)
   {
   }
@@ -58,7 +58,7 @@ public:
 
 private:
   const mir::Shape &_inShape;
-  const uint32_t _axis;
+  const int32_t _axis;
   const mir::TensorVariant _input;
 };
 
index b9b9f17..76d0af0 100644 (file)
@@ -28,7 +28,7 @@ void translate(Index &translatedIndex, const Index &sourceIndex, const Index &ke
 {
   assert(translatedIndex.rank() == sourceIndex.rank());
 
-  for (uint32_t d = 0; d < translatedIndex.rank(); ++d)
+  for (int32_t d = 0; d < translatedIndex.rank(); ++d)
   {
     translatedIndex.at(d) = sourceIndex.at(d) * strides.dim(d) + kernelIndex.at(d) - paddings.at(d);
   }
index dfc9a5a..8d74e89 100644 (file)
@@ -42,7 +42,7 @@ std::vector<TensorVariant> Conv2D::operator()()
 {
   auto res = allocate_tensor(_out_shape);
   Tensor<float> resAccesor(res);
-  Index pads({(uint32_t)_op.getPadding(0), (uint32_t)_op.getPadding(1), 0u});
+  Index pads({_op.getPadding(0), _op.getPadding(1), 0u});
 
   Shape outShape = resAccesor.getShape();
   outShape.dim(2) = 1;
@@ -52,7 +52,7 @@ std::vector<TensorVariant> Conv2D::operator()()
   ShapeRange inRange(_input.getShape());
 
   Shape kShape = _kernel.getShape();
-  uint32_t numKernels = kShape.dim(3);
+  int32_t numKernels = kShape.dim(3);
   kShape.dim(3) = 1;
   ShapeRange kernelRange(kShape);
 
@@ -75,7 +75,7 @@ std::vector<TensorVariant> Conv2D::operator()()
 
         auto in = _input.at(inputIdx);
 
-        for (uint32_t kernelIndex = 0; kernelIndex < numKernels; ++kernelIndex)
+        for (int32_t kernelIndex = 0; kernelIndex < numKernels; ++kernelIndex)
         {
           outRegion.base()[kernelIndex] += in * kernelRegion.base()[kernelIndex];
         }
index f07f02a..2effd08 100644 (file)
@@ -33,7 +33,7 @@ using namespace mir::ops;
 // Refer to https://www.tensorflow.org/api_docs/python/tf/nn/conv2d for info
 std::vector<TensorVariant> Conv2D_FFT::operator()()
 {
-  Index pads({(uint32_t)_op.getPadding(0), (uint32_t)_op.getPadding(1), 0u});
+  Index pads({_op.getPadding(0), _op.getPadding(1), 0u});
   //
   // 1. Pad input (currently only with clamp to zero, maybe clamp to edge and wrap later)
   auto inputPadded = pad_input(pads);
@@ -92,8 +92,8 @@ Conv2D_FFT::Conv2D_FFT(const TensorVariant &input, const Conv2DOp &op)
 std::vector<FFT_complex> Conv2D_FFT::pad_input(const Index &pads)
 {
   // Calculate new shape: just add paddings
-  uint32_t height = _input.getShape().dim(0),
-           width  = _input.getShape().dim(1);
+  int32_t height = _input.getShape().dim(0),
+        width  = _input.getShape().dim(1);
 
   Shape newShape = _input.getShape();
   int rank = newShape.rank();
@@ -144,11 +144,11 @@ std::vector<FFT_complex> Conv2D_FFT::pad_input(const Index &pads)
 std::vector<std::vector<FFT_complex>> Conv2D_FFT::unpack_and_pad_kernels(const Shape &paddedInputShape, const uint64_t spectreSize)
 {
   const Shape &kShape = _kernel.getShape();
-  uint32_t numKernels = kShape.dim(3);
+  int32_t numKernels = kShape.dim(3);
 
   // Vector to store results to
   std::vector<std::vector<FFT_complex>> paddedKernels;
-  for (uint32_t n = 0; n < numKernels; n++) {
+  for (int32_t n = 0; n < numKernels; n++) {
     std::vector<FFT_complex> one_kernel(spectreSize, FFT_complex(0.0f, 0.0f));
     paddedKernels.push_back(one_kernel);
   }
@@ -181,10 +181,10 @@ std::vector<std::vector<FFT_complex>> Conv2D_FFT::unpack_and_pad_kernels(const S
 void Conv2D_FFT::elementwise_product(const std::vector<FFT_complex> &input,
                                      std::vector<std::vector<FFT_complex>> &kernels)
 {
-  uint32_t size = input.size();
+  size_t size = input.size();
   for (auto &kernel : kernels)
   {
-    for (uint32_t i = 0; i < size; i++)
+    for (size_t i = 0; i < size; i++)
     {
       kernel[i] *= input[i];
     }
@@ -212,12 +212,12 @@ TensorVariant Conv2D_FFT::ifft(std::vector<std::vector<FFT_complex>> &spectres,
 
   // Move our results to it
   ShapeRange outRange(outShape);
-  uint32_t width = inShape.dim(1);
+  int32_t width = inShape.dim(1);
   // We have to multiply by number of channels, because
   // only every first of three elements corresponds to
   // correct convolution by channels, the rest are
   // results of shifted convolution
-  uint32_t inChannels = inShape.dim(2);
+  int32_t inChannels = inShape.dim(2);
   for (auto &outIdx : outRange)
   {
     resAccessor.at(outIdx) = spectres[outIdx.at(2)][inChannels * ((outIdx.at(0) * strides.dim(0) + paddings.at(0)) * width +
@@ -257,7 +257,7 @@ void Conv2D_FFT::fft_CT(FFT_complex* array,
     separate(array, elements);
     fft_CT(array, elements / 2);
     fft_CT(array + elements / 2, elements / 2);
-    for(int i = 0; i < elements / 2; i++) {
+    for(size_t i = 0; i < elements / 2; i++) {
       FFT_complex even = array[i];
       FFT_complex odd  = array[i + elements / 2];
       FFT_complex twiddle = exp(FFT_complex(0, -2. * M_PI * i / elements));
@@ -276,7 +276,7 @@ void Conv2D_FFT::ifft_CT(FFT_complex* array,
     separate(array, elements);
     ifft_CT(array, elements / 2);
     ifft_CT(array + elements / 2, elements / 2);
-    for(int i = 0; i < elements / 2; i++) {
+    for(size_t i = 0; i < elements / 2; i++) {
       FFT_complex even = array[i];
       FFT_complex odd  = array[i + elements / 2];
       FFT_complex twiddle = exp(FFT_complex(0, 2. * M_PI * i / elements));
index 85fad32..2ddb8ce 100644 (file)
@@ -99,7 +99,7 @@ void Serializer::serializeShape(const Shape &s)
   for (int32_t i = 0; i < rank; ++i)
   {
     int32_t dim = s.dim(i);
-    serializeT(dim);
+    serializeT<int32_t>(dim);
   }
 }
 
@@ -116,7 +116,7 @@ void Serializer::serializeTensor(const TensorVariant &t)
   const Shape &shape = t.getShape();
   serializeShape(shape);
   // serialize actual data
-  size_t tSize = eSize * num_elements(shape);
+  size_t tSize = eSize * shape.numElements();
 
   size_t oldSize = _buffer.size();
   _buffer.reserve(oldSize + tSize);
@@ -165,7 +165,7 @@ void Serializer::visit(INode *node, ops::Conv2DOp &op)
   // serialize strides
   serializeShape(op.getStrides());
   // serialize pads
-  uint32_t padsRank = op.getInputShape(0).rank();
+  int32_t padsRank = op.getInputShape(0).rank();
   serializePads(op, padsRank);
   // serialize output shape
   serializeShape(op.getOutputShape(0));
@@ -180,7 +180,7 @@ void Serializer::visit(INode *node, ops::DepthwiseConv2DOp &op)
   // serialize strides
   serializeShape(op.getStrides());
   // serialize pads
-  uint32_t padsRank = kernel.getShape().rank();
+  int32_t padsRank = kernel.getShape().rank();
   serializePads(op, padsRank);
   // serialize output shape
   serializeShape(op.getOutputShape(0));
@@ -203,7 +203,7 @@ void Serializer::visit(INode *node, ops::PoolOp &op)
   // serialize strindes
   serializeShape(op.getStrides());
   // serialize pads
-  uint32_t padsRank = windowShape.rank();
+  int32_t padsRank = windowShape.rank();
   serializePads(op, padsRank);
   // serialize border type
   PoolBorderType borderType;
index a1bc110..b65ff0d 100644 (file)
@@ -142,6 +142,7 @@ struct Kernel
   Dims<4> dims;
 };
 
+__attribute__((unused))
 static bool isAddrAligned(const void *data, int alignment)
 {
   return (reinterpret_cast<uintptr_t>(data) % alignment) == 0;
index 27d1f84..853d538 100644 (file)
@@ -105,7 +105,7 @@ void DumpVisitor::visit(const OperatorCode *oc)
 
 static std::ostream &operator<<(std::ostream &os, const flatbuffers::Vector<int32_t> *v)
 {
-  for (int i = 0; i < v->size(); ++i)
+  for (size_t i = 0; i < v->size(); ++i)
   {
     if (i != 0)
       os << ", ";
index be891ed..a752765 100644 (file)
@@ -117,7 +117,7 @@ void IrVisitor::visit(const Operator *op)
             EnumNamesBuiltinOperator()[opcode]);
   }
 
-  for (int i = 0; i < op->outputs()->size(); ++i)
+  for (size_t i = 0; i < op->outputs()->size(); ++i)
   {
     opsForTensorsTheyOutput[(*(op->outputs()))[i]] = outputs[i];
   }
index 2eb3565..e46df17 100644 (file)
@@ -66,8 +66,8 @@ private:
   const flatbuffers::Vector<flatbuffers::Offset<Tensor>> *tensors = nullptr;
   const flatbuffers::Vector<flatbuffers::Offset<Buffer>> *buffers = nullptr;
 
-  std::vector<uint32_t> graphInputs;
-  std::vector<uint32_t> graphOutputs;
+  std::vector<int32_t> graphInputs;
+  std::vector<int32_t> graphOutputs;
 
   // This map maps indices of the tensors in TFLite to operations/nodes in the IR graph
   // that correspond to operations having these tensors as output.
index 34728b0..97507a4 100644 (file)
@@ -28,6 +28,7 @@
 #include "core/modelIR/operations/reshape_op.h"
 #include "pass/PassException.h"
 
+using namespace nnc::mir;
 
 namespace nnc
 {
@@ -38,8 +39,8 @@ std::vector<INode::Ref> OpCreator::createConv2D(InputOps inputs, InputParams par
                                                 const Conv2DOptions *opts)
 {
   auto outputs = createOp<ops::Conv2DOp>(inputs, ActivationFunctionType_NONE, std::move(*params[0]),
-                                         Shape{static_cast<uint32_t>(opts->stride_h()),
-                                               static_cast<uint32_t>(opts->stride_w()), 1},
+                                         Shape{static_cast<int32_t>(opts->stride_h()),
+                                               static_cast<int32_t>(opts->stride_w()), 1},
                                          paddingMap[opts->padding()]);
   return createOp<ops::BiasAddOp>(outputs, opts->fused_activation_function(),
                                   std::move(*params[1]));
@@ -50,8 +51,8 @@ std::vector<INode::Ref> OpCreator::createDepthConv2D(InputOps inputs, InputParam
 {
   auto outputs = createOp<ops::DepthwiseConv2DOp>(
           inputs, ActivationFunctionType_NONE, std::move(*params[0]),
-          Shape{static_cast<uint32_t>(opts->stride_h()),
-                static_cast<uint32_t>(opts->stride_w()), 1},
+          Shape{static_cast<int32_t>(opts->stride_h()),
+                static_cast<int32_t>(opts->stride_w()), 1},
           paddingMap[opts->padding()]);
   return createOp<ops::BiasAddOp>(outputs, opts->fused_activation_function(),
                                   std::move(*params[1]));
@@ -69,10 +70,10 @@ std::vector<INode::Ref> OpCreator::createMaxPool(InputOps inputs, InputParams pa
                                                  const Pool2DOptions *opts)
 {
   return createOp<ops::PoolOp>(inputs, opts->fused_activation_function(),
-                               Shape{static_cast<uint32_t>(opts->filter_height()),
-                                     static_cast<uint32_t>(opts->filter_width()), 1},
-                               Shape{static_cast<uint32_t>(opts->stride_h()),
-                                     static_cast<uint32_t>(opts->stride_w()), 1},
+                               Shape{static_cast<int32_t>(opts->filter_height()),
+                                     static_cast<int32_t>(opts->filter_width()), 1},
+                               Shape{static_cast<int32_t>(opts->stride_h()),
+                                     static_cast<int32_t>(opts->stride_w()), 1},
                                ops::PoolOp::PoolingType::MAX, paddingMap[opts->padding()],
                                ops::PoolOp::BorderType::EMPTY);
 }
@@ -81,10 +82,10 @@ std::vector<INode::Ref> OpCreator::createAvgPool(InputOps inputs, InputParams pa
                                                  const Pool2DOptions *opts)
 {
   return createOp<ops::PoolOp>(inputs, opts->fused_activation_function(),
-                               Shape{static_cast<uint32_t>(opts->filter_height()),
-                                     static_cast<uint32_t>(opts->filter_width()), 1},
-                               Shape{static_cast<uint32_t>(opts->stride_h()),
-                                     static_cast<uint32_t>(opts->stride_w()), 1},
+                               Shape{static_cast<int32_t>(opts->filter_height()),
+                                     static_cast<int32_t>(opts->filter_width()), 1},
+                               Shape{static_cast<int32_t>(opts->stride_h()),
+                                     static_cast<int32_t>(opts->stride_w()), 1},
                                ops::PoolOp::PoolingType::AVG, paddingMap[opts->padding()],
                                ops::PoolOp::BorderType::EMPTY);
 }
@@ -114,7 +115,7 @@ std::vector<INode::Ref> OpCreator::createFullyConnected(InputOps &inputs, InputP
 {
   // Add Reshape operation to make sure the input for FC operation has shape [1, fcInputSize]
   auto outputs = createOp<ops::ReshapeOp>(inputs, ActivationFunctionType_NONE);
-  uint32_t fcInputSize = params[0]->getShape().dim(0);
+  int32_t fcInputSize = params[0]->getShape().dim(0);
   outputs[0]->getOperation()->setOutputShape(0, {1, fcInputSize});
 
   auto fcOutputs = createOp<ops::FullyConnectedOp>(outputs, ActivationFunctionType_NONE, std::move(*params[0]));
index 3bfd54d..7c49d83 100644 (file)
@@ -156,7 +156,7 @@ namespace tensor
 std::ostream &operator<<(std::ostream &os, const Shape &sh)
 {
   os << "Shape(";
-  for (uint32_t i = 0; i < sh.rank(); ++i)
+  for (int32_t i = 0; i < sh.rank(); ++i)
   {
     if (i != 0)
       os << ", ";
diff --git a/contrib/nnc/unittests/core/ShapeIndex.cpp b/contrib/nnc/unittests/core/ShapeIndex.cpp
new file mode 100644 (file)
index 0000000..d2cf484
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "core/modelIR/Shape.h"
+#include "core/modelIR/Index.h"
+
+using namespace nnc::mir;
+
+TEST(Shape, Base)
+{
+  Shape s1{3, 2};
+  ASSERT_EQ(s1.rank(), 2);
+  ASSERT_EQ(s1.dim(0), 3);
+  ASSERT_EQ(s1.dim(1), 2);
+  ASSERT_EQ(s1.dim(-1), 2);
+  ASSERT_EQ(s1.dim(-2), 3);
+  ASSERT_EQ(s1.numElements(), 6);
+
+  s1.dim(1) = 4;
+  ASSERT_EQ(s1.dim(1), 4);
+  ASSERT_EQ(s1.numElements(), 12);
+
+  Shape s2 = s1;
+  ASSERT_EQ(s1, s2);
+
+  s2.resize(1);
+  ASSERT_NE(s1, s2);
+
+  s2.resize(2);
+  s2.dim(1) = s1.dim(1);
+  ASSERT_EQ(s1, s2);
+}
+
+TEST(Index, Base)
+{
+  Index idx{3, 2};
+  ASSERT_EQ(idx.rank(), 2);
+  ASSERT_EQ(idx.at(0), 3);
+  ASSERT_EQ(idx.at(1), 2);
+  ASSERT_EQ(idx.at(-1), 2);
+  ASSERT_EQ(idx.at(-2), 3);
+
+  idx.at(1) = 4;
+  ASSERT_EQ(idx.at(1), 4);
+
+  idx.resize(1);
+  ASSERT_EQ(idx.rank(), 1);
+}
index 47f9dc8..2d68b0a 100644 (file)
@@ -34,7 +34,7 @@ TEST(ShapeInferenceTest, ReshapeAutoDimension) {
 
   auto n = g.create<ops::ReshapeOp>("reshape");
   n->getOperation()->setInputShape( 0, Shape{10, 2, 5} );
-  n->getOperation()->setOutputShape(0, Shape{10, 1, ShapeInference::AUTO_DIM} );
+  n->getOperation()->setOutputShape(0, Shape{10, 1, Shape::AUTO_DIM} );
   n->connectInputTo(0, input->getOutput(0));
 
   si.visit(n, *static_cast<ops::ReshapeOp*>(n->getOperation()));
@@ -59,12 +59,12 @@ TEST(ShapeInferenceTest, ReshapeAutoDimensionVaryRank) {
   n->connectInputTo(0, input->getOutput(0));
 
   // test shrink
-  n->getOperation()->setOutputShape(0, Shape{10, ShapeInference::AUTO_DIM});
+  n->getOperation()->setOutputShape(0, Shape{10, Shape::AUTO_DIM});
   si.visit(n, *static_cast<ops::ReshapeOp*>(n->getOperation()));
   ASSERT_EQ(resultShapeShrink, n->getOperation()->getOutputShape(0));
 
   // test expansion
-  n->getOperation()->setOutputShape(0, Shape{5, ShapeInference::AUTO_DIM, 2, 2});
+  n->getOperation()->setOutputShape(0, Shape{5, Shape::AUTO_DIM, 2, 2});
   si.visit(n, *static_cast<ops::ReshapeOp*>(n->getOperation()));
   ASSERT_EQ(resultShapeExpand, n->getOperation()->getOutputShape(0));
 }
index 0593765..16496ac 100644 (file)
@@ -22,11 +22,11 @@ using namespace nnc::mir;
 namespace {
 
 struct ParamType {
-  uint32_t actual_length;
+  int32_t actual_length;
   Shape shape;
 
   template<typename ...Args>
-  explicit ParamType(uint32_t actual_len, Args&& ...args) : actual_length(actual_len), shape({static_cast<uint32_t>(args)...}) {}
+  explicit ParamType(int32_t actual_len, Args&& ...args) : actual_length(actual_len), shape({static_cast<int32_t>(args)...}) {}
 };
 
 class ShapeIteratorTest : public ::testing::TestWithParam<ParamType> {
@@ -37,7 +37,7 @@ TEST_P(ShapeIteratorTest, ElementCount) {
   Shape sh(GetParam().shape);
   ShapeRange r(sh);
 
-  uint32_t cnt = 0;
+  int32_t cnt = 0;
   for( auto& idx : r ) {
     (void)idx;
     cnt++;
@@ -57,4 +57,22 @@ std::vector<ParamType> test_data {
 
 INSTANTIATE_TEST_CASE_P(SimpleInput, ShapeIteratorTest, ::testing::ValuesIn(test_data));
 
+TEST(ShapeRange, Contains) {
+  const int h = 2;
+  const int w = 3;
+  Shape shape{static_cast<int32_t>(h), static_cast<int32_t>(w)};
+  ShapeRange range(shape);
+  Index index{0,0,0,0};
+  for (int32_t row = -2; row < h + 1; ++row)
+    for (int32_t col = -2; col < w + 1; ++col)
+    {
+      Index idx{row, col};
+      if (row < 0 || row >= h || col < 0 || col >= w)
+        ASSERT_FALSE(range.contains(idx));
+      else
+        ASSERT_TRUE(range.contains(idx));
+    }
+
+}
+
 }
index f4421bb..1d69f6b 100644 (file)
@@ -106,10 +106,11 @@ TEST(Deserializer, IntTensorDeserializationTest) {
   Shape shape_1{3};
   for (auto& idx : ShapeRange(shape_1))
   {
+    (void)idx;
     values.push_back(tmp++);
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * num_elements(shape_1)));
-  for (uint32_t i = 0; i < shape_1.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * shape_1.numElements()));
+  for (int32_t i = 0; i < shape_1.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_1.dim(i));
   }
@@ -123,10 +124,11 @@ TEST(Deserializer, IntTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_2))
   {
+    (void)idx;
     values.push_back(tmp--);
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * num_elements(shape_2)));
-  for (uint32_t i = 0; i < shape_2.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * shape_2.numElements()));
+  for (int32_t i = 0; i < shape_2.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_2.dim(i));
   }
@@ -140,10 +142,11 @@ TEST(Deserializer, IntTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_3))
   {
+    (void)idx;
     values.push_back(tmp++);
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * num_elements(shape_3)));
-  for (uint32_t i = 0; i < shape_3.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(int) * shape_3.numElements()));
+  for (int32_t i = 0; i < shape_3.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_3.dim(i));
   }
@@ -166,11 +169,12 @@ TEST(Deserializer, FloatTensorDeserializationTest) {
   Shape shape_1{3};
   for (auto& idx : ShapeRange(shape_1))
   {
+    (void)idx;
     values.push_back(tmp);
     tmp += 7.3f;
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * num_elements(shape_1)));
-  for (uint32_t i = 0; i < shape_1.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * shape_1.numElements()));
+  for (int32_t i = 0; i < shape_1.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_1.dim(i));
   }
@@ -184,11 +188,12 @@ TEST(Deserializer, FloatTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_2))
   {
+    (void)idx;
     values.push_back(tmp);
     tmp *= -1.32f;
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * num_elements(shape_2)));
-  for (uint32_t i = 0; i < shape_2.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * shape_2.numElements()));
+  for (int32_t i = 0; i < shape_2.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_2.dim(i));
   }
@@ -202,11 +207,12 @@ TEST(Deserializer, FloatTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_3))
   {
+    (void)idx;
     tmp /= 2;
     values.push_back(tmp);
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * num_elements(shape_3)));
-  for (uint32_t i = 0; i < shape_3.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(float) * shape_3.numElements()));
+  for (int32_t i = 0; i < shape_3.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_3.dim(i));
   }
@@ -229,11 +235,12 @@ TEST(Deserializer, DoubleTensorDeserializationTest) {
   Shape shape_1{3};
   for (auto& idx : ShapeRange(shape_1))
   {
+    (void)idx;
     values.push_back(tmp);
     tmp += 7.3f;
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * num_elements(shape_1)));
-  for (uint32_t i = 0; i < shape_1.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * shape_1.numElements()));
+  for (int32_t i = 0; i < shape_1.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_1.dim(i));
   }
@@ -247,11 +254,12 @@ TEST(Deserializer, DoubleTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_2))
   {
+    (void)idx;
     values.push_back(tmp);
     tmp *= -1.32f;
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * num_elements(shape_2)));
-  for (uint32_t i = 0; i < shape_2.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * shape_2.numElements()));
+  for (int32_t i = 0; i < shape_2.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_2.dim(i));
   }
@@ -265,11 +273,12 @@ TEST(Deserializer, DoubleTensorDeserializationTest) {
   proto_shapePtr->clear_dims();
   for (auto& idx : ShapeRange(shape_3))
   {
+    (void)idx;
     tmp /= 2;
     values.push_back(tmp);
   }
-  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * num_elements(shape_3)));
-  for (uint32_t i = 0; i < shape_3.rank(); i++)
+  proto_tensor.set_tensor_content(std::string((char*) values.data(), sizeof(double) * shape_3.numElements()));
+  for (int32_t i = 0; i < shape_3.rank(); i++)
   {
     proto_shapePtr->add_dims(shape_3.dim(i));
   }
index 5c2655c..54f84cb 100644 (file)
@@ -47,7 +47,7 @@ template <typename T>
 static std::shared_ptr<T> allocateTensorContent(const Shape &shape)
 {
   size_t data_size = 1;
-  for (uint32_t i = 0; i < shape.rank(); ++i)
+  for (int32_t i = 0; i < shape.rank(); ++i)
   {
     data_size *= shape.dim(i);
   }
index 9b277d2..12992a0 100644 (file)
@@ -161,7 +161,7 @@ void fillNTensor(mir::TensorVariant &dst, float start)
 mir::TensorVariant createNTensor(mir::Shape &shape, float start)
 {
   shared_ptr<char> dataBuf(
-          new char[sizeof(float)*mir::num_elements(shape)], default_delete<char[]>());
+          new char[sizeof(float)*shape.numElements()], default_delete<char[]>());
   mir::TensorVariant tensor(shape, dataBuf, mir::TensorVariant::DTYPE::FLOAT, sizeof(float));
   fillNTensor(tensor, start);
   return tensor;
@@ -192,7 +192,7 @@ void fillTensors(unique_ptr<mir::TensorVariant> &nTensor, Tensor &aTensor, const
   fillShapes(nShape, aShape, shape);
   aTensor.reShape(aShape);
   shared_ptr<char> dataBuf(
-          new char[sizeof(float)*mir::num_elements(nShape)], default_delete<char[]>());
+          new char[sizeof(float)*nShape.numElements()], default_delete<char[]>());
   nTensor.reset(new mir::TensorVariant(nShape, dataBuf, mir::TensorVariant::DTYPE::FLOAT, sizeof(float)));
   fillNTensor(*nTensor, start);
   copyATensorFromNTensor(aTensor, *nTensor);
@@ -341,7 +341,7 @@ TEST(cpp_operations_test, conv2d)
   // input channels(inputC), output channels(outputC),
   // stride width, stride height
   // size 3 is chosen to cover all cases, where width bigger/smaller then height and equal/not equal to 1
-  using iT = uint32_t;
+  using iT = int32_t;
   for (iT kernelH = 1; kernelH <= 3; ++kernelH)
     for (iT kernelW = 1; kernelW <= 3; ++kernelW)
       for (iT inputC = 1; inputC <= 3; ++inputC)
@@ -373,7 +373,7 @@ TEST(cpp_operations_tests, depthwise_conv)
   // stride width, stride height
   // layers multiplier
   // size 3 is chosen to cover all cases, where width bigger/smaller then height and equal/not equal to 1
-  using iT = uint32_t;
+  using iT = int32_t;
   for (iT kernelH = 1; kernelH <= 3; ++kernelH)
     for (iT kernelW = 1; kernelW <= 3; ++kernelW)
       for (iT channels = 1; channels <= 3; ++channels)
@@ -417,7 +417,7 @@ static void genericPoolTest(Func testFunc, const vector<irOps::PoolOp::BorderTyp
   // channels
   // stride width, stride height
   // size 3 is chosen to cover all cases, where width bigger/smaller then height and equal/not equal to 1
-  using iT = uint32_t;
+  using iT = int32_t;
   for (iT windowH = 1; windowH <= 3; ++windowH)
     for (iT windowW = 1; windowW <= 3; ++windowW)
       for (iT channels = 1; channels <= 2; ++channels)
index 2c6a73f..b821363 100644 (file)
@@ -43,6 +43,7 @@ static void deleteFile(const string &path)
 {
   int res = remove(path.c_str());
   assert(!res && "failed to remove file");
+  (void)res;
 }
 
 int removeRec(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
@@ -55,6 +56,7 @@ static void deleteDir(const string &path)
 {
   int res = nftw(path.c_str(), removeRec, 1, FTW_DEPTH | FTW_PHYS);
   assert(!res && "failed to remove dir");
+  (void)res;
 }
 
 static void checkOutputExists(const string &commonPath)
@@ -111,6 +113,7 @@ TEST(Generator, check_generator_call)
   struct stat sBefore, sAfter;
   int res = stat(BASE_NAME ".h", &sBefore);
   assert(res == 0);
+  (void)res;
   assert(sBefore.st_size == 0);
   CPPCodeGenerator::getInstance().run(&g);
   res = stat(BASE_NAME ".h", &sAfter);
index 1022c78..402a35b 100644 (file)
@@ -226,7 +226,7 @@ TEST(SUPPORT_NNC, verify_cl_options)
   ASSERT_EQ(NDefaultNegOpt, tmp_sint);
 
   // check integer option with positive value
-  ASSERT_EQ(NPosOpt, 33);
+  ASSERT_EQ(NPosOpt, 33u);
 
   //
   // char options