assert (data_size >= get_data_size (DATA_TYPE_SRNPU));
if (data_size > get_data_size (DATA_TYPE_SRNPU) ||
- !(zero_point == default_zero_point && scale == default_scale))
+ !(zero_point == default_quant_zero && scale == default_quant_scale))
need_quantization = true;
}
return nullptr;
}
- std::unique_ptr<Metadata> meta_ptr;
- Metadata * meta_ins = nullptr;
+ std::unique_ptr<Metadata> meta (nullptr);
switch (NPUBIN_VERSION (meta_data->magiccode)) {
case 0:
case 1:
- meta_ins = new Metadata_v1 (meta_data);
+ meta.reset (Metadata_v1::createInstance (meta_data));
break;
case 2:
- meta_ins = new Metadata_v2 (meta_data);
+ meta.reset (Metadata_v2::createInstance (meta_data));
break;
case 3:
- meta_ins = new Metadata_v3 (meta_data);
+ meta.reset (Metadata_v3::createInstance (meta_data));
break;
default:
logerr (TAG, "Invalid NPU binary format version: %d\n",
break;
}
- if (meta_ins != nullptr && !meta_ins->checkSanity ()) {
+ if (meta.get () == nullptr)
logerr (TAG, "Failed to pass the metadata sanity check\n");
- delete meta_ins;
- meta_ins = nullptr;
- }
- meta_ptr.reset (meta_ins);
- return meta_ptr;
+ return meta;
}
/** @brief constructor of npubinfmt v1 */
}
}
-/** @brief sanity check for npubinfmt v1 */
-bool
-Metadata_v1::checkSanity () const
+/** @brief create npubinfmt v1 instance with sanity check */
+Metadata_v1 *
+Metadata_v1::createInstance (npubin_meta *meta)
{
- if (getVersion () != 1)
- return false;
+ Metadata_v1 *metadata = new Metadata_v1 (meta);
+
+ if (metadata->getSize () != metadata->getMetaSize () +
+ metadata->getProgramSize () + metadata->getWeightSize ())
+ goto sanity_violation;
- return getSize () == getMetaSize () + getProgramSize () + getWeightSize ();
+ return metadata;
+
+sanity_violation:
+ delete metadata;
+ return nullptr;
}
/** @brief constructor of npubinfmt v2 */
{
}
-/** @brief sanity check for npubinfmt v2 */
-bool
-Metadata_v2::checkSanity () const
+/** @brief create npubinfmt v1 instance with sanity check */
+Metadata_v2 *
+Metadata_v2::createInstance (npubin_meta *meta)
{
- if (getVersion () != 2)
- return false;
- if (getInputNum () > MAX_TENSORS)
- return false;
- if (getOutputNum () > MAX_TENSORS)
- return false;
-
- return getSize () == getMetaSize () + getProgramSize () + getWeightSize ();
+ Metadata_v2 *metadata = new Metadata_v2 (meta);
+
+ if (metadata->getInputNum () > MAX_TENSORS)
+ goto sanity_violation;
+ if (metadata->getOutputNum () > MAX_TENSORS)
+ goto sanity_violation;
+ if (metadata->getSize () != metadata->getMetaSize () +
+ metadata->getProgramSize () + metadata->getWeightSize ())
+ goto sanity_violation;
+
+ return metadata;
+
+sanity_violation:
+ delete metadata;
+ return nullptr;
}
/** @brief calculate tensor size depending on specified layout */
{
}
-/** @brief sanity check for npubinfmt v3 */
-bool
-Metadata_v3::checkSanity () const
+/** @brief create npubinfmt v1 instance with sanity check */
+Metadata_v3 *
+Metadata_v3::createInstance (npubin_meta *meta)
{
- if (getVersion () != 3)
- return false;
- if (getSegmentsNum () > MAX_SEGMENTS)
- return false;
- if (getInputNum () > getSegmentsNum () || getInputNum () > MAX_TENSORS)
- return false;
- if (getOutputNum () > getSegmentsNum () || getOutputNum () > MAX_TENSORS)
- return false;
-
- if (getWeightSegmentIndex () >= getSegmentsNum ())
- return false;
- for (uint32_t i = 0; i < getInputNum (); i++) {
- if (getInputSegmentIndex (i) >= getSegmentsNum ())
- return false;
+ Metadata_v3 *metadata = new Metadata_v3 (meta);
+
+ if (metadata->getSegmentsNum () > MAX_SEGMENTS)
+ goto sanity_violation;
+ if (metadata->getInputNum () > metadata->getSegmentsNum () ||
+ metadata->getInputNum () > MAX_TENSORS)
+ goto sanity_violation;
+ if (metadata->getOutputNum () > metadata->getSegmentsNum () ||
+ metadata->getOutputNum () > MAX_TENSORS)
+ goto sanity_violation;
+
+ if (metadata->getWeightSegmentIndex () >= metadata->getSegmentsNum ())
+ goto sanity_violation;
+ for (uint32_t i = 0; i < metadata->getInputNum (); i++) {
+ if (metadata->getInputSegmentIndex (i) >= metadata->getSegmentsNum ())
+ goto sanity_violation;
}
- for (uint32_t i = 0; i < getOutputNum (); i++) {
- if (getOutputSegmentIndex (i) >= getSegmentsNum ())
- return false;
+ for (uint32_t i = 0; i < metadata->getOutputNum (); i++) {
+ if (metadata->getOutputSegmentIndex (i) >= metadata->getSegmentsNum ())
+ goto sanity_violation;
}
- return getSize () == getMetaSize () + getProgramSize () + getWeightSize ();
+ if (metadata->getSize () != metadata->getMetaSize () +
+ metadata->getProgramSize () + metadata->getWeightSize ())
+ goto sanity_violation;
+
+ return metadata;
+
+sanity_violation:
+ delete metadata;
+ return nullptr;
}
/**
assert (idx < getInputNum ());
const uint32_t *dims = getInputDims (idx);
- uint32_t tensor_size = 1;
+ uint32_t tensor_size = getInputElemSize (idx);
for (uint32_t rank_idx = 0; rank_idx < MAX_RANK; rank_idx++)
tensor_size *= dims[rank_idx];
assert (idx < getOutputNum ());
const uint32_t *dims = getOutputDims (idx);
- uint32_t tensor_size = 1;
+ uint32_t tensor_size = getOutputElemSize (idx);
for (uint32_t rank_idx = 0; rank_idx < MAX_RANK; rank_idx++)
tensor_size *= dims[rank_idx];
constraint_.notimode = default_notimode;
in_.num_info = 1;
- in_.info[0].layout = DATA_LAYOUT_SRNPU;
- in_.info[0].type = DATA_TYPE_SRNPU;
+ in_.info[0].layout = default_data_layout;
+ in_.info[0].type = default_data_type;
out_.num_info = 1;
- out_.info[0].layout = DATA_LAYOUT_SRNPU;
- out_.info[0].type = DATA_TYPE_SRNPU;
+ out_.info[0].layout = default_data_layout;
+ out_.info[0].type = default_data_type;
}
/**
#include <assert.h>
+/** default data layout and type */
+static const data_type default_data_type = DATA_TYPE_SRNPU;
+static const data_layout default_data_layout = DATA_LAYOUT_SRNPU;
/** this assumes uint8 zero quantization */
-static const uint32_t default_zero_point = 127;
-static const float default_scale = 1.0;
+static const uint32_t default_quant_zero = 127;
+static const float default_quant_scale = 1.0;
/**
* Here, the following is dependent to npubinfmt.h. So, this also follows
* standard types rather than size_t.
*/
+uint32_t get_data_size (data_type type);
+
/** @brief model metadata class */
class Metadata {
public:
+ /** @brief extract metadata info from the data and create metadata instance */
static std::unique_ptr<Metadata> extractMetadata (void *data);
- Metadata (npubin_meta *meta);
virtual ~Metadata () {};
- virtual bool checkSanity () const = 0;
-
virtual uint32_t getInputNum () const = 0;
virtual uint32_t getOutputNum () const = 0;
virtual const uint32_t* getInputDims (uint32_t idx) const = 0;
virtual const uint32_t* getOutputDims (uint32_t idx) const = 0;
- virtual uint32_t getInputQuantZero (uint32_t idx) const = 0;
- virtual float getInputQuantScale (uint32_t idx) const = 0;
+ virtual uint32_t getInputQuantZero (uint32_t idx) const { return default_quant_zero; }
+ virtual float getInputQuantScale (uint32_t idx) const { return default_quant_scale; }
- virtual uint32_t getOutputQuantZero (uint32_t idx) const = 0;
- virtual float getOutputQuantScale (uint32_t idx) const = 0;
+ virtual uint32_t getOutputQuantZero (uint32_t idx) const { return default_quant_zero; }
+ virtual float getOutputQuantScale (uint32_t idx) const { return default_quant_scale; }
- virtual data_type getInputQuantType (uint32_t idx) const { return DATA_TYPE_SRNPU; }
- virtual data_type getOutputQuantType (uint32_t idx) const { return DATA_TYPE_SRNPU; }
+ virtual data_type getInputQuantType (uint32_t idx) const { return default_data_type; }
+ virtual data_type getOutputQuantType (uint32_t idx) const { return default_data_type; }
virtual uint32_t getSegmentsNum () const { return 0; }
virtual uint32_t getSegmentSize (uint32_t idx) const { return 0; }
int getVersion () const { return version_; }
protected:
+ Metadata (npubin_meta *meta);
+
npubin_meta *meta_; /**< user-exposed metadata structure */
int version_; /**< metadata version */
};
/** @brief metadata version 1: support only a single pair of input/ouput tensors */
class Metadata_v1 : public Metadata {
public:
- Metadata_v1 (npubin_meta *meta);
-
- bool checkSanity () const;
+ /** @brief create metadata with npubinfmt v1. if sanity check is failed, return nullptr */
+ static Metadata_v1 * createInstance (npubin_meta *meta);
uint32_t getInputNum () const override { return 1; }
uint32_t getOutputNum () const override { return 1; }
return output_dims[idx];
}
- uint32_t getInputQuantZero (uint32_t idx) const override {
- return default_zero_point;
- }
- float getInputQuantScale (uint32_t idx) const override {
- return default_scale;
- }
- uint32_t getOutputQuantZero (uint32_t idx) const override {
- return default_zero_point;
- }
- float getOutputQuantScale (uint32_t idx) const override {
- return default_scale;
- }
-
private:
+ Metadata_v1 (npubin_meta *meta);
+
uint32_t input_dims[MAX_TENSORS][MAX_RANK]; /**< dummy input dimensions */
uint32_t output_dims[MAX_TENSORS][MAX_RANK]; /**< dummy output dimensions */
};
/** @brief metadata version 2: support multiple input/output tensors */
class Metadata_v2 : public Metadata {
public:
- Metadata_v2 (npubin_meta *meta);
-
- bool checkSanity () const;
+ /** @brief create metadata with npubinfmt v2. if sanity check is failed, return nullptr */
+ static Metadata_v2 * createInstance (npubin_meta *meta);
uint32_t getInputNum () const override { return meta_->input_num; }
uint32_t getOutputNum () const override { return meta_->output_num; }
assert (idx < getOutputNum ());
return meta_->output_quant_s[idx];
}
+
+ private:
+ Metadata_v2 (npubin_meta *meta);
};
/** @brief metadata version 3: support a segment table */
class Metadata_v3 : public Metadata {
public:
- Metadata_v3 (npubin_meta *meta);
-
- bool checkSanity () const;
+ /** @brief create metadata with npubinfmt v3. if sanity check is failed, return nullptr */
+ static Metadata_v3 * createInstance (npubin_meta *meta);
uint32_t getInputNum () const override { return meta_->input_seg_num; }
uint32_t getOutputNum () const override { return meta_->output_seg_num; }
uint32_t getInputTensorSize (uint32_t idx, data_layout layout) const override;
uint32_t getOutputTensorSize (uint32_t idx, data_layout layout) const override;
- uint32_t getInputElemSize (uint32_t idx) const override { return 1; }
- uint32_t getOutputElemSize (uint32_t idx) const override { return 1; }
+ uint32_t getInputElemSize (uint32_t idx) const override {
+ return get_data_size (getInputQuantType (idx));
+ }
+ uint32_t getOutputElemSize (uint32_t idx) const override {
+ return get_data_size (getOutputQuantType (idx));
+ }
const uint32_t* getInputDims (uint32_t idx) const override {
assert (idx < getInputNum ());
assert (idx < getOutputNum ());
return meta_->output_seg_idx[idx];
}
+
+ private:
+ Metadata_v3 (npubin_meta *meta);
};
/** @brief model class derived from hwmem */
tensors_data_info out_; /**< output tensor info. */
};
-uint32_t get_data_size (data_type type);
-
#endif /* __NE_MODEL_HH__ */
buffer->setDriverAPI (api.get());
EXPECT_EQ (buffer->alloc (4096), 0);
+ /** dummy segt */
+ std::unique_ptr<SegmentTable> segt (new SegmentTable (new HWmemDevice));
+ segt->setDriverAPI (api.get());
+ EXPECT_EQ (segt->alloc (), 0);
+
EXPECT_EQ (InferenceEngine::invokeInputService (
api.get(), NPUINPUT_HOST, 0, model.get(), buffer.get()), 0);
+ EXPECT_EQ (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_HOST, 1, model.get(), segt.get()), 0);
+
+ sleep (1);
+}
+
+/**
+ * @brief test invokeInputService () with TRIV2
+ */
+TEST (ne_core_inf_test, invoke_triv2)
+{
+ std::unique_ptr<DriverAPI> api;
+ api = DriverAPI::createDriverAPI (NPUCOND_TRIV2_CONN_SOCIP, 0);
+
+ /** create dummy model & segt */
+ std::unique_ptr<Model> model (new Model (new HWmemDevice));
+ model->setDriverAPI (api.get());
+ EXPECT_EQ (model->alloc (4096), 0);
+
+ std::unique_ptr<SegmentTable> segt (new SegmentTable (new HWmemDevice));
+ segt->setDriverAPI (api.get());
+ EXPECT_EQ (segt->alloc (), 0);
+
+ EXPECT_EQ (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_HOST, 1, model.get(), segt.get()), 0);
+ EXPECT_EQ (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_HW_RECURRING, 1, model.get(), segt.get()), 0);
sleep (1);
}
buffer->setDriverAPI (api.get());
EXPECT_EQ (buffer->alloc (4096), 0);
+ std::unique_ptr<SegmentTable> segt (new SegmentTable (new HWmemDevice));
+ segt->setDriverAPI (api.get());
+ EXPECT_EQ (segt->alloc (), 0);
+
/** unsupported opmode */
EXPECT_NE (InferenceEngine::invokeInputService (
api.get(), NPUINPUT_STOP, 0, model.get(), buffer.get()), 0);
EXPECT_NE (InferenceEngine::invokeInputService (
api.get(), NPUINPUT_I2S_MIC, 0, model.get(), buffer.get()), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_STOP, 0, model.get(), segt.get()), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_INTERNAL_CAM, 0, model.get(), segt.get()), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_I2S_MIC, 0, model.get(), segt.get()), 0);
+
+ /** HW_RECURRING works only with segment table */
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ api.get(), NPUINPUT_HW_RECURRING, 0, model.get(), buffer.get()), 0);
+
sleep (1);
}
buffer->setDriverAPI (api.get());
EXPECT_EQ (buffer->alloc (4096), 0);
+ std::unique_ptr<SegmentTable> segt (new SegmentTable (new HWmemDevice));
+ segt->setDriverAPI (api.get());
+ EXPECT_EQ (segt->alloc (), 0);
+
/** invalid args (api should be valid) */
EXPECT_NE (InferenceEngine::invokeInputService (
nullptr, NPUINPUT_HOST, 0, nullptr, (Buffer *) nullptr), 0);
nullptr, NPUINPUT_HOST, 0, nullptr, buffer.get()), 0);
EXPECT_NE (InferenceEngine::invokeInputService (
nullptr, NPUINPUT_HOST, 0, model.get(), buffer.get()), 0);
+
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ nullptr, NPUINPUT_HOST, 0, nullptr, (SegmentTable *) nullptr), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ nullptr, NPUINPUT_HOST, 0, model.get(), (SegmentTable *) nullptr), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ nullptr, NPUINPUT_HOST, 0, nullptr, segt.get()), 0);
+ EXPECT_NE (InferenceEngine::invokeInputService (
+ nullptr, NPUINPUT_HOST, 0, model.get(), segt.get()), 0);
}
/**
EXPECT_NE (service.submit (nullptr, 0, model, buffer), 0);
EXPECT_EQ (service.submit (api.get(), 0, model, buffer), 0);
+ SegmentTable * segt = nullptr;
+ EXPECT_NE (service.submit (nullptr, 1, nullptr, segt), 0);
+ EXPECT_NE (service.submit (api.get(), 1, nullptr, segt), 0);
+ EXPECT_NE (service.submit (nullptr, 1, model, segt), 0);
+ EXPECT_EQ (service.submit (api.get(), 1, model, segt), 0);
+
sleep (1);
delete model;
}
+class TestInputService : public InputService
+{
+ public:
+ TestInputService () {};
+};
+
+/**
+ * @brief test features of submit() with unsupported input service
+ */
+TEST (ne_core_inputservice_test, host_submit_unsupported_n)
+{
+ InputService * service = new TestInputService;
+
+ EXPECT_NE (service->submit (nullptr, 0, nullptr, (Buffer *) nullptr), 0);
+ EXPECT_NE (service->submit (nullptr, 0, nullptr, (SegmentTable *) nullptr), 0);
+
+ delete service;
+}
+
/**
* @brief test features of submit() with error handling
*/
const tensor_data_info * in = model->getInputDataInfo (0);
EXPECT_NE (in, nullptr);
- EXPECT_EQ (in->layout, DATA_LAYOUT_SRNPU);
- EXPECT_EQ (in->type, DATA_TYPE_SRNPU);
+ EXPECT_EQ (in->layout, default_data_layout);
+ EXPECT_EQ (in->type, default_data_type);
const tensor_data_info * out = model->getOutputDataInfo (0);
EXPECT_NE (out, nullptr);
- EXPECT_EQ (out->layout, DATA_LAYOUT_SRNPU);
- EXPECT_EQ (out->type, DATA_TYPE_SRNPU);
+ EXPECT_EQ (out->layout, default_data_layout);
+ EXPECT_EQ (out->type, default_data_type);
/** user can specify constraint & info */
constraint.timeout_ms = 100;
TEST (ne_core_model_test, model_primitives_invalid_args_n)
{
std::unique_ptr <Model> model (new Model (new HWmemDevice));
+ const uint64_t exp_size_input = 2048;
+ const uint64_t exp_size_output = 2048;
/** invalid arguments */
EXPECT_NE (model->setMetadata (nullptr), 0);
+ /** make dummy metadata */
+ npubin_meta data;
+ data.magiccode = NPUBIN_MAGICCODE | 0x1; /* v1 */
+ data.size = 4096;
+ data.buffer_size = 4096;
+ data.input_size = exp_size_input;
+ data.input_offset = 0;
+ data.output_size = exp_size_output;
+ data.output_offset = 2048;
+ data.program_size = 0;
+ data.weight_size = 0;
+ ASSERT_EQ (model->setMetadata (&data), 0);
+
+ /** data info */
tensors_data_info info;
EXPECT_NE (model->setDataInfo (nullptr, nullptr), 0);
EXPECT_NE (model->setDataInfo (&info, nullptr), 0);
/** access info without setting metadata */
EXPECT_EQ (model->getMetadata (), nullptr);
+ EXPECT_EQ (model->getInputTensorNum (), (uint32_t) 0);
+ EXPECT_EQ (model->getOutputTensorNum (), (uint32_t) 0);
EXPECT_EQ (model->getInputTensorSize (0), (uint32_t) 0);
EXPECT_EQ (model->getOutputTensorSize (0), (uint32_t) 0);
EXPECT_EQ (model->getInputDataInfo (0), nullptr);
data.magiccode = NPUBIN_MAGICCODE | 0x2; /* v2 */
data.input_num = MAX_TENSORS + 1;
EXPECT_NE (model->setMetadata (&data), 0);
+ data.input_num = 1;
data.output_num = MAX_TENSORS + 1;
EXPECT_NE (model->setMetadata (&data), 0);
data.weight_size = NPUBIN_META_SIZE;
EXPECT_NE (model->setMetadata (&data), 0); /* size overflow */
+ /** invalid segment num or index */
+ data.magiccode = NPUBIN_MAGICCODE | 0x3; /* v3 */
+ data.segment_num = MAX_SEGMENTS + 1;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.segment_num = MAX_SEGMENTS / 2;
+
+ data.input_seg_num = data.segment_num + 1;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.input_seg_num = data.segment_num - 1;
+ data.output_seg_num = data.segment_num + 1;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.output_seg_num = data.segment_num - 1;
+
+ data.input_seg_num = MAX_TENSORS + 1;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.input_seg_num = MAX_TENSORS;
+ data.output_seg_num = MAX_TENSORS + 1;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.output_seg_num = MAX_TENSORS;
+
+ data.weight_seg_idx = data.segment_num;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.weight_seg_idx = data.segment_num - 1;
+ data.input_seg_idx[0] = data.segment_num;
+ EXPECT_NE (model->setMetadata (&data), 0);
+ data.input_seg_idx[0] = data.segment_num - 1;
+ data.output_seg_idx[0] = data.segment_num;
+ EXPECT_NE (model->setMetadata (&data), 0);
+
/** TODO add more */
}
/**
+ * @brief check get_data_size
+ */
+TEST (ne_core_model_test, get_data_size)
+{
+ EXPECT_EQ (get_data_size (DATA_TYPE_SRNPU), (uint32_t) 1);
+ EXPECT_EQ (get_data_size (DATA_TYPE_INT8), (uint32_t) 1);
+ EXPECT_EQ (get_data_size (DATA_TYPE_UINT8), (uint32_t) 1);
+ EXPECT_EQ (get_data_size (DATA_TYPE_INT16), (uint32_t) 2);
+ EXPECT_EQ (get_data_size (DATA_TYPE_UINT16), (uint32_t) 2);
+ EXPECT_EQ (get_data_size (DATA_TYPE_INT32), (uint32_t) 4);
+ EXPECT_EQ (get_data_size (DATA_TYPE_UINT32), (uint32_t) 4);
+ EXPECT_EQ (get_data_size (DATA_TYPE_FLOAT32), (uint32_t) 4);
+ EXPECT_EQ (get_data_size (DATA_TYPE_INT64), (uint32_t) 8);
+ EXPECT_EQ (get_data_size (DATA_TYPE_UINT64), (uint32_t) 8);
+ EXPECT_EQ (get_data_size (DATA_TYPE_FLOAT64), (uint32_t) 8);
+}
+
+/**
* @brief check set/get primitives of metadata v1
*/
TEST (ne_core_model_test, metadata_primitives_v1)
/** return default values for unsupported info */
EXPECT_EQ (meta->getInputElemSize (0), (uint32_t) 1);
EXPECT_EQ (meta->getOutputElemSize (0), (uint32_t) 1);
- EXPECT_EQ (meta->getInputDims (0)[0], meta->getInputTensorSize (0, DATA_LAYOUT_SRNPU));
- EXPECT_EQ (meta->getOutputDims (0)[0], meta->getOutputTensorSize (0, DATA_LAYOUT_SRNPU));
- EXPECT_EQ (meta->getInputQuantZero (0), default_zero_point);
- EXPECT_EQ (meta->getOutputQuantZero (0), default_zero_point);
- EXPECT_FLOAT_EQ (meta->getInputQuantScale (0), default_scale);
- EXPECT_FLOAT_EQ (meta->getOutputQuantScale (0), default_scale);
+ EXPECT_EQ (meta->getInputDims (0)[0], meta->getInputTensorSize (0, default_data_layout));
+ EXPECT_EQ (meta->getOutputDims (0)[0], meta->getOutputTensorSize (0, default_data_layout));
+ EXPECT_EQ (meta->getInputQuantZero (0), default_quant_zero);
+ EXPECT_EQ (meta->getOutputQuantZero (0), default_quant_zero);
+ EXPECT_FLOAT_EQ (meta->getInputQuantScale (0), default_quant_scale);
+ EXPECT_FLOAT_EQ (meta->getOutputQuantScale (0), default_quant_scale);
+ EXPECT_EQ (meta->getInputQuantType (0), default_data_type);
+ EXPECT_EQ (meta->getOutputQuantType (0), default_data_type);
+
+ EXPECT_EQ (meta->getSegmentsNum (), (uint32_t) 0);
+ EXPECT_EQ (meta->getSegmentSize (0), (uint32_t) 0);
+ EXPECT_EQ (meta->getWeightSegmentIndex (), (uint32_t) 0);
+ EXPECT_EQ (meta->getInputSegmentIndex (0), (uint32_t) 0);
+ EXPECT_EQ (meta->getOutputSegmentIndex (0), (uint32_t) 0);
+
+ /** v0 also works */
+ data.magiccode = NPUBIN_MAGICCODE; /* v0 --> v1 */
+ EXPECT_EQ (model->setMetadata (&data), 0);
+ EXPECT_NE (model->getMetadata (), nullptr);
+ EXPECT_EQ (model->getMetadata ()->getVersion (), 1);
}
/**
}
/**
+ * @brief check set/get primitives of metadata v3
+ */
+TEST (ne_core_model_test, metadata_primitives_v3)
+{
+ std::unique_ptr <Model> model (new Model (new HWmemDevice));
+
+ /** make dummy metadata v3 */
+ npubin_meta data;
+
+ data.magiccode = NPUBIN_MAGICCODE | 0x3; /* v3 */
+ data.size = 8192;
+ data.buffer_size = 4096;
+ data.program_size = 2048;
+ data.weight_size = 2048;
+
+ uint32_t input_num = 3;
+ uint32_t output_num = 4;
+
+ data.segment_num = input_num + output_num + 1;
+ for (uint32_t i = 0; i < data.segment_num; i++)
+ data.segment_size[i] = 0x1000;
+
+ data.input_seg_num = input_num;
+ for (uint32_t i = 0; i < data.input_seg_num; i++) {
+ data.input_seg_idx[i] = i;
+ for (uint32_t j = 0; j < MAX_RANK; j++)
+ data.input_seg_dims[i][j] = 2 * (i + 1);
+ data.input_seg_quant_z[i] = 3 * (i + 1);
+ data.input_seg_quant_s[i] = 4 * (i + 1);
+ data.input_seg_quant_type[i] = DATA_TYPE_QASYMM8;
+ }
+
+ data.output_seg_num = output_num;
+ for (uint32_t i = 0; i < data.output_seg_num; i++) {
+ data.output_seg_idx[i] = data.input_seg_num + i;
+ for (uint32_t j = 0; j < MAX_RANK; j++)
+ data.output_seg_dims[i][j] = 2 * (i + 1);
+ data.output_seg_quant_z[i] = 3 * (i + 1);
+ data.output_seg_quant_s[i] = 4 * (i + 1);
+ data.output_seg_quant_type[i] = DATA_TYPE_QSYMM16;
+ }
+
+ data.weight_seg_idx = data.segment_num - 1;
+
+ EXPECT_EQ (model->setMetadata (&data), 0);
+
+ const Metadata * meta = model->getMetadata ();
+ EXPECT_NE (meta, nullptr);
+
+ EXPECT_EQ (meta->getVersion (), 3);
+ EXPECT_EQ (meta->getBufferSize(), data.buffer_size);
+ EXPECT_EQ (meta->getProgramSize(), data.program_size);
+ EXPECT_EQ (meta->getWeightSize(), data.weight_size);
+
+ EXPECT_EQ (meta->getInputNum (), input_num);
+ for (uint32_t i = 0; i < meta->getInputNum (); i++) {
+ uint32_t size = meta->getInputElemSize (i);
+ EXPECT_EQ (meta->getInputOffset (i), 0);
+ EXPECT_EQ (meta->getInputElemSize (i), get_data_size (DATA_TYPE_QASYMM8));
+ for (uint32_t j = 0; j < MAX_RANK; j++) {
+ EXPECT_EQ (meta->getInputDims(i)[j], 2 * (i + 1));
+ size *= meta->getInputDims(i)[j];
+ }
+ EXPECT_EQ (meta->getInputQuantZero (i), 3 * (i + 1));
+ EXPECT_EQ (meta->getInputQuantScale (i), 4 * (i + 1));
+ EXPECT_EQ (meta->getInputQuantType (i), DATA_TYPE_QASYMM8);
+
+ EXPECT_EQ (meta->getInputTensorSize (i, DATA_LAYOUT_NHWC), size);
+ }
+
+ EXPECT_EQ (meta->getOutputNum (), output_num);
+ for (uint32_t i = 0; i < meta->getOutputNum (); i++) {
+ uint32_t size = meta->getOutputElemSize (i);
+ EXPECT_EQ (meta->getOutputOffset (i), 0);
+ EXPECT_EQ (meta->getOutputElemSize (i), get_data_size (DATA_TYPE_QSYMM16));
+ for (uint32_t j = 0; j < MAX_RANK; j++) {
+ EXPECT_EQ (meta->getOutputDims(i)[j], 2 * (i + 1));
+ size *= meta->getOutputDims(i)[j];
+ }
+ EXPECT_EQ (meta->getOutputQuantZero (i), 3 * (i + 1));
+ EXPECT_EQ (meta->getOutputQuantScale (i), 4 * (i + 1));
+ EXPECT_EQ (meta->getOutputQuantType (i), DATA_TYPE_QSYMM16);
+
+ EXPECT_EQ (meta->getOutputTensorSize (i, DATA_LAYOUT_NHWC), size);
+ }
+}
+
+/**
* @brief model alloc without driver api
*/
TEST (ne_core_model_test, model_alloc_no_drv_api_n)