From: Павел Ильютченко/AI Tools Lab /SRR/Engineer/삼성전자 Date: Thu, 1 Aug 2019 17:01:13 +0000 (+0300) Subject: [mir2loco] Support Const operation (#5794) X-Git-Tag: submit/tizen/20190809.050447~242 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d53495a7397d71c17550db9666070ce3cbf85892;p=platform%2Fcore%2Fml%2Fnnfw.git [mir2loco] Support Const operation (#5794) * Support Const operation transformation * Append test with Const op containing float values Signed-off-by: Pavel Iliutchenko --- diff --git a/compiler/mir2loco/src/mir2loco.cpp b/compiler/mir2loco/src/mir2loco.cpp index b2031b7..17e9d22 100644 --- a/compiler/mir2loco/src/mir2loco.cpp +++ b/compiler/mir2loco/src/mir2loco.cpp @@ -17,12 +17,15 @@ #include "mir2loco.h" #include "mir/ops/ConcatOp.h" +#include "mir/ops/ConstantOp.h" #include "mir/ops/PoolOp.h" #include "mir/ops/ReluOp.h" #include "mir/ops/ReshapeOp.h" #include +#include + namespace mir2loco { namespace @@ -95,6 +98,26 @@ loco::FeatureDecode *createNHWCFeatureDecode(loco::Graph *graph) decode_node->decoder(std::move(dec)); return decode_node; } + +loco::DataType DTYPE2DataType(const mir::DTYPE &dtype) +{ + switch (dtype) + { + case mir::DTYPE::UNKNOWN: + return loco::DataType::Unknown; + case mir::DTYPE::FLOAT32: + return loco::DataType::FLOAT32; + case mir::DTYPE::FLOAT64: + return loco::DataType::FLOAT64; + case mir::DTYPE::INT32: + return loco::DataType::S32; + case mir::DTYPE::INT64: + return loco::DataType::S64; + default: + break; + } + throw std::runtime_error("Unsupported dtype"); +} } // namespace void Transformer::visit(mir::ops::BatchNormOp &op) { throw std::runtime_error("NYI"); } @@ -135,7 +158,27 @@ void Transformer::visit(mir::ops::ConcatOp &op) _mir2loco_map.emplace(&op, last_concat); } -void Transformer::visit(mir::ops::ConstantOp &op) { throw std::runtime_error("NYI"); } +void Transformer::visit(mir::ops::ConstantOp &op) +{ + auto const_node = _loco_graph->nodes()->create(); + // Not set Input + // Set Shape + const auto &out_shape = op.getOutputShape(0); + setupShape(out_shape, const_node); + // Copy value + const auto &value = op.getValue(); + const_node->dtype(DTYPE2DataType(value.getDataType())); + // TODO Support other data types + assert(const_node->dtype() == loco::DataType::FLOAT32); + const_node->size(out_shape.numElements()); + // TODO Change that when loco support other DataTypeImpl + float &const_float = const_node->at(0); + char *loco_ptr = reinterpret_cast(&const_float); + char *mir_ptr = value.at(mir::Index(out_shape.rank())); + std::memcpy(loco_ptr, mir_ptr, out_shape.numElements() * sizeof(float)); + // Add to map + _mir2loco_map.emplace(&op, const_node); +} void Transformer::visit(mir::ops::Conv2DOp &op) { throw std::runtime_error("NYI"); } diff --git a/compiler/mir2loco/src/mir2loco.test.cpp b/compiler/mir2loco/src/mir2loco.test.cpp index b274644..dcc85e1 100644 --- a/compiler/mir2loco/src/mir2loco.test.cpp +++ b/compiler/mir2loco/src/mir2loco.test.cpp @@ -17,6 +17,7 @@ #include "mir2loco.h" #include "mir/ops/ConcatOp.h" +#include "mir/ops/ConstantOp.h" #include "mir/ops/PoolOp.h" #include "mir/ops/ReluOp.h" #include "mir/ops/ReshapeOp.h" @@ -248,3 +249,30 @@ TEST_F(TestTransformer_mir2loco, Reshape_Test) ASSERT_EQ(reshape_node->dim(1), 8); ASSERT_EQ(reshape_node->dim(2), 81); } + +TEST_F(TestTransformer_mir2loco, Const_Float_Test) +{ + mir::Graph mir_graph; + + mir::Shape shape = mir::Shape({2, 3}); + const float data[] = {5.9, 6.7, 5.32, 54.11231, 43.2444, 3.409}; + auto mir_tensor = mir::TensorVariant(mir::DTYPE::FLOAT32, shape, (const void *)data); + auto *constant = mir_graph.create("constant", mir_tensor); + auto *output = mir_graph.create("output", constant->getOutput(0)); + + mir2loco::Transformer transformer; + auto loco_graph = transformer.transform(&mir_graph); + loco::ConstGen *const_node = dynamic_cast(loco_graph->nodes()->at(0)); + loco::Push *push_node = dynamic_cast(loco_graph->nodes()->at(1)); + + ASSERT_NE(const_node, nullptr); + ASSERT_NE(push_node, nullptr); + ASSERT_EQ(push_node->from(), const_node); + // Shape check + ASSERT_EQ(const_node->rank(), 2); + ASSERT_EQ(const_node->dim(0), 2); + ASSERT_EQ(const_node->dim(1), 3); + + for (int i = 0; i < 6; i++) + ASSERT_FLOAT_EQ(const_node->at(i), data[i]); +}