From 81c33212439e564238fa62d16410b0e929bc70dc Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9D=B4=EC=83=81=EA=B7=9C/On-Device=20Lab=28SR=29/Princip?= =?utf8?q?al=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 4 Dec 2019 12:27:53 +0900 Subject: [PATCH] [nnpkg_run] Bring out h5 load/dump, allocation to separate files (#9342) nnpackge_run grows bigger and bigger. This patch factor out the feature implementation into separate files. Signed-off-by: Sanggyu Lee --- tests/tools/nnpackage_run/CMakeLists.txt | 2 + tests/tools/nnpackage_run/src/allocation.h | 37 +++++++ tests/tools/nnpackage_run/src/h5formatter.cc | 118 ++++++++++++++++++++ tests/tools/nnpackage_run/src/h5formatter.h | 41 +++++++ tests/tools/nnpackage_run/src/nnfw_util.cc | 45 ++++++++ tests/tools/nnpackage_run/src/nnfw_util.h | 37 +++++++ tests/tools/nnpackage_run/src/nnpackage_run.cc | 142 ++----------------------- 7 files changed, 290 insertions(+), 132 deletions(-) create mode 100644 tests/tools/nnpackage_run/src/allocation.h create mode 100644 tests/tools/nnpackage_run/src/h5formatter.cc create mode 100644 tests/tools/nnpackage_run/src/h5formatter.h create mode 100644 tests/tools/nnpackage_run/src/nnfw_util.cc create mode 100644 tests/tools/nnpackage_run/src/nnfw_util.h diff --git a/tests/tools/nnpackage_run/CMakeLists.txt b/tests/tools/nnpackage_run/CMakeLists.txt index 671aa95..743df7f 100644 --- a/tests/tools/nnpackage_run/CMakeLists.txt +++ b/tests/tools/nnpackage_run/CMakeLists.txt @@ -17,6 +17,8 @@ list(APPEND HDF5_CXX_LIBRARIES aec) list(APPEND NNPACKAGE_RUN_SRCS "src/nnpackage_run.cc") list(APPEND NNPACKAGE_RUN_SRCS "src/args.cc") +list(APPEND NNPACKAGE_RUN_SRCS "src/h5formatter.cc") +list(APPEND NNPACKAGE_RUN_SRCS "src/nnfw_util.cc") nnas_find_package(Boost REQUIRED) diff --git a/tests/tools/nnpackage_run/src/allocation.h b/tests/tools/nnpackage_run/src/allocation.h new file mode 100644 index 0000000..efd7f12 --- /dev/null +++ b/tests/tools/nnpackage_run/src/allocation.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNPACKAGE_RUN_ALLOCATION_H__ +#define __NNPACKAGE_RUN_ALLOCATION_H__ + +#include +#include + +namespace NNPackageRun +{ +class Allocation +{ +public: + Allocation() : data_(nullptr) {} + ~Allocation() { free(data_); } + void *data() const { return data_; } + void *alloc(uint64_t sz) { return data_ = malloc(sz); } +private: + void *data_; +}; +} // end of namespace + +#endif // __NNPACKAGE_RUN_ALLOCATION_H__ diff --git a/tests/tools/nnpackage_run/src/h5formatter.cc b/tests/tools/nnpackage_run/src/h5formatter.cc new file mode 100644 index 0000000..c2bfdfc --- /dev/null +++ b/tests/tools/nnpackage_run/src/h5formatter.cc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "h5formatter.h" +#include "nnfw.h" +#include "nnfw_util.h" + +#include +#include +#include +#include +#include + +namespace NNPackageRun +{ +static const char *h5_value_grpname = "value"; + +void H5Formatter::loadInputs(const std::string &filename, std::vector &inputs) +{ + uint32_t num_inputs; + NNPR_ENSURE_STATUS(nnfw_input_size(session, &num_inputs)); + try + { + // Turn off the automatic error printing. + H5::Exception::dontPrint(); + + H5::H5File file(filename, H5F_ACC_RDONLY); + H5::Group value_group = file.openGroup(h5_value_grpname); + for (uint32_t i = 0; i < num_inputs; ++i) + { + nnfw_tensorinfo ti; + NNPR_ENSURE_STATUS(nnfw_input_tensorinfo(session, i, &ti)); + + H5::DataSet data_set = value_group.openDataSet(std::to_string(i)); + + // check type + H5::DataType type = data_set.getDataType(); + if (!(type == H5::PredType::IEEE_F32BE || type == H5::PredType::IEEE_F32LE)) + { + throw std::runtime_error("h5 input has non-float32 type. nnpkg_run supports float32 only."); + } + + // allocate memory for data + auto sz = num_elems(&ti); + inputs[i].alloc(sz * sizeof(float)); + // read data + data_set.read(inputs[i].data(), H5::PredType::NATIVE_FLOAT); + + NNPR_ENSURE_STATUS(nnfw_set_input(session, i, NNFW_TYPE_TENSOR_FLOAT32, inputs[i].data(), + sizeof(float) * num_elems(&ti))); + NNPR_ENSURE_STATUS(nnfw_set_input_layout(session, i, NNFW_LAYOUT_CHANNELS_LAST)); + } + } + catch (const H5::Exception &e) + { + H5::Exception::printErrorStack(); + std::exit(-1); + } + catch (const std::exception &e) + { + std::cerr << e.what() << std::endl; + std::exit(-1); + } +}; + +void H5Formatter::dumpOutputs(const std::string &filename, std::vector &outputs) +{ + uint32_t num_outputs; + NNPR_ENSURE_STATUS(nnfw_output_size(session, &num_outputs)); + try + { + // Turn off the automatic error printing. + H5::Exception::dontPrint(); + + H5::H5File file(filename, H5F_ACC_TRUNC); + H5::Group value_group = file.createGroup(h5_value_grpname); + for (uint32_t i = 0; i < num_outputs; i++) + { + nnfw_tensorinfo ti; + NNPR_ENSURE_STATUS(nnfw_output_tensorinfo(session, i, &ti)); + std::vector dims(ti.rank); + for (uint32_t j = 0; j < ti.rank; ++j) + { + if (ti.dims[j] >= 0) + dims[j] = static_cast(ti.dims[j]); + else + { + std::cerr << "Negative dimension in output tensor" << std::endl; + exit(-1); + } + } + H5::DataSpace data_space(ti.rank, dims.data()); + H5::DataSet data_set = + value_group.createDataSet(std::to_string(i), H5::PredType::IEEE_F32BE, data_space); + data_set.write(outputs[i].data(), H5::PredType::NATIVE_FLOAT); + } + } + catch (const H5::Exception &e) + { + H5::Exception::printErrorStack(); + std::exit(-1); + } +}; + +} // end of namespace NNPackageRun diff --git a/tests/tools/nnpackage_run/src/h5formatter.h b/tests/tools/nnpackage_run/src/h5formatter.h new file mode 100644 index 0000000..a59e941 --- /dev/null +++ b/tests/tools/nnpackage_run/src/h5formatter.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNPACKAGE_RUN_H5FORMATTER_H__ +#define __NNPACKAGE_RUN_H5FORMATTER_H__ + +#include +#include + +#include "allocation.h" + +struct nnfw_session; + +namespace NNPackageRun +{ +class H5Formatter +{ +public: + H5Formatter(nnfw_session *sess) : session(sess) {} + void loadInputs(const std::string &filename, std::vector &inputs); + void dumpOutputs(const std::string &filename, std::vector &outputs); + +private: + nnfw_session *session; +}; +} // end of namespace + +#endif // __NNPACKAGE_RUN_H5FORMATTER_H__ diff --git a/tests/tools/nnpackage_run/src/nnfw_util.cc b/tests/tools/nnpackage_run/src/nnfw_util.cc new file mode 100644 index 0000000..78cd65f --- /dev/null +++ b/tests/tools/nnpackage_run/src/nnfw_util.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "nnfw.h" + +namespace NNPackageRun +{ +uint64_t num_elems(const nnfw_tensorinfo *ti) +{ + uint64_t n = 1; + for (uint32_t i = 0; i < ti->rank; ++i) + { + assert(ti->dims[i] >= 0); + n *= ti->dims[i]; + } + return n; +} + +uint64_t bufsize_for(const nnfw_tensorinfo *ti) +{ + static int elmsize[] = { + sizeof(float), /* NNFW_TYPE_TENSOR_FLOAT32 */ + sizeof(int), /* NNFW_TYPE_TENSOR_INT32 */ + sizeof(char), /* NNFW_TYPE_TENSOR_QUANT8_ASYMM */ + sizeof(bool), /* NNFW_TYPE_TENSOR_BOOL = 3 */ + }; + return elmsize[ti->dtype] * num_elems(ti); +} + +} // end of namespace \ No newline at end of file diff --git a/tests/tools/nnpackage_run/src/nnfw_util.h b/tests/tools/nnpackage_run/src/nnfw_util.h new file mode 100644 index 0000000..8d1260b --- /dev/null +++ b/tests/tools/nnpackage_run/src/nnfw_util.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NNPACKAGE_RUN_NNFW_UTIL_H__ +#define __NNPACKAGE_RUN_NNFW_UTIL_H__ + +#include "nnfw.h" + +#define NNPR_ENSURE_STATUS(a) \ + do \ + { \ + if ((a) != NNFW_STATUS_NO_ERROR) \ + { \ + exit(-1); \ + } \ + } while (0) + +namespace NNPackageRun +{ +uint64_t num_elems(const nnfw_tensorinfo *ti); +uint64_t bufsize_for(const nnfw_tensorinfo *ti); +} // end of namespace nnpkg_run + +#endif // __NNPACKAGE_UTIL_H__ diff --git a/tests/tools/nnpackage_run/src/nnpackage_run.cc b/tests/tools/nnpackage_run/src/nnpackage_run.cc index d84bad2..d42f251 100644 --- a/tests/tools/nnpackage_run/src/nnpackage_run.cc +++ b/tests/tools/nnpackage_run/src/nnpackage_run.cc @@ -14,12 +14,13 @@ * limitations under the License. */ +#include "allocation.h" #include "args.h" +#include "benchmark.h" +#include "h5formatter.h" #include "tflite/Diff.h" #include "nnfw.h" -#include "benchmark.h" - -#include +#include "nnfw_util.h" #include #include @@ -30,58 +31,15 @@ #include -#define NNPR_ENSURE_STATUS(a) \ - do \ - { \ - if ((a) != NNFW_STATUS_NO_ERROR) \ - { \ - exit(-1); \ - } \ - } while (0) - -namespace -{ - -uint64_t num_elems(const nnfw_tensorinfo *ti) +namespace NNPackageRun { - uint64_t n = 1; - for (uint32_t i = 0; i < ti->rank; ++i) - { - assert(ti->dims[i] >= 0); - n *= ti->dims[i]; - } - return n; -} - -uint64_t bufsize_for(const nnfw_tensorinfo *ti) -{ - static int elmsize[] = { - sizeof(float), /* NNFW_TYPE_TENSOR_FLOAT32 */ - sizeof(int), /* NNFW_TYPE_TENSOR_INT32 */ - sizeof(char), /* NNFW_TYPE_TENSOR_QUANT8_ASYMM */ - sizeof(bool), /* NNFW_TYPE_TENSOR_BOOL = 3 */ - }; - return elmsize[ti->dtype] * num_elems(ti); -} template void randomData(RandomGenerator &randgen, void *data, uint64_t size) { for (uint64_t i = 0; i < size; i++) reinterpret_cast(data)[i] = randgen.generate(); } - -class Allocation -{ -public: - Allocation() : data_(nullptr) {} - ~Allocation() { free(data_); } - void *data() const { return data_; } - void *alloc(uint64_t sz) { return data_ = malloc(sz); } -private: - void *data_; -}; - -} // unnamed namespace +} // TODO Replace this with nnfw::misc::benchmark::Accumulator namespace benchmark @@ -113,7 +71,6 @@ private: } // namespace benchmark -static const char *h5_value_grpname = "value"; static const char *default_backend_cand = "acl_cl"; NNFW_STATUS resolve_op_backend(nnfw_session *session) @@ -140,7 +97,8 @@ NNFW_STATUS resolve_op_backend(nnfw_session *session) int main(const int argc, char **argv) { - NNPackageRun::Args args(argc, argv); + using namespace NNPackageRun; + Args args(argc, argv); auto nnpackage_path = args.getPackageFilename(); std::unique_ptr mp{nullptr}; @@ -219,55 +177,8 @@ int main(const int argc, char **argv) mp_results[0] = mp->End("Compiling"); // prepare input - std::vector inputs(num_inputs); - auto loadInputs = [session, num_inputs, &inputs](const std::string &filename) { - try - { - // Turn off the automatic error printing. - H5::Exception::dontPrint(); - - H5::H5File file(filename, H5F_ACC_RDONLY); - H5::Group value_group = file.openGroup(h5_value_grpname); - for (uint32_t i = 0; i < num_inputs; ++i) - { - nnfw_tensorinfo ti; - NNPR_ENSURE_STATUS(nnfw_input_tensorinfo(session, i, &ti)); - - H5::DataSet data_set = value_group.openDataSet(std::to_string(i)); - - // check type - H5::DataType type = data_set.getDataType(); - if (!(type == H5::PredType::IEEE_F32BE || type == H5::PredType::IEEE_F32LE)) - { - throw std::runtime_error( - "h5 input has non-float32 type. nnpkg_run supports float32 only."); - } - - // allocate memory for data - auto sz = num_elems(&ti); - inputs[i].alloc(sz * sizeof(float)); - // read data - data_set.read(inputs[i].data(), H5::PredType::NATIVE_FLOAT); - - NNPR_ENSURE_STATUS(nnfw_set_input(session, i, NNFW_TYPE_TENSOR_FLOAT32, inputs[i].data(), - sizeof(float) * num_elems(&ti))); - NNPR_ENSURE_STATUS(nnfw_set_input_layout(session, i, NNFW_LAYOUT_CHANNELS_LAST)); - } - } - catch (const H5::Exception &e) - { - H5::Exception::printErrorStack(); - std::exit(-1); - } - catch (const std::exception &e) - { - std::cerr << e.what() << std::endl; - std::exit(-1); - } - }; - auto generateInputs = [session, num_inputs, &inputs]() { // generate random data const int seed = 1; @@ -295,9 +206,8 @@ int main(const int argc, char **argv) NNPR_ENSURE_STATUS(nnfw_set_input_layout(session, i, NNFW_LAYOUT_CHANNELS_LAST)); } }; - if (!args.getLoadFilename().empty()) - loadInputs(args.getLoadFilename()); + H5Formatter(session).loadInputs(args.getLoadFilename(), inputs); else generateInputs(); @@ -350,40 +260,8 @@ int main(const int argc, char **argv) } // dump output tensors - - auto dumpOutputs = [session, num_outputs, &outputs](const std::string &filename) { - try - { - // Turn off the automatic error printing. - H5::Exception::dontPrint(); - - H5::H5File file(filename, H5F_ACC_TRUNC); - H5::Group value_group = file.createGroup(h5_value_grpname); - for (uint32_t i = 0; i < num_outputs; i++) - { - nnfw_tensorinfo ti; - NNPR_ENSURE_STATUS(nnfw_output_tensorinfo(session, i, &ti)); - std::vector dims(ti.rank); - for (uint32_t j = 0; j < ti.rank; ++j) - { - assert(ti.dims[j] >= 0); - dims[j] = ti.dims[j]; - } - H5::DataSpace data_space(ti.rank, dims.data()); - H5::DataSet data_set = - value_group.createDataSet(std::to_string(i), H5::PredType::IEEE_F32BE, data_space); - data_set.write(outputs[i].data(), H5::PredType::NATIVE_FLOAT); - } - } - catch (const H5::Exception &e) - { - H5::Exception::printErrorStack(); - std::exit(-1); - } - }; - if (!args.getDumpFilename().empty()) - dumpOutputs(args.getDumpFilename()); + H5Formatter(session).dumpOutputs(args.getDumpFilename(), outputs); NNPR_ENSURE_STATUS(nnfw_close_session(session)); -- 2.7.4