#include "Convert.h"
#include "GraphBuilderContext.h"
#include "GraphBuilderRegistry.h"
+#include "Onnxutil.h"
#include <cwrap/Fildes.h>
}
}
-/**
- * @brief If domain is empty string or onnx.ai, it is default domain
- * @param [in] domain The name of domain
- * @return Whether it is default domain or not
- */
-bool is_default_domain(const std::string domain)
-{
- return (domain.compare("") == 0 || domain.compare("onnx.ai") == 0);
-}
-
-/**
- * @note If the platform is little endian, 0x00112233 would be saved as [0x33, 0x22, 0x11, 0x00]
- * If not, it would be saved as [0x00, 0x11, 0x22, 0x33]
- * @return Whether platform is little endian or not
- */
-bool is_platform_little_endian()
-{
- int32_t num = 0x00112233;
- return (*(char *)&num == 0x33);
-}
-
-/**
- * @brief Get float tensor data
- * @param [in] tensor Tensor to get float data
- * @return Float vector which stores float tensor data
- */
-std::vector<float> get_float_data(const ::onnx::TensorProto tensor)
-{
- std::vector<float> data;
-
- // Exactly one of the fields is used to store the elements of the tensor
- assert(!(tensor.has_raw_data() && (tensor.float_data_size() > 0)));
- assert(tensor.has_raw_data() || (tensor.float_data_size() > 0));
-
- if (tensor.has_raw_data())
- {
- const std::string raw_data = tensor.raw_data();
-
- // If platform is big endian, we should convert data as big endian
- if (!is_platform_little_endian())
- {
- // TODO Revise implementation of this logic. This is too complex.
- const char *little_endian_bytes = raw_data.c_str();
- char *big_endian_bytes = reinterpret_cast<char *>(std::malloc(raw_data.size()));
-
- for (int i = 0; i < raw_data.size(); ++i)
- big_endian_bytes[i] = little_endian_bytes[i];
-
- const size_t element_size = sizeof(float);
- const size_t num_elements = raw_data.size() / element_size;
- for (size_t i = 0; i < num_elements; ++i)
- {
- char *start_byte = big_endian_bytes + i * element_size;
- char *end_byte = start_byte + element_size - 1;
-
- for (size_t count = 0; count < element_size / 2; ++count)
- {
- char temp = *start_byte;
- *start_byte = *end_byte;
- *end_byte = temp;
- ++start_byte;
- --end_byte;
- }
- }
-
- data.insert(data.end(), reinterpret_cast<const float *>(big_endian_bytes),
- reinterpret_cast<const float *>(big_endian_bytes + raw_data.size()));
-
- std::free(big_endian_bytes);
- }
- else
- {
- const char *bytes = raw_data.c_str();
- data.insert(data.end(), reinterpret_cast<const float *>(bytes),
- reinterpret_cast<const float *>(bytes + raw_data.size()));
- }
- }
- else
- {
- for (int i = 0; i < tensor.float_data_size(); ++i)
- data.push_back(tensor.float_data(i));
- }
-
- return data;
-}
-
// TODO Make comments clear
void convert_graph(::onnx::ModelProto &onnx_model_proto, loco::Graph *graph)
{
{
auto opset = onnx_model_proto.opset_import(i);
- if (!opset.has_domain() || is_default_domain(opset.domain()))
+ if (!opset.has_domain() || moco::onnx::is_default_domain(opset.domain()))
{
if (opset.version() > opset_version)
{
initializer_name_set.insert(initializer.name());
// TODO Support other data types
- auto data = get_float_data(initializer);
+ auto data = moco::onnx::get_float_data(initializer);
auto const_node = graph->nodes()->create<loco::ConstGen>();
const_node->dtype(moco::onnx::as_loco_datatype(initializer.data_type()));
--- /dev/null
+/*
+ * 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 "Convert.h"
+
+#include <cassert>
+#include <stdexcept>
+
+namespace
+{
+
+/**
+ * @note If the platform is little endian, 0x00112233 would be saved as [0x33, 0x22, 0x11, 0x00]
+ * If not, it would be saved as [0x00, 0x11, 0x22, 0x33]
+ * @return Whether platform is little endian or not
+ */
+bool is_platform_little_endian()
+{
+ int32_t num = 0x00112233;
+ return (*(char *)&num == 0x33);
+}
+
+} // namespace
+
+namespace moco
+{
+namespace onnx
+{
+
+bool is_default_domain(const std::string domain)
+{
+ return (domain.compare("") == 0 || domain.compare("onnx.ai") == 0);
+}
+
+std::vector<float> get_float_data(const ::onnx::TensorProto &tensor)
+{
+ std::vector<float> data;
+
+ // Exactly one of the fields is used to store the elements of the tensor
+ assert(!(tensor.has_raw_data() && (tensor.float_data_size() > 0)));
+ assert(tensor.has_raw_data() || (tensor.float_data_size() > 0));
+
+ if (tensor.has_raw_data())
+ {
+ const std::string raw_data = tensor.raw_data();
+
+ // If platform is big endian, we should convert data as big endian
+ if (!is_platform_little_endian())
+ {
+ // TODO Revise implementation of this logic. This is too complex.
+ const char *little_endian_bytes = raw_data.c_str();
+ char *big_endian_bytes = reinterpret_cast<char *>(std::malloc(raw_data.size()));
+
+ for (int i = 0; i < raw_data.size(); ++i)
+ big_endian_bytes[i] = little_endian_bytes[i];
+
+ const size_t element_size = sizeof(float);
+ const size_t num_elements = raw_data.size() / element_size;
+ for (size_t i = 0; i < num_elements; ++i)
+ {
+ char *start_byte = big_endian_bytes + i * element_size;
+ char *end_byte = start_byte + element_size - 1;
+
+ for (size_t count = 0; count < element_size / 2; ++count)
+ {
+ char temp = *start_byte;
+ *start_byte = *end_byte;
+ *end_byte = temp;
+ ++start_byte;
+ --end_byte;
+ }
+ }
+
+ data.insert(data.end(), reinterpret_cast<const float *>(big_endian_bytes),
+ reinterpret_cast<const float *>(big_endian_bytes + raw_data.size()));
+
+ std::free(big_endian_bytes);
+ }
+ else
+ {
+ const char *bytes = raw_data.c_str();
+ data.insert(data.end(), reinterpret_cast<const float *>(bytes),
+ reinterpret_cast<const float *>(bytes + raw_data.size()));
+ }
+ }
+ else
+ {
+ for (int i = 0; i < tensor.float_data_size(); ++i)
+ data.push_back(tensor.float_data(i));
+ }
+
+ return data;
+}
+
+} // namespace onnx
+} // namespace moco
--- /dev/null
+/*
+ * 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 __MOCO_FRONTEND_ONNX_ONNXUTIL_H__
+#define __MOCO_FRONTEND_ONNX_ONNXUTIL_H__
+
+#include <onnx/onnx.pb.h>
+
+#include <string>
+
+namespace moco
+{
+namespace onnx
+{
+
+/**
+ * @brief If domain is empty string or onnx.ai, it is default domain
+ * @param [in] domain The name of domain
+ * @return Whether it is default domain or not
+ */
+bool is_default_domain(const std::string domain);
+
+/**
+ * @brief Get float tensor data
+ * @param [in] tensor Tensor to get float data
+ * @return Float vector which stores float tensor data
+ */
+std::vector<float> get_float_data(const ::onnx::TensorProto &tensor);
+
+} // namespace onnx
+} // namespace moco
+
+#endif // __MOCO_FRONTEND_ONNX_ONNXUTIL_H__