Imported Upstream version 1.8.0
[platform/core/ml/nnfw.git] / runtime / onert / frontend / base_loader / include / base_loader.h
index f5687ad..0f6a2a5 100644 (file)
@@ -53,6 +53,8 @@ protected:
   using SubGraph = typename LoaderDomain::SubGraph;
   using Tensor = typename LoaderDomain::Tensor;
   using TensorType = typename LoaderDomain::TensorType;
+  using DimensionType = typename LoaderDomain::DimensionType;
+  using SparseIndexVector = typename LoaderDomain::SparseIndexVector;
 
 protected:
   bool isOptionalInputTensor(std::int32_t idx) { return idx == -1; }
@@ -75,6 +77,13 @@ public:
    * @param file_path
    */
   void loadFromFile(const char *file_path);
+  /**
+   * @brief Load a model from a buffer
+   *
+   * @param buffer buffer pointer
+   * @param size buffer size
+   */
+  void loadFromBuffer(uint8_t *buffer, size_t size);
 
 protected:
   ~BaseLoader() = default;
@@ -107,7 +116,6 @@ protected:
   void loadSoftmax(const Operator *op, ir::Graph &subg);
   void loadMaxPool2D(const Operator *op, ir::Graph &subg);
   void loadConcatenation(const Operator *op, ir::Graph &subg);
-  void loadInstanceNorm(const Operator *op, ir::Graph &subg);
   void loadFill(const Operator *op, ir::Graph &subg);
   void loadFC(const Operator *op, ir::Graph &subg);
   void loadAdd(const Operator *op, ir::Graph &subg);
@@ -140,6 +148,7 @@ protected:
   void loadSqueeze(const Operator *op, ir::Graph &subg);
   void loadPrelu(const Operator *op, ir::Graph &subg);
   void loadSplit(const Operator *op, ir::Graph &subg);
+  void loadSplitV(const Operator *op, ir::Graph &subg);
   void loadSlice(const Operator *op, ir::Graph &subg);
   void loadStridedSlice(const Operator *op, ir::Graph &subg);
   void loadUnpack(const Operator *op, ir::Graph &subg);
@@ -165,12 +174,13 @@ protected:
   void loadTile(const Operator *op, ir::Graph &subg);
   void loadLogicalOr(const Operator *op, ir::Graph &subg);
   void loadRange(const Operator *op, ir::Graph &subg);
-  void loadBCQFullyConnected(const Operator *op, ir::Graph &subg);
-  void loadBCQGather(const Operator *op, ir::Graph &subg);
   void loadMatrixBandPart(const Operator *op, ir::Graph &subg);
   void loadBroadcastTo(const Operator *op, ir::Graph &subg);
   void loadFusedBatchNorm(const Operator *op, ir::Graph &subg);
   void loadLogSoftmax(const Operator *op, ir::Graph &subg);
+  void loadQuantize(const Operator *op, ir::Graph &subg);
+  void loadSpaceToDepth(const Operator *op, ir::Graph &subg);
+  void loadStatelessRandomUniform(const Operator *op, ir::Graph &subg);
 
 protected:
   // Base address for mapped region for loading (if needed)
@@ -216,12 +226,20 @@ void BaseLoader<LoaderDomain, SpecificLoader>::BaseLoader::loadFromFile(const ch
   _verifier = std::make_unique<Verifier>(reinterpret_cast<const std::uint8_t *>(_base), size);
 
   loadModel();
-  munmap(_base, size);
 
   close(_fd);
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
+void BaseLoader<LoaderDomain, SpecificLoader>::BaseLoader::loadFromBuffer(uint8_t *buffer,
+                                                                          size_t size)
+{
+  _base = buffer;
+  _verifier = std::make_unique<Verifier>(reinterpret_cast<const std::uint8_t *>(_base), size);
+  loadModel();
+}
+
+template <typename LoaderDomain, typename SpecificLoader>
 ir::Activation BaseLoader<LoaderDomain, SpecificLoader>::BaseLoader::convertActivation(
     const ActivationFunctionType type)
 {
@@ -299,6 +317,23 @@ void BaseLoader<LoaderDomain, SpecificLoader>::BaseLoader::deallocateMmappedArea
   }
 }
 
