From 2c11ff3beb61bf57c4c24dc44d2e65f71611739f Mon Sep 17 00:00:00 2001 From: =?utf8?q?=EC=9C=A4=ED=98=84=EC=8B=9D/On-Device=20Lab=28SR=29/Princip?= =?utf8?q?al=20Engineer/=EC=82=BC=EC=84=B1=EC=A0=84=EC=9E=90?= Date: Wed, 10 Apr 2019 17:40:43 +0900 Subject: [PATCH] [nnkit/TF] Parser to parse test.info under contrib/moco/test/tf (#3199) * [enco/TF] Parser to parse test.info under contrib/moco/test/tf This is a parser code to oarse test.info. Signed-off-by: Hyun Sik Yoon * modify macro and add TODO --- .../tf/include/nnkit/support/tf/TensorInfoParser.h | 46 ++++++ .../nnkit/libs/support/tf/src/TensorInfoParser.cpp | 158 +++++++++++++++++++++ 2 files changed, 204 insertions(+) create mode 100644 contrib/nnkit/libs/support/tf/include/nnkit/support/tf/TensorInfoParser.h create mode 100644 contrib/nnkit/libs/support/tf/src/TensorInfoParser.cpp diff --git a/contrib/nnkit/libs/support/tf/include/nnkit/support/tf/TensorInfoParser.h b/contrib/nnkit/libs/support/tf/include/nnkit/support/tf/TensorInfoParser.h new file mode 100644 index 0000000..9b7a165 --- /dev/null +++ b/contrib/nnkit/libs/support/tf/include/nnkit/support/tf/TensorInfoParser.h @@ -0,0 +1,46 @@ +/* + * 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. + */ + +/** + * @file TensorInfoParser.h + * @brief This file contains functions to parse tensor.info files in moco/test/tf + */ + +#ifndef __NNKIT_SUPPORT_TF_TENSOR_INFO_PARSER_H__ +#define __NNKIT_SUPPORT_TF_TENSOR_INFO_PARSER_H__ + +#include "nnkit/support/tf/ParsedTensor.h" + +#include +#include + +namespace nnkit +{ +namespace support +{ +namespace tf +{ + +/** + * @brief Function to parse test.info + */ +std::vector> parse(const char* info_path); + +} // namespace tf +} // namespace support +} // namespace nnkit + +#endif // __NNKIT_SUPPORT_TF_TENSOR_INFO_PARSER_H__ diff --git a/contrib/nnkit/libs/support/tf/src/TensorInfoParser.cpp b/contrib/nnkit/libs/support/tf/src/TensorInfoParser.cpp new file mode 100644 index 0000000..c2e447f --- /dev/null +++ b/contrib/nnkit/libs/support/tf/src/TensorInfoParser.cpp @@ -0,0 +1,158 @@ +/* + * 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 "nnkit/support/tf/TensorInfoParser.h" + +#include +#include + +#include + +#include +#include +#include +#include +#include + +// debug +#include + +/** + * @file TensorInfoParser.cpp + * @brief This file contains functions to parse tensor.info files in moco/test/tf + */ + +namespace nnkit +{ +namespace support +{ +namespace tf +{ + +ParsedTensor::Kind get_kind(const char *tok) +{ + if (strcmp(tok, "input") == 0) + return ParsedTensor::Kind::Input; + else if (strcmp(tok, "output") == 0) + return ParsedTensor::Kind::Output; + else + throw std::runtime_error("A line must be either 'input' or 'output':"); +} + +TF_DataType get_dtype(const char *dtype) +{ + if (strcmp(dtype, "TF_FLOAT") == 0) + return TF_FLOAT; + else + throw std::runtime_error(std::string("Unsupported tensor datatype: ") + dtype); +} + +/** + * @brief Function to parse a line of test.info file + * Examples: + * - "input, in/placeholder_32:0, TF_INT32, [3, 4, 2, 3]" + * - "output, result:0, TF_FLOAT, []" + */ +std::unique_ptr parse_line(char *line) +{ + // parsed data + ParsedTensor::Kind kind; + std::string name; + TF_DataType dtype; + std::vector shape; + + // parsing steps + enum Step { PLS_KIND = 0, PLS_TENSOR_NAME, PLS_DATA_TYPE, PLS_SHAPE_DIM }; + + int step = PLS_KIND; + + char delimeter[] = " ,[]\t\n"; + + // split line with token + char *tok = strtok(line, delimeter); + + if (tok == NULL) // line with no token. e.g., line == "" + return nullptr; + + // tok will be when there is no parsed token. Empty line will also have no token. + while (tok != NULL) + { + if (tok[0] == '#') // '#' means comment + { + if (step == PLS_KIND) // line starting with # + return nullptr; + else + break; + } + + if (step == PLS_KIND) + { + kind = get_kind(tok); + step++; + } + else if (step == PLS_TENSOR_NAME) + { + name.assign(tok); + step++; + } + else if (step == PLS_DATA_TYPE) + { + dtype = get_dtype(tok); + step++; + } + else if (step == PLS_SHAPE_DIM) + { + shape.emplace_back(std::stoi(tok)); + } + else + throw std::runtime_error("Unknown parsing step"); + + tok = strtok(NULL, delimeter); // get next token + } + + assert(step == PLS_SHAPE_DIM); + + return stdex::make_unique(kind, name, dtype, shape); +} + +std::vector> parse(const char* info_path) +{ + std::vector> tensors; + + const int line_len = 512; + + FILE *fp; // TODO make C++ wrapper that close fp when any exception is thrown + char line[line_len]; + + fp = fopen(info_path, "r"); + if (fp == NULL) + throw std::runtime_error(std::string("cannot open file : ") + info_path); + + while (fgets(line, line_len, fp) != NULL) // read one line + { + auto tensor = parse_line(line); + if (tensor) + tensors.emplace_back(std::move(tensor)); + } + + fclose(fp); + + return tensors; +} + +} // namespace tf +} // namespace support +} // namespace nnkit -- 2.7.4