Add Caffe proto reader (#255)
authorDmitry Mozolev/AI Tools Lab/Engineer/삼성전자 <d.mozolev@samsung.com>
Tue, 29 May 2018 14:13:58 +0000 (17:13 +0300)
committerSergey Vostokov/AI Tools Lab/Staff Engineer/삼성전자 <s.vostokov@samsung.com>
Tue, 29 May 2018 14:13:58 +0000 (17:13 +0300)
Add Caffe proto reader

Both reading from binary and from text files is supported.

Signed-off-by: Dmitry Mozolev <d.mozolev@samsung.com>
contrib/nnc/libs/frontend/CMakeLists.txt
contrib/nnc/libs/frontend/caffe/CMakeLists.txt [new file with mode: 0644]
contrib/nnc/libs/frontend/caffe/include/proto_reader.h [new file with mode: 0644]
contrib/nnc/libs/frontend/caffe/src/proto_reader.cpp [new file with mode: 0644]

index 62c171a..f793ded 100644 (file)
@@ -12,3 +12,4 @@ target_include_directories(${nn_import_common} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR
 set_target_properties(${nn_import_common} PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
 add_subdirectory(tflite)
+add_subdirectory(caffe)
diff --git a/contrib/nnc/libs/frontend/caffe/CMakeLists.txt b/contrib/nnc/libs/frontend/caffe/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d76bc97
--- /dev/null
@@ -0,0 +1,24 @@
+# Try to get compiled caffe proto and return if not successful
+# Note: this creates a target called "caffeproto" that contains compiled caffe.proto sources,
+#       and after linking with it caffe.pb.h will be available as "caffe/proto/caffe.pb.h"
+# Note2: DOWNLOAD_CAFFE cmake option should be on
+nncc_find_package(CaffeProto QUIET)
+if(NOT CaffeProto_FOUND)
+  return()
+endif()
+
+###################
+# Caffe importer  #
+###################
+
+file(GLOB caffe_importer_sources ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
+file(GLOB caffe_importer_headers ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h)
+
+add_nncc_library(caffe_importer SHARED ${caffe_importer_sources}
+                                       ${caffe_importer_headers})
+
+target_include_directories(caffe_importer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+target_link_libraries(caffe_importer PUBLIC caffeproto)
+target_link_libraries(caffe_importer PUBLIC ${nn_import_common})
+target_link_libraries(caffe_importer PRIVATE nncc_core)
diff --git a/contrib/nnc/libs/frontend/caffe/include/proto_reader.h b/contrib/nnc/libs/frontend/caffe/include/proto_reader.h
new file mode 100644 (file)
index 0000000..ccee059
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef NNCC_PROTO_READER_H
+#define NNCC_PROTO_READER_H
+
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/io/zero_copy_stream_impl.h"
+#include "google/protobuf/text_format.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace caffe
+{
+namespace util
+{
+
+using google::protobuf::io::FileInputStream;
+using google::protobuf::io::ZeroCopyInputStream;
+using google::protobuf::io::CodedInputStream;
+
+bool readProtoFromTextFile(const char* filename, ::caffe::NetParameter* proto);
+bool readProtoFromBinaryFile(const char* filename, ::caffe::NetParameter* proto);
+
+} // namespace util
+} // namespace caffe
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc
+
+#endif // NNCC_PROTO_READER_H
diff --git a/contrib/nnc/libs/frontend/caffe/src/proto_reader.cpp b/contrib/nnc/libs/frontend/caffe/src/proto_reader.cpp
new file mode 100644 (file)
index 0000000..784f5e4
--- /dev/null
@@ -0,0 +1,66 @@
+#include <iostream>
+#include <fcntl.h>
+#include <unistd.h>
+#include <memory>
+
+#include "caffe/proto/caffe.pb.h"
+
+#include "proto_reader.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace frontend
+{
+namespace caffe
+{
+namespace util
+{
+
+const int protoBytesLimit = INT_MAX;
+const int protoBytesWarningLimit = 1024 * 1024 * 512;
+
+bool readProtoFromTextFile(const char* filename, ::caffe::NetParameter* proto)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd == -1)
+    {
+        std::cout << "File not found: " << filename << std::endl;
+        return false;
+    }
+
+    FileInputStream input{fd};
+
+    bool success = google::protobuf::TextFormat::Parse(&input, proto);
+
+    close(fd);
+
+    return success;
+}
+
+bool readProtoFromBinaryFile(const char* filename, ::caffe::NetParameter* proto)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd == -1)
+    {
+        std::cout << "File not found: " << filename << std::endl;
+        return false;
+    }
+
+    FileInputStream raw_input{fd};
+    CodedInputStream coded_input{&raw_input};
+    coded_input.SetTotalBytesLimit(protoBytesLimit, protoBytesWarningLimit);
+
+    bool success = proto->ParseFromCodedStream(&coded_input);
+
+    close(fd);
+
+    return success;
+}
+
+} // namespace util
+} // namespace caffe
+} // namespace frontend
+} // namespace contrib
+} // namespace nncc