diff options
Diffstat (limited to 'compiler/nnc/backends/soft_backend')
-rw-r--r-- | compiler/nnc/backends/soft_backend/BaseGenerator.cpp | 132 | ||||
-rw-r--r-- | compiler/nnc/backends/soft_backend/CGenerator.cpp | 41 | ||||
-rw-r--r-- | compiler/nnc/backends/soft_backend/CMakeLists.txt | 28 | ||||
-rw-r--r-- | compiler/nnc/backends/soft_backend/CPPGenerator.cpp | 98 |
4 files changed, 101 insertions, 198 deletions
diff --git a/compiler/nnc/backends/soft_backend/BaseGenerator.cpp b/compiler/nnc/backends/soft_backend/BaseGenerator.cpp deleted file mode 100644 index 94afd690d..000000000 --- a/compiler/nnc/backends/soft_backend/BaseGenerator.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2018 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 "backends/soft_backend/BaseGenerator.h" -#include "ModelAnalyzer.h" -#include "SBSerializer.h" -#include "option/Options.h" -#include "CommonData.def" - -#include <sys/stat.h> - -#include <cerrno> -#include <cstring> -#include <fstream> -#include <memory> -#include <stdexcept> -#include <fcntl.h> - -using namespace std; - -namespace nnc -{ - -namespace -{ - -/** - * @brief Creates pointer to some output stream to encapsulate resource management into deleter - * for example may be used to return std::cout - * @param path Path to opened file - * @return Pointer output stream - * @throws PluginException if did not succeed - */ -unique_ptr<ofstream> getStream(const string &path) -{ - unique_ptr<ofstream> ofs(new ofstream(path)); - if (ofs->fail()) - throw std::runtime_error("Can not open code output file: " + path); - return ofs; -} - -/** - * @brief Creates directory - * @param path Path to desired directory - * @throws PluginException in did not succeed - */ -void createDir(const string &path) -{ - int res = - mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // NOLINT(hicpp-signed-bitwise) - if (res != 0 && errno != EEXIST) - throw std::runtime_error("Failed to create output directory"); -} - -} // unnamed namespace - -BaseCodeGenerator::BaseCodeGenerator() -{ - string base_path = cli::artifactDir + "/" + cli::artifactName; - _headerPath = base_path + ".h"; - _codePath = base_path + ".cpp"; - _paramsPath = base_path + ".params"; -} - -void BaseCodeGenerator::materializeModelParams(ostream &out, const Serializer &s) -{ - using namespace params; - - // First form a dump header - char header[HEADER_LEN]; - uint32_t version = s.getFormatVersion(); - uint32_t hash = s.getModelHash(); - static_assert(VERSION_LEN == sizeof(version), "version length mismatch"); - static_assert(HASH_LEN == sizeof(hash), "hash length mismatch"); - memcpy(header, MAGIC, MAGIC_LEN); - memcpy(header + MAGIC_LEN, &version, VERSION_LEN); - memcpy(header + MAGIC_LEN + VERSION_LEN, &hash, HASH_LEN); - - out.write(header, HEADER_LEN); - if (out.fail()) - throw std::runtime_error("Failed to write model parameters header"); - auto ¶ms = s.getBuffer(); - out.write(params.data(), params.size()); - if (out.fail()) - throw std::runtime_error("Failed to write model Parameters"); -} - -void BaseCodeGenerator::run(mir::Graph *graph) -{ - assert(graph); - - // visit and analyze graph - ModelAnalyzer ma; - ma.analyze(graph); - // serialize parameters - Serializer serializer; - serializer.serialize(ma.getInferenceSequence()); - // rename tensors for specific backend language - formatTensorNames(ma); - - createDir(cli::artifactDir); - - // Print header - auto header_stream = getStream(_headerPath); - materializeHeader(*header_stream, ma); - header_stream.reset(); - - // Print code - auto code_stream = getStream(_codePath); - materializeCode(*code_stream, ma, serializer); - code_stream.reset(); - - // Print model parameters - auto model_stream = getStream(_paramsPath); - materializeModelParams(*model_stream, serializer); - model_stream.reset(); -} - -} // namespace nnc diff --git a/compiler/nnc/backends/soft_backend/CGenerator.cpp b/compiler/nnc/backends/soft_backend/CGenerator.cpp deleted file mode 100644 index 234234907..000000000 --- a/compiler/nnc/backends/soft_backend/CGenerator.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2018 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 "backends/soft_backend/CGenerator.h" -#include "ModelAnalyzer.h" - -using namespace std; - -namespace nnc -{ - -void CCodeGenerator::formatTensorNames(const ModelAnalyzer & /*ma*/) -{ - // TODO format tensor names according to c backend requirements -} - -void CCodeGenerator::materializeHeader(ostream & /*out*/, const ModelAnalyzer & /*ma*/) -{ - // TODO emit C header to out stream -} - -void CCodeGenerator::materializeCode(ostream & /*out*/, const ModelAnalyzer & /*ma*/, - const Serializer & /*s*/) -{ - // TODO emit C code to out stream -} - -} // namespace nnc diff --git a/compiler/nnc/backends/soft_backend/CMakeLists.txt b/compiler/nnc/backends/soft_backend/CMakeLists.txt index 185f90fea..c1f1fa6ce 100644 --- a/compiler/nnc/backends/soft_backend/CMakeLists.txt +++ b/compiler/nnc/backends/soft_backend/CMakeLists.txt @@ -1,29 +1,13 @@ -set(SOFT_BACKEND_COMMON_SOURCES BaseGenerator.cpp ModelAnalyzer.cpp SBSerializer.cpp SequencedIR.cpp) -set(SOFT_BACKEND_CPP_SOURCES CPPGenerator.cpp) -set(SOFT_BACKEND_C_SOURCES CGenerator.cpp) +set(SOFT_BACKEND_CPP_SOURCES CPPGenerator.cpp ModelAnalyzer.cpp SBSerializer.cpp SequencedIR.cpp) file(GLOB_RECURSE SOFT_DEF_SOURCES "*.def") nnc_make_generated_sources("${SOFT_DEF_SOURCES}" ${CMAKE_CURRENT_BINARY_DIR} SOFT_GENERATED_SOURCES) -add_library(soft_backend_common STATIC ${SOFT_BACKEND_COMMON_SOURCES}) -set_property(TARGET soft_backend_common PROPERTY POSITION_INDEPENDENT_CODE ON) -target_include_directories(soft_backend_common PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(soft_backend_common PRIVATE nnc_support) -target_link_libraries(soft_backend_common PRIVATE mir) +nnc_add_library(soft_backend_cpp SHARED ${SOFT_BACKEND_CPP_SOURCES} ${SOFT_GENERATED_SOURCES}) +target_include_directories(soft_backend_cpp PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -function(make_soft_backend NAME) - nnc_add_library(${NAME} SHARED ${ARGN} ${SOFT_GENERATED_SOURCES}) - target_include_directories(${NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) - - target_link_libraries(${NAME} PUBLIC soft_backend_common) - target_link_libraries(${NAME} PRIVATE nnc_support) - target_link_libraries(${NAME} PRIVATE mir) - - # install soft backend c++ library - nnc_install_library(${NAME}) -endfunction(make_soft_backend) - -make_soft_backend(soft_backend_cpp ${SOFT_BACKEND_CPP_SOURCES}) -make_soft_backend(soft_backend_c ${SOFT_BACKEND_C_SOURCES}) +target_link_libraries(soft_backend_cpp PRIVATE nnc_support mir) +# install soft backend c++ library +nnc_install_library(soft_backend_cpp) diff --git a/compiler/nnc/backends/soft_backend/CPPGenerator.cpp b/compiler/nnc/backends/soft_backend/CPPGenerator.cpp index ce7057e15..f2188c3d3 100644 --- a/compiler/nnc/backends/soft_backend/CPPGenerator.cpp +++ b/compiler/nnc/backends/soft_backend/CPPGenerator.cpp @@ -21,8 +21,6 @@ #include "SBSerializer.h" #include "option/Options.h" -using namespace std; - #include "CommonData.def" #include "cpp_header_types.generated.h" @@ -52,12 +50,104 @@ using namespace std; #include "cpp_transpose.generated.h" #include "cpp_gather.generated.h" +#include <cerrno> +#include <cstring> +#include <fstream> +#include <stdexcept> +#include <sys/stat.h> + namespace nnc { using namespace sir; +using namespace std; + +/** + * @brief Creates pointer to some output stream to encapsulate resource management into deleter + * for example may be used to return std::cout + * @param path Path to opened file + * @return Pointer output stream + * @throws runtime_error if did not succeed + */ +static unique_ptr<ofstream> getStream(const string &path) +{ + unique_ptr<ofstream> ofs(new ofstream(path)); + if (ofs->fail()) + throw runtime_error("Can not open code output file: " + path); + return ofs; +} + +/** + * @brief Creates directory + * @param path Path to desired directory + * @throws runtime_error in did not succeed + */ +static void createDir(const string &path) +{ + int res = + mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); // NOLINT(hicpp-signed-bitwise) + if (res != 0 && errno != EEXIST) + throw runtime_error("Failed to create output directory"); +} + +void CPPCodeGenerator::materializeModelParams(ostream &out, const Serializer &s) +{ + using namespace params; + + // First form a dump header + char header[HEADER_LEN]; + uint32_t version = s.getFormatVersion(); + uint32_t hash = s.getModelHash(); + static_assert(VERSION_LEN == sizeof(version), "version length mismatch"); + static_assert(HASH_LEN == sizeof(hash), "hash length mismatch"); + memcpy(header, MAGIC, MAGIC_LEN); + memcpy(header + MAGIC_LEN, &version, VERSION_LEN); + memcpy(header + MAGIC_LEN + VERSION_LEN, &hash, HASH_LEN); + + out.write(header, HEADER_LEN); + if (out.fail()) + throw runtime_error("Failed to write model parameters header"); + auto ¶ms = s.getBuffer(); + out.write(params.data(), params.size()); + if (out.fail()) + throw runtime_error("Failed to write model Parameters"); +} -using TensorType = TensorDescriptor::Type; +void CPPCodeGenerator::run(mir::Graph *graph) +{ + assert(graph); + + // visit and analyze graph + ModelAnalyzer ma; + ma.analyze(graph); + // serialize parameters + Serializer serializer; + serializer.serialize(ma.getInferenceSequence()); + // rename tensors for specific backend language + formatTensorNames(ma); + + createDir(cli::artifactDir); + + const string base_path = cli::artifactDir + "/" + cli::artifactName; + const string header_path = base_path + ".h"; + const string code_path = base_path + ".cpp"; + const string params_path = base_path + ".params"; + + // Print header + auto header_stream = getStream(header_path); + materializeHeader(*header_stream, ma); + header_stream.reset(); + + // Print code + auto code_stream = getStream(code_path); + materializeCode(*code_stream, ma, serializer); + code_stream.reset(); + + // Print model parameters + auto model_stream = getStream(params_path); + materializeModelParams(*model_stream, serializer); + model_stream.reset(); +} /** * @brief Renames tensors with respect to C++ naming conventions @@ -65,6 +155,8 @@ using TensorType = TensorDescriptor::Type; */ void CPPCodeGenerator::formatTensorNames(const ModelAnalyzer &ma) { + using TensorType = TensorDescriptor::Type; + int tmp_tensors = 0; for (const TensorDescriptor &td : ma.getTensors()) { |