summaryrefslogtreecommitdiff
path: root/compiler/caffegen
diff options
context:
space:
mode:
author박종현/On-Device Lab(SR)/Staff Engineer/삼성전자 <jh1302.park@samsung.com>2019-07-18 14:58:51 +0900
committerGitHub Enterprise <noreply-CODE@samsung.com>2019-07-18 14:58:51 +0900
commitdcfc6d1b6089b497608c3c63a564f240a7d247ee (patch)
tree8f30b3a52a898703019d276b7b14d7c023dd597a /compiler/caffegen
parent9df0e14167706f46dce5eab712f8961161af9e12 (diff)
downloadnnfw-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/.FORMATCHECKED0
-rw-r--r--compiler/caffegen/CMakeLists.txt14
-rw-r--r--compiler/caffegen/README.md45
-rw-r--r--compiler/caffegen/src/DecodeCommand.cpp46
-rw-r--r--compiler/caffegen/src/DecodeCommand.h27
-rw-r--r--compiler/caffegen/src/Driver.cpp42
-rw-r--r--compiler/caffegen/src/EncodeCommand.cpp51
-rw-r--r--compiler/caffegen/src/EncodeCommand.h27
-rw-r--r--compiler/caffegen/src/InitCommand.cpp65
-rw-r--r--compiler/caffegen/src/InitCommand.h27
-rw-r--r--compiler/caffegen/src/MergeCommand.cpp58
-rw-r--r--compiler/caffegen/src/MergeCommand.h33
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, &param))
+ {
+ 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__