Fix arm c++ artifact generation (#1285)
authorEfimov Alexander/AI Tools Lab/./Samsung Electronics <a.efimov@samsung.com>
Tue, 4 Sep 2018 14:09:19 +0000 (17:09 +0300)
committerРоман Михайлович Русяев/AI Tools Lab /SRR/Staff Engineer/삼성전자 <r.rusyaev@samsung.com>
Tue, 4 Sep 2018 14:09:19 +0000 (17:09 +0300)
+ Fix alignment of serialized data
+ Fix build with NEON enabled
+ Fix -Wall warnings

Signed-off-by: Efimov Alexander <a.efimov@samsung.com>
contrib/nnc/plugin/soft_backend/cpp_operations.def
contrib/nnc/plugin/soft_backend/cpp_ops/eigen.def
contrib/nnc/plugin/soft_backend/serializer.cpp

index aa2f76e..d9dc525 100644 (file)
@@ -9,6 +9,8 @@
 
 using namespace std;
 
+#define UNUSED(x) ((void)(x))
+
 static_assert(numeric_limits<float>::is_iec559, "Unsupported float type");
 
 void readParameters(char *&data, size_t &len, const string &path,
@@ -23,37 +25,46 @@ void readParameters(char *&data, size_t &len, const string &path,
 
   // gather file info
   int statRes = fstat(fd, &st);
-  (void)statRes;
   assert(statRes != -1);
+  UNUSED(statRes);
   len = st.st_size;
   assert(len >= params::HEADER_LEN);
 
   // check magic correctness
   char magic[params::MAGIC_LEN + 1] = {};
-  read(fd, magic, params::MAGIC_LEN);
+  ssize_t magic_len = read(fd, magic, params::MAGIC_LEN);
+  assert(magic_len == params::MAGIC_LEN);
+  UNUSED(magic_len);
   assert(strncmp(magic, params::MAGIC, params::MAGIC_LEN) == 0);
+  UNUSED(magic);
 
   // checkversion correctness
   decltype(expectedVersion) version;
-  read(fd, &version, sizeof(version));
+  ssize_t version_len = read(fd, &version, sizeof(version));
+  assert(version_len == sizeof(version));
+  UNUSED(version_len);
   assert(version == expectedVersion);
+  UNUSED(version);
 
   // check hash correctness
   decltype(expectedHash) hash;
-  read(fd, &hash, sizeof(hash));
+  ssize_t hash_len = read(fd, &hash, sizeof(hash));
+  assert(hash_len == sizeof(hash));
+  UNUSED(hash_len);
   assert(hash == expectedHash);
+  UNUSED(hash);
 
   data = static_cast<char *>(mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0));
   int is_error = close(fd);
   assert(!is_error &&  "Can not close file!");
-  (void)is_error;
+  UNUSED(is_error);
 }
 
 void releaseParameters(char *data, size_t len)
 {
   int res = munmap(data, len);
-  (void)res;
   assert(res == 0);
+  UNUSED(res);
 }
 
 template <int rank>
@@ -100,7 +111,7 @@ static inline T deserializeT(const char *&buf)
 static inline Shape deserializeShape(const char *&buf)
 {
   Shape s;
-  char rank = deserializeT<char>(buf);
+  int32_t rank = deserializeT<int32_t>(buf);
   s.setDims(rank);
   for (int i = 0; i < rank; ++i)
   {
@@ -115,15 +126,23 @@ struct Kernel
   Dims<4> dims;
 };
 
+static bool isAddrAligned(const void *data, int alignment)
+{
+  return (reinterpret_cast<uintptr_t>(data) % alignment) == 0;
+}
+
 static inline Kernel deserializeKernel(const char *&buf)
 {
-  char dType = deserializeT<char>(buf);
+  int32_t dType = deserializeT<int32_t>(buf);
   assert(dType == 1 && "Unknown data type");
-  char eSize = deserializeT<char>(buf);
+  UNUSED(dType);
+  int32_t eSize = deserializeT<int32_t>(buf);
   assert(eSize == 4 && "Unsupported element size");
+  UNUSED(eSize);
   Kernel k;
   k.dims = shapeToDims(deserializeShape(buf));
   k.data = reinterpret_cast<const float *>(buf);
+  assert(isAddrAligned(buf, 4) && "data should be aligned to 4 bytes to use arm vector instructions");
   buf += volume(k.dims) * eSize;
   return k;
 }
@@ -135,7 +154,7 @@ void concat(Tensor &out, const char *params, const Args &...inputs)
 {
   const float *input[] = {inputs.getData()...};
   Dims<4> input_d[] = {shapeToDims(inputs.getShape())...};
-  int axis = deserializeT<char>(params);
+  int axis = deserializeT<int32_t>(params);
   Shape out_s = deserializeShape(params);
   // because inner functions accepts axis in reverse order
   axis = out_s.getDims() - 1 - axis;
@@ -155,8 +174,8 @@ void conv2d(Tensor &out, const char *params, const Tensor &in)
   Kernel kernel = deserializeKernel(params);
   Shape strides = deserializeShape(params);
   // pads type. unused for now
-  char pt = deserializeT<char>(params);
-  (void)pt;
+  int32_t pt = deserializeT<int32_t>(params);
+  UNUSED(pt);
   Shape pads = deserializeShape(params);
   Shape out_s = deserializeShape(params);
 
@@ -203,8 +222,8 @@ void depthwiseConv2d(Tensor &out, const char *params, const Tensor &in)
   Kernel kernel = deserializeKernel(params);
   Shape strides = deserializeShape(params);
   // pads type. unused for now
-  char pt = deserializeT<char>(params);
-  (void)pt;
+  int32_t pt = deserializeT<int32_t>(params);
+  UNUSED(pt);
   Shape pads = deserializeShape(params);
   Shape out_s = deserializeShape(params);
 
@@ -241,8 +260,9 @@ void softmax(Tensor &out, const char *params, const Tensor &in)
   const float *input = in.getData();
   Dims<4> input_d = shapeToDims(in.getShape());
   float beta = 1;
-  char axis = deserializeT<char>(params);
+  int32_t axis = deserializeT<int32_t>(params);
   assert(axis == in.getShape().getDims() - 1);
+  UNUSED(axis);
 
   out.reShape(in.getShape());
 
@@ -257,8 +277,8 @@ static inline void genericPool(Executor executor, Tensor &out, const char *param
   Shape window = deserializeShape(params);
   Shape strides = deserializeShape(params);
   // pads type. unused for now
-  char pt = deserializeT<char>(params);
-  (void)pt;
+  int32_t pt = deserializeT<int32_t>(params);
+  UNUSED(pt);
   Shape pads = deserializeShape(params);
   Shape out_s = deserializeShape(params);
 
index 24f01de..d83f608 100644 (file)
@@ -13229,6 +13229,7 @@ struct palign_impl<Offset,Type>\
             first = Command(first, second, Offset);\
     }\
 };\
+
 PALIGN_NEON(0,Packet4f,vextq_f32)
 PALIGN_NEON(1,Packet4f,vextq_f32)
 PALIGN_NEON(2,Packet4f,vextq_f32)
index a272b91..9580646 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <algorithm>
 
+#define UNUSED(x) ((void)(x))
+
 namespace nncc
 {
 namespace contrib
@@ -37,8 +39,10 @@ using nncc::contrib::core::ADT::TensorVariant;
 
 namespace
 {
-  const auto MAX_DIMS = numeric_limits<char>::max();
+  // Currently there are no operations with more then 4 dimensions in kernels/weights etc supported
+  const auto MAX_DIMS = 4;
   const auto MAX_DIM_SIZE = numeric_limits<int32_t>::max();
+  // Assuming there are no large enums
   const auto MAX_ENUM_VAL = numeric_limits<char>::max();
 } // unnamed namespace
 
@@ -66,8 +70,8 @@ typename underlying_type<E>::type etoi(E enumVal)
 void Serializer::serializeShape(const Shape &s)
 {
   int32_t rank = s.rank();
-  assert(rank < MAX_DIMS);
-  serializeT<char>(s.rank());
+  assert(rank <= MAX_DIMS);
+  serializeT<int32_t>(s.rank());
   for (int32_t i = 0; i < rank; ++i)
   {
     int32_t dim = s.dim(i);
@@ -79,11 +83,11 @@ void Serializer::serializeTensor(const TensorVariant &t)
 {
   // serialize type
   assert(etoi(t.getDataType()) < MAX_ENUM_VAL);
-  serializeT<char>(etoi(t.getDataType()));
+  serializeT<int32_t>(etoi(t.getDataType()));
   // seriazlie data size
   size_t eSize = t.getElementSize();
-  assert(eSize < MAX_DIMS);
-  serializeT<char>(eSize);
+  assert(eSize <= MAX_DIMS);
+  serializeT<int32_t>(eSize);
   // serialize shape
   const Shape &shape = t.getShape();
   serializeShape(shape);
@@ -103,15 +107,16 @@ void Serializer::serializePads(const Op &op, int32_t padsRank)
 {
   // serialize padding type
   assert(etoi(op.getPaddingType()) < MAX_ENUM_VAL);
-  serializeT<char>(etoi(op.getPaddingType()));
+  serializeT<int32_t>(etoi(op.getPaddingType()));
   // serialize pads
-  assert(padsRank < MAX_DIMS);
-  serializeT<char>(padsRank);
+  assert(padsRank <= MAX_DIMS);
+  serializeT<int32_t>(padsRank);
   for (int i = 0; i < static_cast<int>(padsRank); ++i)
   {
     auto pad = op.getPadding(i);
     assert(pad <= MAX_DIM_SIZE);
     assert(pad >= 0);
+    UNUSED(pad);
     serializeT<int32_t>(op.getPadding(i));
   }
 }
@@ -120,8 +125,8 @@ void Serializer::visit(ADT::INode *node, ops::ConcatOp &op)
 {
   _curOp->_paramStartOffset = _buffer.size();
   // axis number should fit into one byte
-  assert(op.getAxis() < MAX_DIMS);
-  serializeT<char>(op.getAxis());
+  assert(op.getAxis() <= MAX_DIMS);
+  serializeT<int32_t>(op.getAxis());
   serializeShape(op.getOutputShape(0));
 }
 
@@ -161,8 +166,8 @@ void Serializer::visit(ADT::INode *node, ops::SoftmaxOp &op)
 {
   _curOp->_paramStartOffset = _buffer.size();
   // axis number should fit into one byte
-  assert(op.getAxis() < MAX_DIMS);
-  serializeT<char>(op.getAxis());
+  assert(op.getAxis() <= MAX_DIMS);
+  serializeT<int32_t>(op.getAxis());
 }
 
 void Serializer::visit(ADT::INode *node, ops::PoolOp &op)