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; }
* @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;
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);
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);
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)
_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)
{
}
}
+/* 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)
}
// 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);
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
}
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;
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));
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));
}
BatchMatMul,
Einsum,
BroadcastTo,
- FusedBatchNorm
+ FusedBatchNorm,
+ StatelessRandomUniform
};
// Mapping from custom op name string to BuiltinOP enum
{"Einsum", BuiltinOP::Einsum},
{"FusedBatchNormV3", BuiltinOP::FusedBatchNorm},
{"BroadcastTo", BuiltinOP::BroadcastTo},
+ {"StatelessRandomUniform", BuiltinOP::StatelessRandomUniform},
};
try
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"};
}
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;
}
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();
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;
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)));