diff options
author | 박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com> | 2019-07-18 14:58:51 +0900 |
---|---|---|
committer | GitHub Enterprise <noreply-CODE@samsung.com> | 2019-07-18 14:58:51 +0900 |
commit | dcfc6d1b6089b497608c3c63a564f240a7d247ee (patch) | |
tree | 8f30b3a52a898703019d276b7b14d7c023dd597a /compiler/caffegen | |
parent | 9df0e14167706f46dce5eab712f8961161af9e12 (diff) | |
download | nnfw-dcfc6d1b6089b497608c3c63a564f240a7d247ee.tar.gz nnfw-dcfc6d1b6089b497608c3c63a564f240a7d247ee.tar.bz2 nnfw-dcfc6d1b6089b497608c3c63a564f240a7d247ee.zip |
Rename contrib as compiler (#4342)
* Rename contrib as compiler
This commit renames the top-level contrib directory as "compiler".
Signed-off-by: Jonghyun Park <jh1302.park@samsung.com>
* Fix CMakeLists.txt
Diffstat (limited to 'compiler/caffegen')
-rw-r--r-- | compiler/caffegen/.FORMATCHECKED | 0 | ||||
-rw-r--r-- | compiler/caffegen/CMakeLists.txt | 14 | ||||
-rw-r--r-- | compiler/caffegen/README.md | 45 | ||||
-rw-r--r-- | compiler/caffegen/src/DecodeCommand.cpp | 46 | ||||
-rw-r--r-- | compiler/caffegen/src/DecodeCommand.h | 27 | ||||
-rw-r--r-- | compiler/caffegen/src/Driver.cpp | 42 | ||||
-rw-r--r-- | compiler/caffegen/src/EncodeCommand.cpp | 51 | ||||
-rw-r--r-- | compiler/caffegen/src/EncodeCommand.h | 27 | ||||
-rw-r--r-- | compiler/caffegen/src/InitCommand.cpp | 65 | ||||
-rw-r--r-- | compiler/caffegen/src/InitCommand.h | 27 | ||||
-rw-r--r-- | compiler/caffegen/src/MergeCommand.cpp | 58 | ||||
-rw-r--r-- | compiler/caffegen/src/MergeCommand.h | 33 |
12 files changed, 435 insertions, 0 deletions
diff --git a/compiler/caffegen/.FORMATCHECKED b/compiler/caffegen/.FORMATCHECKED new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/compiler/caffegen/.FORMATCHECKED diff --git a/compiler/caffegen/CMakeLists.txt b/compiler/caffegen/CMakeLists.txt new file mode 100644 index 000000000..5ffc43e46 --- /dev/null +++ b/compiler/caffegen/CMakeLists.txt @@ -0,0 +1,14 @@ +nncc_find_package(Caffe QUIET) + +if(NOT Caffe_FOUND) + return() +endif(NOT Caffe_FOUND) + +file(GLOB_RECURSE SOURCES "src/*.cpp") + +add_executable(caffegen ${SOURCES}) +target_link_libraries(caffegen stdex) +target_link_libraries(caffegen cli) +# NOTE "Caffe" package provides both caffe and caffeproto target +# NOTE "caffeproto" is linked to "caffe" +target_link_libraries(caffegen caffe) diff --git a/compiler/caffegen/README.md b/compiler/caffegen/README.md new file mode 100644 index 000000000..57019d67d --- /dev/null +++ b/compiler/caffegen/README.md @@ -0,0 +1,45 @@ +# caffegen + +`caffegen` is a tool for generating caffe model and decoding binary file of caffe model + +## How caffegen works + +Some of commands in `caffegen` use standard input for reading data and standard output for exporting result. +In this case, we strongly recommand you to use pipe, not copy & paste the content of file itself. + +Otherwise, `caffegen` use arguments to pass some directories. + +## Supported command + +Basically, caffgen command is used as `caffegen [COMMAND]` and there are four `COMMAND` types. + - init : initialize parameters using prototxt. + - encode : make a binary file(caffemodel) using initialized data + - decode : decode a binary file(caffemodel) and reproduce the initialized data + - merge : copy the trained weights from a caffemodel into a prototxt file + +## How to use each command + +1. Init (Using stdin and stdout) + - `./build/contrib/caffegen/caffegen init` + - Type the prototxt by yourself + - Then you can get the result on the shell. + - `cat ./contrib/enco/test/caffe/000/test.prototxt | ./build/contrib/caffegen/caffegen init` + - Prototxt will be automatically passed + - Then you can get the result on the shell. + +2. Encode (Using stdin and stdout) + - `./build/contrib/caffegen/caffegen encode` + - Type the initialized data by yourself + - Then you can get the result on the shell. + - `cat ./contrib/enco/test/caffe/000/test.prototxt | ./build/contrib/caffegen/caffegen init | ./build/contrib/caffegen/caffegen encode > 000.caffemodel` + - The initialized data will be automatically passed + - The encoded result will be automatically saved in caffemodel file + +3. Decode (Using stdin and stdout) + - `cat 000.caffemodel | ./build/contrib/caffegen/caffegen decode` + - Caffemodel file will be automatically passed + - Then you can get the result on the shell + +4. Merge (Using arguments) + - `./build/contrib/caffegen/caffegen merge ./contrib/enco/test/caffe/000/test.prototxt 000.caffemodel` + - `./build/contrib/caffegen/caffegen merge ./contrib/enco/test/caffe/000/test.prototxt 000.caffemodel > 000.merged` diff --git a/compiler/caffegen/src/DecodeCommand.cpp b/compiler/caffegen/src/DecodeCommand.cpp new file mode 100644 index 000000000..02d044ed3 --- /dev/null +++ b/compiler/caffegen/src/DecodeCommand.cpp @@ -0,0 +1,46 @@ +/* + * 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 "DecodeCommand.h" + +#include <caffe/proto/caffe.pb.h> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <iostream> + +int DecodeCommand::run(int, const char *const *) const +{ + caffe::NetParameter param; + + // Load binary from standard input + google::protobuf::io::IstreamInputStream is{&std::cin}; + google::protobuf::io::CodedInputStream coded_is{&is}; + + if (!param.ParseFromCodedStream(&coded_is)) + { + std::cerr << "ERROR: Failed to parse caffemodel" << std::endl; + return 255; + } + + // Write text into standard output + google::protobuf::io::OstreamOutputStream os{&std::cout}; + google::protobuf::TextFormat::Print(param, &os); + + return 0; +} diff --git a/compiler/caffegen/src/DecodeCommand.h b/compiler/caffegen/src/DecodeCommand.h new file mode 100644 index 000000000..4b43b465b --- /dev/null +++ b/compiler/caffegen/src/DecodeCommand.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#ifndef __DECODE_COMMAND_H__ +#define __DECODE_COMMAND_H__ + +#include <cli/Command.h> + +struct DecodeCommand final : public cli::Command +{ + int run(int argc, const char *const *argv) const override; +}; + +#endif // __DECODE_COMMAND_H__ diff --git a/compiler/caffegen/src/Driver.cpp b/compiler/caffegen/src/Driver.cpp new file mode 100644 index 000000000..81b01e6f1 --- /dev/null +++ b/compiler/caffegen/src/Driver.cpp @@ -0,0 +1,42 @@ +/* + * 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 "InitCommand.h" +#include "EncodeCommand.h" +#include "DecodeCommand.h" +#include "MergeCommand.h" + +#include <cli/App.h> +#include <stdex/Memory.h> + +#include <map> +#include <string> + +using stdex::make_unique; + +int main(int argc, char **argv) +{ + cli::App app{argv[0]}; + + // all receive data from stdin + app.insert("init", make_unique<InitCommand>()); + app.insert("encode", make_unique<EncodeCommand>()); + app.insert("decode", make_unique<DecodeCommand>()); + // takes 2 args: prototxt model and caffemodel weights in that order + app.insert("merge", make_unique<MergeCommand>()); + + return app.run(argc - 1, argv + 1); +} diff --git a/compiler/caffegen/src/EncodeCommand.cpp b/compiler/caffegen/src/EncodeCommand.cpp new file mode 100644 index 000000000..4b35030bd --- /dev/null +++ b/compiler/caffegen/src/EncodeCommand.cpp @@ -0,0 +1,51 @@ +/* + * 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 "EncodeCommand.h" + +#include <caffe/proto/caffe.pb.h> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <iostream> + +int EncodeCommand::run(int, const char *const *) const +{ + caffe::NetParameter param; + + // Load text from standard input + google::protobuf::io::IstreamInputStream is{&std::cin}; + + if (!google::protobuf::TextFormat::Parse(&is, ¶m)) + { + std::cerr << "ERROR: Failed to parse prototxt" << std::endl; + return 255; + } + + // Write binary into standard output + google::protobuf::io::OstreamOutputStream os{&std::cout}; + google::protobuf::io::CodedOutputStream coded_os{&os}; + + if (!param.SerializeToCodedStream(&coded_os)) + { + std::cerr << "ERROR: Failed to serialize" << std::endl; + return 255; + } + + return 0; +} diff --git a/compiler/caffegen/src/EncodeCommand.h b/compiler/caffegen/src/EncodeCommand.h new file mode 100644 index 000000000..1115c2363 --- /dev/null +++ b/compiler/caffegen/src/EncodeCommand.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#ifndef __ENCODE_COMMAND_H__ +#define __ENCODE_COMMAND_H__ + +#include <cli/Command.h> + +struct EncodeCommand final : public cli::Command +{ + int run(int argc, const char *const *argv) const override; +}; + +#endif // __ENCODE_COMMAND_H__ diff --git a/compiler/caffegen/src/InitCommand.cpp b/compiler/caffegen/src/InitCommand.cpp new file mode 100644 index 000000000..fd5b8a467 --- /dev/null +++ b/compiler/caffegen/src/InitCommand.cpp @@ -0,0 +1,65 @@ +/* + * 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 "InitCommand.h" + +#include <caffe/net.hpp> +#include <caffe/util/upgrade_proto.hpp> +#include <caffe/proto/caffe.pb.h> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <iostream> + +int InitCommand::run(int, const char *const *) const +{ + // Read prototxt from standard input + ::caffe::NetParameter in; + { + google::protobuf::io::IstreamInputStream is{&std::cin}; + if (!google::protobuf::TextFormat::Parse(&is, &in)) + { + std::cerr << "ERROR: Failed to parse prototxt" << std::endl; + return 255; + } + } + + // Upgrade prototxt if necessary + if (::caffe::NetNeedsUpgrade(in)) + { + if (!::caffe::UpgradeNetAsNeeded("<stdin>", &in)) + { + std::cerr << "ERROR: Failed to upgrade prototxt" << std::endl; + return 255; + } + } + + ::caffe::Net<float> net(in); + + // Extract initialized parameters + ::caffe::NetParameter out; + { + net.ToProto(&out); + } + + // Write initialized parameters to standard output + google::protobuf::io::OstreamOutputStream os{&std::cout}; + google::protobuf::TextFormat::Print(out, &os); + + return 0; +} diff --git a/compiler/caffegen/src/InitCommand.h b/compiler/caffegen/src/InitCommand.h new file mode 100644 index 000000000..8d86a195f --- /dev/null +++ b/compiler/caffegen/src/InitCommand.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#ifndef __INIT_COMMAND_H__ +#define __INIT_COMMAND_H__ + +#include <cli/Command.h> + +struct InitCommand final : public cli::Command +{ + int run(int argc, const char *const *argv) const override; +}; + +#endif // __INIT_COMMAND_H__ diff --git a/compiler/caffegen/src/MergeCommand.cpp b/compiler/caffegen/src/MergeCommand.cpp new file mode 100644 index 000000000..4e1d863bc --- /dev/null +++ b/compiler/caffegen/src/MergeCommand.cpp @@ -0,0 +1,58 @@ +/* + * 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 "MergeCommand.h" + +#include <caffe/proto/caffe.pb.h> +#include <caffe/caffe.hpp> + +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/text_format.h> + +#include <iostream> +#include <string> + +int MergeCommand::run(int argc, const char *const *argv) const +{ + if (argc != 2) + { + std::cerr << "ERROR: this command requires exactly 2 arguments" << std::endl; + return 254; + } + + std::string model_file = argv[0]; + std::string trained_file = argv[1]; + + // Load the network + caffe::Net<float> caffe_test_net(model_file, caffe::TEST); + // Load the weights + caffe_test_net.CopyTrainedLayersFrom(trained_file); + + caffe::NetParameter net_param; + caffe_test_net.ToProto(&net_param); + + // Write binary with initialized params into standard output + google::protobuf::io::OstreamOutputStream os(&std::cout); + google::protobuf::io::CodedOutputStream coded_os{&os}; + + if (!net_param.SerializeToCodedStream(&coded_os)) + { + std::cerr << "ERROR: Failed to serialize" << std::endl; + return 255; + } + return 0; +} diff --git a/compiler/caffegen/src/MergeCommand.h b/compiler/caffegen/src/MergeCommand.h new file mode 100644 index 000000000..e0134626c --- /dev/null +++ b/compiler/caffegen/src/MergeCommand.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef __MERGE_COMMAND_H__ +#define __MERGE_COMMAND_H__ + +#include <cli/Command.h> + +/** + * @brief Takes .prototxt and .caffemodel filenames from ARGV + * and fills the model with trained weights. + * The resulting binary model with weights to be consumed by nnc is printed to StdOut + * @return error code + */ +struct MergeCommand final : public cli::Command +{ + int run(int argc, const char *const *argv) const override; +}; + +#endif //__MERGE_COMMAND_H__ |