+/* Copied from tensorflow lite. Need to append copyright */
+template <typename T> bool Copy(const T *data_ptr, std::vector<uint16_t> &arr)
+{
+  if (data_ptr->values() == nullptr)
+  {
+    return false;
+  }
+
+  int size = data_ptr->values()->size();
+  arr.reserve(size);
+  for (int i = 0; i < size; i++)
+  {
+    arr.emplace_back(static_cast<uint16_t>(data_ptr->values()->Get(i)));
+  }
+  return true;
+}
+
 template <typename LoaderDomain, typename SpecificLoader>
 ir::OperandIndex BaseLoader<LoaderDomain, SpecificLoader>::loadOperand(const Tensor *tensor,
                                                                        ir::Graph &subg)
@@ -355,6 +390,61 @@ ir::OperandIndex BaseLoader<LoaderDomain, SpecificLoader>::loadOperand(const Ten
   }
   // Create TypeInfo
   ir::TypeInfo type_info(data_type, scale, zero_point);
+  // Sparsity
+  auto src_sparsity = tensor->sparsity();
+  if (src_sparsity != nullptr)
+  {
+    std::vector<uint16_t> w1_segments;
+    std::vector<uint16_t> w1_indices;
+    // ignore traversal_order, block_map
+    // load metadata
+    const size_t dim_metadata_size = src_sparsity->dim_metadata()->size();
+    if (dim_metadata_size != 2)
+      throw std::runtime_error("sparse tensor is supported only for 2D");
+    const auto *src_metadata = src_sparsity->dim_metadata()->Get(0);
+    if (src_metadata->format() != DimensionType::DimensionType_DENSE)
+      throw std::runtime_error("sparse tensor dim[0] is not DENSE");
+    src_metadata = src_sparsity->dim_metadata()->Get(1);
+    if (src_metadata->format() != DimensionType::DimensionType_SPARSE_CSR)
+      throw std::runtime_error("sparse tensor dim[0] is not SPARSE_CSR");
+
+    auto ParseSparseIndexVector = [src_metadata, &w1_segments, &w1_indices]() {
+      if (src_metadata->array_segments() == nullptr || src_metadata->array_indices() == nullptr)
+        return false;
+      bool status = true;
+      switch (src_metadata->array_segments_type())
+      {
+        case SparseIndexVector::SparseIndexVector_Int32Vector:
+          status = Copy(src_metadata->array_segments_as_Int32Vector(), w1_segments);
+          break;
+        case SparseIndexVector::SparseIndexVector_Uint16Vector:
+          status = Copy(src_metadata->array_segments_as_Uint16Vector(), w1_segments);
+          break;
+        case SparseIndexVector::SparseIndexVector_Uint8Vector:
+          status = Copy(src_metadata->array_segments_as_Uint8Vector(), w1_segments);
+          break;
+        default:
+          return false;
+      }
+      if (status != true)
+        return false;
+      switch (src_metadata->array_indices_type())
+      {
+        case SparseIndexVector::SparseIndexVector_Int32Vector:
+          return Copy(src_metadata->array_indices_as_Int32Vector(), w1_indices);
+        case SparseIndexVector::SparseIndexVector_Uint16Vector:
+          return Copy(src_metadata->array_indices_as_Uint16Vector(), w1_indices);
+        case SparseIndexVector::SparseIndexVector_Uint8Vector:
+          return Copy(src_metadata->array_indices_as_Uint8Vector(), w1_indices);
+        default:
+          break;
+      }
+      return false;
+    };
+    if (ParseSparseIndexVector() == false)
+      throw std::runtime_error("Error during parsing sparsity index information");
+    type_info.sparse2DMetadata(std::move(w1_segments), std::move(w1_indices));
+  }
   // Create operand
   const auto operand_index = subg.addOperand(shape, type_info);
 
@@ -363,18 +453,17 @@ ir::OperandIndex BaseLoader<LoaderDomain, SpecificLoader>::loadOperand(const Ten
   if (data != nullptr)
   {
     using std::ptrdiff_t;
-    size_t data_size = data->size();
-    ptrdiff_t unaligned_offset_start = data->data() - _base;
-    ptrdiff_t offset_end = unaligned_offset_start + data_size;
-
-    // Calculated aligned offset from base address of mapped region
-    // munmap accepts memory address which is a multiple of the pagesize
-    ptrdiff_t aligned_offset_start = (unaligned_offset_start / _pagesize) * _pagesize;
-    size_t mmap_size = offset_end - aligned_offset_start;
-
-    auto ptr = std::make_unique<ir::MMapedData>(_fd, aligned_offset_start, mmap_size,
-                                                unaligned_offset_start, data_size);
-    subg.setOperandValue(operand_index, std::move(ptr));
+    std::unique_ptr<ir::Data> data_obj;
+    if (_fd == -1) // Model is from memory
+    {
+      data_obj = std::make_unique<ir::ExternalData>(data->data(), data->size());
+    }
+    else // Model is loaded(mmap'd) from a file
+    {
+      data_obj = std::make_unique<ir::CachedData>(data->data(), data->size());
+      deallocateMmappedArea(const_cast<uint8_t *>(data->data()), data->size());
+    }
+    subg.setOperandValue(operand_index, std::move(data_obj));
   }
 
   // Name unused
@@ -592,25 +681,6 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadConcatenation(const Operator
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
-void BaseLoader<LoaderDomain, SpecificLoader>::loadInstanceNorm(const Operator *op, ir::Graph &subg)
-{
-  ir::OperandIndexSequence inputs;
-  ir::OperandIndexSequence outputs;
-
-  loadOperationIO(op, inputs, outputs);
-
-  ir::operation::InstanceNorm::Param param;
-  const auto *options = op->builtin_options_as_InstanceNormOptions();
-
-  param.activation = convertActivation(options->fused_activation_function());
-  // Use default value 1e-5 if value of epsilon is zero
-  param.epsilon = options->epsilon() == 0.f ? 1e-5 : options->epsilon();
-
-  std::unique_ptr<ir::Operation> new_op(new ir::operation::InstanceNorm(inputs, outputs, param));
-  subg.addOperation(std::move(new_op));
-}
-
-template <typename LoaderDomain, typename SpecificLoader>
 void BaseLoader<LoaderDomain, SpecificLoader>::loadFill(const Operator *op, ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
@@ -778,6 +848,8 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadResizeBilinear(const Operator
   ir::operation::ResizeBilinear::Param param;
   param.height_out = size_v[0];
   param.width_out = size_v[1];
+  param.align_corners = op->builtin_options_as_ResizeBilinearOptions()->align_corners();
+  param.half_pixel_centers = op->builtin_options_as_ResizeBilinearOptions()->half_pixel_centers();
 
   std::unique_ptr<ir::Operation> new_op(new ir::operation::ResizeBilinear({input}, outputs, param));
   subg.addOperation(std::move(new_op));
@@ -1046,81 +1118,61 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadBatchToSpaceND(const Operator
   ir::OperandIndexSequence outputs;
 
   loadOperationIO(op, inputs, outputs);
-  auto input = inputs.at(0);
-  auto block_shape = inputs.at(1);
-  auto crops = inputs.at(2);
-
-  if (!subg.operands().at(crops).isConstant())
-    throw std::runtime_error("BatchToSpaceND: non-constant 'crops' is not supported.");
 
-  std::vector<std::int32_t> crops_v = subg.operands().at(crops).template asVector<std::int32_t>();
-  assert(crops_v.size() == 4);
-  if (crops_v != std::vector<std::int32_t>{0, 0, 0, 0})
-    throw std::runtime_error("BatchToSpaceND: 'crops' other than {0, 0, 0, 0} is not supported.");
-
-  std::unique_ptr<ir::Operation> new_op{
-      new ir::operation::BatchToSpaceND{{input, block_shape}, outputs}};
+  std::unique_ptr<ir::Operation> new_op{new ir::operation::BatchToSpaceND{inputs, outputs}};
   subg.addOperation(std::move(new_op));
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
-void BaseLoader<LoaderDomain, SpecificLoader>::loadBCQGather(const Operator *op, ir::Graph &subg)
+void BaseLoader<LoaderDomain, SpecificLoader>::loadMatrixBandPart(const Operator *op,
+                                                                  ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
   ir::OperandIndexSequence outputs;
 
   loadOperationIO(op, inputs, outputs);
 
-  ir::operation::BCQGather::Param param;
-  const auto *options = op->builtin_options_as_BCQGatherOptions();
-  param.input_hidden_size = options->input_hidden_size();
-  param.axis = options->axis();
-
-  std::unique_ptr<ir::Operation> new_op(new ir::operation::BCQGather(inputs, outputs, param));
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::MatrixBandPart(inputs, outputs));
   subg.addOperation(std::move(new_op));
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
-void BaseLoader<LoaderDomain, SpecificLoader>::loadBCQFullyConnected(const Operator *op,
-                                                                     ir::Graph &subg)
+void BaseLoader<LoaderDomain, SpecificLoader>::loadBroadcastTo(const Operator *op, ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
   ir::OperandIndexSequence outputs;
 
   loadOperationIO(op, inputs, outputs);
 
-  ir::operation::BCQFullyConnected::Param param;
-  const auto *options = op->builtin_options_as_BCQFullyConnectedOptions();
-  param.weights_hidden_size = options->weights_hidden_size();
-  param.activation = convertActivation(options->fused_activation_function());
-
-  std::unique_ptr<ir::Operation> new_op(
-      new ir::operation::BCQFullyConnected(inputs, outputs, param));
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::BroadcastTo(inputs, outputs));
   subg.addOperation(std::move(new_op));
 }
-
 template <typename LoaderDomain, typename SpecificLoader>
-void BaseLoader<LoaderDomain, SpecificLoader>::loadMatrixBandPart(const Operator *op,
-                                                                  ir::Graph &subg)
+void BaseLoader<LoaderDomain, SpecificLoader>::loadSpaceToDepth(const Operator *op, ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
   ir::OperandIndexSequence outputs;
+  ir::operation::SpaceToDepth::Param param;
+
+  const auto *options = op->builtin_options_as_SpaceToDepthOptions();
+
+  param.block_size = options->block_size();
 
   loadOperationIO(op, inputs, outputs);
 
-  std::unique_ptr<ir::Operation> new_op(new ir::operation::MatrixBandPart(inputs, outputs));
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::SpaceToDepth(inputs, outputs, param));
   subg.addOperation(std::move(new_op));
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
-void BaseLoader<LoaderDomain, SpecificLoader>::loadBroadcastTo(const Operator *op, ir::Graph &subg)
+void BaseLoader<LoaderDomain, SpecificLoader>::loadStatelessRandomUniform(const Operator *op,
+                                                                          ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
   ir::OperandIndexSequence outputs;
-
   loadOperationIO(op, inputs, outputs);
 
-  std::unique_ptr<ir::Operation> new_op(new ir::operation::BroadcastTo(inputs, outputs));
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::StatelessRandomUniform(inputs, outputs));
   subg.addOperation(std::move(new_op));
 }
 
@@ -1144,7 +1196,8 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadCustom(const Operator *op, ir
     BatchMatMul,
     Einsum,
     BroadcastTo,
-    FusedBatchNorm
+    FusedBatchNorm,
+    StatelessRandomUniform
   };
 
   // Mapping from custom op name string to BuiltinOP enum
@@ -1156,6 +1209,7 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadCustom(const Operator *op, ir
       {"Einsum", BuiltinOP::Einsum},
       {"FusedBatchNormV3", BuiltinOP::FusedBatchNorm},
       {"BroadcastTo", BuiltinOP::BroadcastTo},
+      {"StatelessRandomUniform", BuiltinOP::StatelessRandomUniform},
   };
 
   try
@@ -1185,6 +1239,9 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadCustom(const Operator *op, ir
       case BuiltinOP::FusedBatchNorm:
         loadFusedBatchNorm(op, subg);
         break;
+      case BuiltinOP::StatelessRandomUniform:
+        loadStatelessRandomUniform(op, subg);
+        break;
       default:
         throw std::runtime_error{
             "Loader: Custom OP map is defined but operation loader function is not defined"};
@@ -1274,6 +1331,23 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadSplit(const Operator *op, ir:
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
+void BaseLoader<LoaderDomain, SpecificLoader>::loadSplitV(const Operator *op, ir::Graph &subg)
+{
+  ir::OperandIndexSequence inputs;
+  ir::OperandIndexSequence outputs;
+
+  loadOperationIO(op, inputs, outputs);
+
+  ir::operation::SplitV::Param param{};
+
+  const auto *options = op->builtin_options_as_SplitVOptions();
+  param.num_splits = options->num_splits();
+
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::SplitV(inputs, outputs, param));
+  subg.addOperation(std::move(new_op));
+}
+
+template <typename LoaderDomain, typename SpecificLoader>
 void BaseLoader<LoaderDomain, SpecificLoader>::loadSlice(const Operator *op, ir::Graph &subg)
 {
   ir::OperandIndexSequence inputs;
@@ -1743,6 +1817,18 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadLogSoftmax(const Operator *op
 }
 
 template <typename LoaderDomain, typename SpecificLoader>
+void BaseLoader<LoaderDomain, SpecificLoader>::loadQuantize(const Operator *op, ir::Graph &subg)
+{
+  ir::OperandIndexSequence inputs;
+  ir::OperandIndexSequence outputs;
+
+  loadOperationIO(op, inputs, outputs);
+
+  std::unique_ptr<ir::Operation> new_op(new ir::operation::Quantize(inputs, outputs));
+  subg.addOperation(std::move(new_op));
+}
+
+template <typename LoaderDomain, typename SpecificLoader>
 void BaseLoader<LoaderDomain, SpecificLoader>::loadOperation(const Operator *op, ir::Graph &subg)
 {
   const auto builtin_op = _model->operator_codes()->Get(op->opcode_index())->builtin_code();
@@ -1870,6 +1956,9 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadOperation(const Operator *op,
     case BuiltinOperator::BuiltinOperator_SPLIT:
       loadSplit(op, subg);
       return;
+    case BuiltinOperator::BuiltinOperator_SPLIT_V:
+      loadSplitV(op, subg);
+      return;
     case BuiltinOperator::BuiltinOperator_SLICE:
       loadSlice(op, subg);
       return;
@@ -1959,6 +2048,12 @@ void BaseLoader<LoaderDomain, SpecificLoader>::loadOperation(const Operator *op,
     case BuiltinOperator::BuiltinOperator_LOG_SOFTMAX:
       loadLogSoftmax(op, subg);
       return;
+    case BuiltinOperator::BuiltinOperator_QUANTIZE:
+      loadQuantize(op, subg);
+      return;
+    case BuiltinOperator::BuiltinOperator_SPACE_TO_DEPTH:
+      loadSpaceToDepth(op, subg);
+      return;
     default:
       throw std::runtime_error(
           std::string("Unsupported operation: ").append(EnumNameBuiltinOperator(builtin_op)));