From 3a8b2fcfb7df2a0d0f3f25feca8052913f39ff81 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 25 Jul 2018 18:55:55 +0900
Subject: [PATCH 001/321] travis: configure Coverity Scan

---
 .travis.yml | 54 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 38 insertions(+), 16 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 73005dc..844e662 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,25 +1,44 @@
 dist: trusty
 sudo: required
 language: cpp
-os:
-  - linux
-  - osx
-addons:
-    apt:
-        sources:
-            - ubuntu-toolchain-r-test
-            - sourceline: 'ppa:maarten-fonville/protobuf'
-        packages:
-            - gcc-7
-            - g++-7
-            - cmake-data
-            - cmake
-            - libopencv-dev
-            - libprotobuf-dev
-            - protobuf-compiler
+matrix:
+    include:
+        - os: osx
+        - os: linux
+          addons:
+              apt:
+                  sources:
+                      - ubuntu-toolchain-r-test
+                      - sourceline: 'ppa:maarten-fonville/protobuf'
+                  packages:
+                      - gcc-7
+                      - g++-7
+                      - cmake-data
+                      - cmake
+                      - libopencv-dev
+                      - libprotobuf-dev
+                      - protobuf-compiler
+              coverity_scan:
+                  project:
+                      name: "pfnet-research/menoh"
+                      description: "Menoh: DNN inference library"
+                  notification_email: sakai@preferred.jp
+                  build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" .
+                  build_command: make
+                  branch_pattern: coverity_scan
+env:
+    global:
+        # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
+        #   via the "travis encrypt" command using the project repo's public key
+        - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
 cache:
     directories:
         - $HOME/mkl-dnn
+before_install:
+    - |
+      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+        echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+      fi
 install:
     - |
       if [ "$TRAVIS_OS_NAME" = "osx" ]; then
@@ -40,6 +59,9 @@ install:
 before_script:
     - ls -R $HOME/mkl-dnn
 script:
+    #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
+    # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
+    - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
     - mkdir build
     - cd build
     - |

From 8ddc3f1291fb6905e4c489b54a43f0e7fe5356aa Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 25 Jul 2018 19:14:46 +0900
Subject: [PATCH 002/321] add Coverity Scan badge to README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 28f6b33..dc54fd8 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
 # Menoh
 
 [![travis](https://img.shields.io/travis/pfnet-research/menoh/master.svg)](https://travis-ci.org/pfnet-research/menoh) [![Build status](https://ci.appveyor.com/api/projects/status/luo2m9p5fg9jxjsh/branch/master?svg=true)](https://ci.appveyor.com/project/pfnet-research/menoh/branch/master)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/16151/badge.svg)](https://scan.coverity.com/projects/pfnet-research-menoh)
 
 Menoh is DNN inference library with C API.
 

From 7b0a6f007ee8f7cf043b14e96623559b2fc2be08 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 26 Jul 2018 11:01:44 +0900
Subject: [PATCH 003/321] fix uninitialized pointer in array default
 constructor

---
 menoh/array.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/array.hpp b/menoh/array.hpp
index 4c10f57..16710eb 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -31,7 +31,7 @@ namespace menoh_impl {
         dtype_t dtype_;
         std::vector<int> dims_;
         std::shared_ptr<void> data_;
-        void* data_handle_;
+        void* data_handle_ = nullptr;
     };
 
     std::size_t total_size(array const& a);

From 09785d001dfa79c8f4c00d5564b47642e2f3ba53 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 26 Jul 2018 12:58:15 +0900
Subject: [PATCH 004/321] fix bugs annotated by coverity scan

fix dtype undefined = -1
define unsupported input dims error
---
 include/menoh/menoh.h       |  1 +
 menoh/dtype.hpp             |  3 ++-
 menoh/mkldnn/model_core.cpp |  6 ++++--
 menoh/mkldnn/model_core.hpp |  1 +
 menoh/model_core.hpp        | 19 ++++++++++++++-----
 5 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 6bba639..2fc016f 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -65,6 +65,7 @@ enum menoh_error_code_constant {
     menoh_error_code_failed_to_configure_operator,
     menoh_error_code_backend_error,
     menoh_error_code_same_named_variable_already_exist,
+    menoh_error_code_unsupported_input_dims,
 };
 typedef int32_t menoh_error_code;
 /*! \brief Users can get detailed message about last error.
diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index 1a60f9d..c404506 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -19,10 +19,11 @@ namespace menoh_impl {
                   "Checking one float is 32bit: failed");
 
     enum class dtype_t {
-        undefined,
+        undefined = -1,
         float_ = menoh_dtype_float
         // TODO more types
     };
+    static_assert(dtype_t::undefined != dtype_t::float_, "");
 
     class invalid_dtype : public exception {
     public:
diff --git a/menoh/mkldnn/model_core.cpp b/menoh/mkldnn/model_core.cpp
index dcb8b11..987e961 100644
--- a/menoh/mkldnn/model_core.cpp
+++ b/menoh/mkldnn/model_core.cpp
@@ -58,13 +58,15 @@ namespace menoh_impl {
                 std::string name;
                 array arr;
                 std::tie(name, arr) = name_and_arr_pair;
-                mkldnn::memory::format format;
+                mkldnn::memory::format format =
+                  mkldnn::memory::format::format_undef;
                 if(arr.dims().size() == 2) {
                     format = mkldnn::memory::format::nc;
                 } else if(arr.dims().size() == 4) {
                     format = mkldnn::memory::format::nchw;
                 } else {
-                    assert("invalid input dims size");
+                    throw unsupported_input_dims(
+                      name, std::to_string(arr.dims().size()));
                 }
                 auto mem = array_to_memory(arr, format, engine);
                 variable_memory_table.insert({name, mem});
diff --git a/menoh/mkldnn/model_core.hpp b/menoh/mkldnn/model_core.hpp
index be95c89..0883208 100644
--- a/menoh/mkldnn/model_core.hpp
+++ b/menoh/mkldnn/model_core.hpp
@@ -15,6 +15,7 @@
 namespace menoh_impl {
     namespace mkldnn_backend {
 
+
         class model_core final : public menoh_impl::model_core {
         public:
             model_core(
diff --git a/menoh/model_core.hpp b/menoh/model_core.hpp
index 40a1590..de8e4fd 100644
--- a/menoh/model_core.hpp
+++ b/menoh/model_core.hpp
@@ -11,19 +11,28 @@ namespace menoh_impl {
 
     class failed_to_configure_operator : public exception {
     public:
-        explicit failed_to_configure_operator(
-          std::string const& op_type, std::string const& first_output_name,
-          std::string const& message)
+        failed_to_configure_operator(std::string const& op_type,
+                                     std::string const& first_output_name,
+                                     std::string const& message)
           : exception(menoh_error_code_failed_to_configure_operator,
                       "menoh failed to configure operator error: " + op_type +
                         " which issues " + first_output_name + ": " + message) {
         }
     };
 
+    class unsupported_input_dims : public exception {
+    public:
+        unsupported_input_dims(std::string const& name,
+                               std::string const& dims_size)
+          : exception(menoh_error_code_unsupported_input_dims,
+                      "menoh unsupported input dims error: " + name +
+                        "has dims size: " + dims_size) {}
+    };
+
     class backend_error : public exception {
     public:
-        explicit backend_error(std::string const& backend_name,
-                               std::string const& message)
+        backend_error(std::string const& backend_name,
+                      std::string const& message)
           : exception(menoh_error_code_backend_error,
                       "menoh backend error: " + backend_name + ": " + message) {
         }

From cc90044f5a72727e328969cc8f44dfb57299d874 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 26 Jul 2018 13:55:34 +0900
Subject: [PATCH 005/321] default initialize dtype in array

---
 menoh/array.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/array.hpp b/menoh/array.hpp
index 16710eb..2bb70bc 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -28,7 +28,7 @@ namespace menoh_impl {
         bool has_ownership() const { return static_cast<bool>(data_); }
 
     private:
-        dtype_t dtype_;
+        dtype_t dtype_ = dtype_t::undefined;
         std::vector<int> dims_;
         std::shared_ptr<void> data_;
         void* data_handle_ = nullptr;

From 51f7b663df4b831882c38d909df756780f8496f5 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 31 Jul 2018 16:44:17 +0900
Subject: [PATCH 006/321] travis/appveyor: update to use mkl-dnn 0.15

---
 .travis/install_mkldnn.sh |  2 +-
 appveyor.yml              | 11 +++++------
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/.travis/install_mkldnn.sh b/.travis/install_mkldnn.sh
index 0c536d0..29fa3c9 100644
--- a/.travis/install_mkldnn.sh
+++ b/.travis/install_mkldnn.sh
@@ -1,7 +1,7 @@
 if [ ! -d "$HOME/mkl-dnn/lib" ]; then
     git clone https://github.com/intel/mkl-dnn.git
     cd mkl-dnn
-    git checkout v0.14
+    git checkout v0.15
     cd scripts && bash ./prepare_mkl.sh && cd ..
     sed -i 's/add_subdirectory(examples)//g' CMakeLists.txt
     sed -i 's/add_subdirectory(tests)//g' CMakeLists.txt
diff --git a/appveyor.yml b/appveyor.yml
index 63dcdb3..d9073cf 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,12 +24,11 @@ install:
 
 - if [%TARGET%]==[mingw] (
     pacman -S --needed --noconfirm mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-opencv mingw-w64-x86_64-protobuf mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python3-numpy mingw-w64-x86_64-hdf5 mingw-w64-x86_64-ca-certificates &&
-    curl -omingw-w64-x86_64-mkl-dnn-0.14-3-x86_64.pkg.tar.xz -L https://preferredjp.box.com/shared/static/eb90vngoz8zngp6yy69x91q0swp11ha1.xz &&
-    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.14-3-x86_64.pkg.tar.xz
+    curl -omingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz &&
+    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
   ) else (
-    curl -omkl-dnn-0.14-win64.7z -L --insecure https://preferredjp.box.com/shared/static/njn6vrjt8zaslk82yjw7j1pczkcp3c0f.7z &&
-    mkdir mkl-dnn-0.14-win64 &&
-    7z x -omkl-dnn-0.14-win64 mkl-dnn-0.14-win64.7z &&
+    curl -omkl-dnn-0.15-win64.zip -L --insecure https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mkl-dnn-0.15-win64.zip &&
+    7z x mkl-dnn-0.15-win64.zip &&
     call appveyor\install_protoc_msvc.bat
   )
 
@@ -48,7 +47,7 @@ install:
 build_script:
 - mkdir build
 - cd build
-- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.14-win64\bin;c:\projects\menoh\mkl-dnn-0.14-win64\include;c:\projects\menoh\mkl-dnn-0.14-win64\lib
+- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.15-win64\bin;c:\projects\menoh\mkl-dnn-0.15-win64\include;c:\projects\menoh\mkl-dnn-0.15-win64\lib
 - if [%TARGET%]==[mingw] (
     cmake -G "MSYS Makefiles" -DENABLE_TEST=ON -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
     make

From de2c392141b474c03bfb1f0cfde2625af87017c5 Mon Sep 17 00:00:00 2001
From: playertwo <842517+playertwo@users.noreply.github.com>
Date: Tue, 7 Aug 2018 07:50:03 +0300
Subject: [PATCH 007/321] Add calc output dims for conv_transpose

---
 menoh/graph.cpp | 24 ++++++++++++++++++++++++
 menoh/node.cpp  | 12 ++++++++++++
 menoh/node.hpp  |  5 +++++
 3 files changed, 41 insertions(+)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 7781d09..40a0509 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -279,6 +279,30 @@ namespace menoh_impl {
                 }
                 variable_dims_table.insert(
                   {node.output_name_list.at(0), output_dims});
+            } else if(node.op_type == "ConvTranspose") {
+                auto weight_name = node.input_name_list.at(1);
+                auto output_channel_num =
+                  get_output_channel_num_from_parameter_dims(
+                    find_value(parameter_table, weight_name).dims());
+                auto output_dims = calc_2d_output_dims_for_conv_transpose(node,
+                          output_channel_num, variable_dims_table);
+                auto dilations =
+                  optional_attribute_ints(node, "dilations", {1, 1});
+                if(dilations != std::vector<int>({1, 1})) {
+                    auto actual = "(" + std::to_string(dilations.at(0)) + ", " +
+                                  std::to_string(dilations.at(1)) + ")";
+                    throw unsupported_operator_attribute(
+                      node.op_type, node.output_name_list.front(), "dilations",
+                      actual, "(1, 1)");
+                }
+                auto group = optional_attribute_int(node, "group", 1);
+                if(group != 1) {
+                    throw unsupported_operator_attribute(
+                      node.op_type, node.output_name_list.front(), "group",
+                      std::to_string(group), "1");
+                }
+                variable_dims_table.insert(
+                  {node.output_name_list.at(0), output_dims});
             } else if(node.op_type == "MaxPool" ||
                       node.op_type == "AveragePool") {
                 auto input_name = node.input_name_list.at(0);
diff --git a/menoh/node.cpp b/menoh/node.cpp
index 63d6f65..354e0f1 100644
--- a/menoh/node.cpp
+++ b/menoh/node.cpp
@@ -96,4 +96,16 @@ namespace menoh_impl {
           output_channel_num, kernel_shape, strides, pads);
     }
 
+    std::vector<int>
+    calc_2d_output_dims_for_conv_transpose(menoh_impl::node const& node, int output_channel_num,
+                        std::unordered_map<std::string, std::vector<int>> const&
+                          variable_dims_table) {
+        std::vector<int> strides, kernel_shape, pads;
+        std::tie(strides, kernel_shape, pads) =
+          attributes_for_2d_data_processing(node);
+        return calc_2d_output_dims_for_conv_transpose(
+          find_value(variable_dims_table, node.input_name_list.at(0)),
+          output_channel_num, kernel_shape, strides, pads);
+    }
+
 } // namespace menoh_impl
diff --git a/menoh/node.hpp b/menoh/node.hpp
index a66b86f..9c57a80 100644
--- a/menoh/node.hpp
+++ b/menoh/node.hpp
@@ -47,6 +47,11 @@ namespace menoh_impl {
                         std::unordered_map<std::string, std::vector<int>> const&
                           variable_dims_table);
 
+    std::vector<int>
+    calc_2d_output_dims_for_conv_transpose(menoh_impl::node const& node, int output_channel_num,
+                        std::unordered_map<std::string, std::vector<int>> const&
+                          variable_dims_table);
+                          
 } // namespace menoh_impl
 
 #endif // MENOH_NODE_HPP

From 27d7ff6397112f544378d69cb61a313d3d17f947 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 9 Aug 2018 22:36:49 +0900
Subject: [PATCH 008/321] Update LICENSE_THIRD_PARTY

---
 docs/LICENSE_THIRD_PARTY | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/docs/LICENSE_THIRD_PARTY b/docs/LICENSE_THIRD_PARTY
index 78c1b25..bd06d16 100644
--- a/docs/LICENSE_THIRD_PARTY
+++ b/docs/LICENSE_THIRD_PARTY
@@ -40,4 +40,39 @@ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+==== Protocol Buffers ====
+
+Copyright 2008 Google Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Code generated by the Protocol Buffer compiler is owned by the owner
+of the input file used when generating it.  This code is not
+standalone and requires a support library to be linked with it.  This
+support library is itself covered by the above license.

From e11a7846fa5463cb0e504c19c320136da7ad9e9b Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 20 Aug 2018 10:55:58 +0900
Subject: [PATCH 009/321] add --version-script for libmenoh.so

---
 menoh/CMakeLists.txt |  2 ++
 menoh/menoh.map      | 12 ++++++++++++
 2 files changed, 14 insertions(+)
 create mode 100644 menoh/menoh.map

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 975fcbc..b361b66 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -4,6 +4,8 @@ target_link_libraries(menoh ${MKLDNN_LIBRARY} ${PROTOBUF_LIBRARY})
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
 
+set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
+
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
     LIBRARY DESTINATION "lib"
diff --git a/menoh/menoh.map b/menoh/menoh.map
new file mode 100644
index 0000000..aee6518
--- /dev/null
+++ b/menoh/menoh.map
@@ -0,0 +1,12 @@
+{
+  global:
+    extern "C" {
+      menoh_*;
+    };
+    extern "C++" {
+      menoh::*; menoh_impl::*; onnx::*;
+    };
+
+  local:
+    *;
+};

From 15ed1e284b5bea21803b5c580653012ee6212f0c Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 20 Aug 2018 13:12:40 +0900
Subject: [PATCH 010/321] fix CI errors

---
 menoh/CMakeLists.txt | 6 +++++-
 menoh/menoh.map      | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index b361b66..dfb1205 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -4,7 +4,11 @@ target_link_libraries(menoh ${MKLDNN_LIBRARY} ${PROTOBUF_LIBRARY})
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
 
-set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
+if(UNIX)
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+        set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
+    endif ()
+endif ()
 
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
diff --git a/menoh/menoh.map b/menoh/menoh.map
index aee6518..160152f 100644
--- a/menoh/menoh.map
+++ b/menoh/menoh.map
@@ -4,7 +4,11 @@
       menoh_*;
     };
     extern "C++" {
-      menoh::*; menoh_impl::*; onnx::*;
+      menoh::*;
+      menoh_impl::*;
+      typeinfo*for?menoh_impl::*;
+      vtable*for?menoh_impl::*;
+      onnx::*;
     };
 
   local:

From 577cde428b06c868ea7c5759e85f6672cdad980d Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 20 Aug 2018 13:47:46 +0900
Subject: [PATCH 011/321] simplifies the condition for the linker flags

---
 menoh/CMakeLists.txt | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index dfb1205..6a52756 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -4,10 +4,8 @@ target_link_libraries(menoh ${MKLDNN_LIBRARY} ${PROTOBUF_LIBRARY})
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
 
-if(UNIX)
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
-        set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
-    endif ()
+if(NOT APPLE)
+    set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
 endif ()
 
 install(TARGETS menoh

From 8db61c8194478dfbca8badb7f3b32596d031e3e9 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Mon, 20 Aug 2018 18:28:46 +0900
Subject: [PATCH 012/321] add link to Node.js binding

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index dc54fd8..91e8da9 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@ This codebase contains C API and C++ API.
 - Go wrapper : [go-menoh](https://github.com/pfnet-research/go-menoh)
   - (unofficial wrapper [gomenoh](https://github.com/kou-m/gomenoh) by kou-m san has been merged)
 - Haskell wrapper : [menoh-haskell](https://github.com/pfnet-research/menoh-haskell)
+- Node.js wrapper : [node-menoh](https://github.com/pfnet-research/node-menoh)
 - Ruby wrapper : [menoh-ruby](https://github.com/pfnet-research/menoh-ruby)
 - Rust wrapper : [menoh-rs](https://github.com/pfnet-research/menoh-rs)
   - There is also [unofficial Rust wrapper by Y-Nak san](https://github.com/Y-Nak/menoh-rs)

From ec61ff82f3af0f3e26c8d253ab947ef58cf8445a Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 22 Aug 2018 18:46:59 +0900
Subject: [PATCH 013/321] add logs for travis

---
 .travis.yml | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 844e662..e364d29 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -57,6 +57,18 @@ install:
     - python retrieve_data.py
     - python gen_test_data.py
 before_script:
+    - |
+      echo 'Checking library versions:'
+      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+        gcc-7 --version
+        g++-7 --version
+        ldconfig -p
+      fi
+      if [ "$TRAVIS_OS_NAME" = "osx" ]; then
+        brew list --versions
+      fi
+      cmake --version
+      make --version
     - ls -R $HOME/mkl-dnn
 script:
     #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi

From 8ecfcd3999e9130ab0c153a09a5b3be26c9fbe08 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 22 Aug 2018 19:16:30 +0900
Subject: [PATCH 014/321] add logs for appveyor

---
 .travis.yml  |  2 +-
 appveyor.yml | 11 +++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index e364d29..7d1973b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -58,7 +58,7 @@ install:
     - python gen_test_data.py
 before_script:
     - |
-      echo 'Checking library versions:'
+      echo 'Checking tools and libraries version:'
       if [ "$TRAVIS_OS_NAME" = "linux" ]; then
         gcc-7 --version
         g++-7 --version
diff --git a/appveyor.yml b/appveyor.yml
index d9073cf..7cb52b1 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -44,6 +44,17 @@ install:
     python gen_test_data.py
   )
 
+before_build:
+  - if [%TARGET%]==[msvc] (
+      echo TODO
+    )
+  - if [%TARGET%]==[mingw] (
+      gcc --version
+      g++ --version
+      cmake --version
+      make --version
+    )
+
 build_script:
 - mkdir build
 - cd build

From 36f7424d24928d767c9b9841491adea2d4e6a579 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 22 Aug 2018 19:33:32 +0900
Subject: [PATCH 015/321] show package versions in Linux

---
 .travis.yml  | 3 +--
 appveyor.yml | 9 +++------
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 7d1973b..4821f93 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -60,8 +60,7 @@ before_script:
     - |
       echo 'Checking tools and libraries version:'
       if [ "$TRAVIS_OS_NAME" = "linux" ]; then
-        gcc-7 --version
-        g++-7 --version
+        apt list --installed
         ldconfig -p
       fi
       if [ "$TRAVIS_OS_NAME" = "osx" ]; then
diff --git a/appveyor.yml b/appveyor.yml
index 7cb52b1..f8000cb 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -45,13 +45,10 @@ install:
   )
 
 before_build:
-  - if [%TARGET%]==[msvc] (
-      echo TODO
-    )
   - if [%TARGET%]==[mingw] (
-      gcc --version
-      g++ --version
-      cmake --version
+      echo 'Checking tools and libraries version:' &&
+      pacman -Q &&
+      cmake --version &&
       make --version
     )
 

From 818e1aeb94feca9c41a9f456fcd9d3ba8c4dd0e7 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 23 Aug 2018 19:07:38 +0900
Subject: [PATCH 016/321] add LINK_STATIC_* options to link dependent libraries
 statically in Linux

---
 CMakeLists.txt       | 66 ++++++++++++++++++++++++++++++++++++++++----
 menoh/CMakeLists.txt | 42 +++++++++++++++++++++++++---
 tool/CMakeLists.txt  |  6 +++-
 3 files changed, 104 insertions(+), 10 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e6d8397..7b2db2a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.9)
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
@@ -8,6 +8,10 @@ set(MENOH_PATCH_VERSION 2)
 
 # Options
 option(BUILD_SHARED_LIBS "Build shared libs" ON)
+
+option(USE_OLD_GLIBCXX_ABI "Generate binaries for the old libstdc++ ABI" OFF)
+option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
+
 option(ENABLE_TEST "Build test" OFF)
 option(ENABLE_BENCHMARK "Build benchmark" ON)
 option(ENABLE_EXAMPLE "Build example" ON)
@@ -31,21 +35,65 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
     set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG -march=native")
 endif()
 
+# Configure to use the new `libstdc++` ABI
+if(USE_OLD_GLIBCXX_ABI)
+    message(STATUS "Set _GLIBCXX_USE_CXX11_ABI macro to 0")
+    add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
+endif()
+
 include_directories("${PROJECT_SOURCE_DIR}")
 include_directories("${PROJECT_SOURCE_DIR}/include")
 
 set(EXTERNAL_DIR ${CMAKE_SOURCE_DIR}/external)
+set(DOWNLOAD_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/downloads CACHE PATH "")
+mark_as_advanced(DOWNLOAD_LOCATION)
+
+# Enable ExternalProject_Add
+include(ExternalProject)
+
+# protobuf setup
+set(PROTOBUF_VERSION "2.6.1")
+
+if(UNIX AND LINK_STATIC_LIBPROTOBUF)
+    set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
+    set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
+
+    # Requires `-fPIC` for linking with a shared library
+    set(PROTOBUF_CFLAGS -fPIC)
+    set(PROTOBUF_CXXFLAGS -fPIC)
+    if(USE_OLD_GLIBCXX_ABI)
+        set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
+    endif()
+
+    ExternalProject_Add(protobuf
+        PREFIX ${PROTOBUF_DIR}
+        URL ${PROTOBUF_URL}
+        URL_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423
+        DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
+        BUILD_IN_SOURCE 1
+        CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
+        BUILD_COMMAND make
+        INSTALL_COMMAND make install
+    )
+
+    set(Protobuf_INCLUDE_DIR ${PROTOBUF_DIR}/include)
+    set(Protobuf_LIBRARY ${PROTOBUF_DIR}/lib/libprotobuf.a)
+    set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+else()
+    include(FindProtobuf)
+    find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
+endif()
+
+include_directories(${Protobuf_INCLUDE_DIR})
 
 # ONNX setup
 set(ONNX_DIR ${EXTERNAL_DIR}/onnx)
-set(Protobuf_PROTOC_EXECUTABLE protoc CACHE STRING "protoc path")
-include(FindProtobuf)
-find_package(Protobuf 2.6.1 REQUIRED)
-include_directories(${PROTOBUF_INCLUDE_DIR})
 execute_process(COMMAND git submodule update --init -- ${ONNX_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=${ONNX_DIR} ${ONNX_DIR}/onnx/onnx.proto WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
 set(ONNX_PROTO_HEADER ${ONNX_DIR}/onnx/onnx.pb.h)
 set(ONNX_PROTO_SRC ${ONNX_DIR}/onnx/onnx.pb.cc)
+
 include_directories(${EXTERNAL_DIR})
 include_directories(${ONNX_DIR})
 
@@ -62,21 +110,29 @@ if(${ENABLE_TEST})
     # GTest setup
     set(GTEST_DIR test/lib/googletest)
     execute_process(COMMAND git submodule update --init -- ${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+    message(STATUS "# add_subdirectory\(${GTEST_DIR}\)")
     add_subdirectory(${GTEST_DIR})
+    message(STATUS "# add_subdirectory\(test\)")
     add_subdirectory(test)
 endif()
 
 if(${ENABLE_BENCHMARK})
+    message(STATUS "# add_subdirectory\(benchmark\)")
     add_subdirectory(benchmark)
 endif()
 
 if(${ENABLE_EXAMPLE})
+    message(STATUS "# add_subdirectory\(example\)")
     add_subdirectory(example)
 endif()
 
 if(${ENABLE_TOOL})
+    message(STATUS "# add_subdirectory\(tool\)")
     add_subdirectory(tool)
 endif()
 
+message(STATUS "# add_subdirectory\(menoh\)")
 add_subdirectory(menoh)
+
+message(STATUS "# add_subdirectory\(include\)")
 add_subdirectory(include)
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 6a52756..550a12f 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -1,12 +1,46 @@
+# Options
+option(LINK_STATIC_LIBGCC "Link static libgcc to libmenoh" OFF)
+option(LINK_STATIC_LIBSTDCXX "Link static libstdc++ to libmenoh" OFF)
+
+if(NOT DEFINED ONNX_PROTO_SRC)
+    message(FATAL_ERROR "ONNX_PROTO_SRC is not found")
+endif()
+if(NOT DEFINED ONNX_PROTO_HEADER)
+    message(FATAL_ERROR "ONNX_PROTO_HEADER is not found")
+endif()
+
+# Note: The libraries can be static (.a) or shared (.so)
+if(NOT DEFINED MKLDNN_LIBRARY)
+    message(FATAL_ERROR "MKLDNN_LIBRARY is not found")
+endif()
+if(NOT DEFINED Protobuf_LIBRARY)
+    message(FATAL_ERROR "Protobuf_LIBRARY is not found")
+endif()
+
 file(GLOB_RECURSE SOURCES "." "*.cpp")
-add_library(menoh ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
-target_link_libraries(menoh ${MKLDNN_LIBRARY} ${PROTOBUF_LIBRARY})
+add_library(menoh SHARED ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
+
+# configure MENOH_LINK_LIBRARIES
+if(LINK_STATIC_LIBGCC)
+    set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} -static-libgcc)
+endif()
+if(LINK_STATIC_LIBSTDCXX)
+    set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} -static-libstdc++)
+endif()
+set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} ${MKLDNN_LIBRARY} ${Protobuf_LIBRARY})
+
+message(STATUS "MENOH_LINK_LIBRARIES: ${MENOH_LINK_LIBRARIES}")
+target_link_libraries(menoh PRIVATE ${MENOH_LINK_LIBRARIES})
+
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
 
+# remove private symbols
 if(NOT APPLE)
-    set (CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
-endif ()
+    set_property(
+        TARGET menoh APPEND_STRING PROPERTY
+            LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
+endif()
 
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 250926e..b227300 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -1,4 +1,8 @@
+if(NOT DEFINED Protobuf_LIBRARY)
+    message(FATAL_ERROR "Protobuf_LIBRARY is not found")
+endif()
+
 add_executable(onnx_viewer onnx_viewer.cpp)
-target_link_libraries(onnx_viewer menoh)
+target_link_libraries(onnx_viewer ${Protobuf_LIBRARY} menoh)
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
 install(TARGETS onnx_viewer RUNTIME DESTINATION bin)

From 70dfe9f54d6f0f7aa5aada5c0db1f17bacb4688c Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 23 Aug 2018 19:25:26 +0900
Subject: [PATCH 017/321] add a dependency to mkldnn explicitly

---
 test/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 31827a2..8cfbde6 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -11,5 +11,5 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main menoh)
+target_link_libraries(menoh_test gtest_main mkldnn menoh)
 add_test(NAME menoh_test COMMAND menoh_test)

From 04f7b1232efc9ba38fbb28ce44d6d49d44ebe815 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 24 Aug 2018 11:34:25 +0900
Subject: [PATCH 018/321] fix bugs

---
 CMakeLists.txt       | 17 ++++++++++++++---
 menoh/CMakeLists.txt | 19 ++++++++-----------
 test/CMakeLists.txt  | 10 +++++++++-
 tool/CMakeLists.txt  |  7 ++++---
 4 files changed, 35 insertions(+), 18 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b2db2a..3b8ecf9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,6 +57,7 @@ set(PROTOBUF_VERSION "2.6.1")
 if(UNIX AND LINK_STATIC_LIBPROTOBUF)
     set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
     set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
+    set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
 
     # Requires `-fPIC` for linking with a shared library
     set(PROTOBUF_CFLAGS -fPIC)
@@ -65,10 +66,10 @@ if(UNIX AND LINK_STATIC_LIBPROTOBUF)
         set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
     endif()
 
-    ExternalProject_Add(protobuf
+    ExternalProject_Add(Protobuf
         PREFIX ${PROTOBUF_DIR}
         URL ${PROTOBUF_URL}
-        URL_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423
+        URL_HASH ${PROTOBUF_HASH}
         DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
         BUILD_IN_SOURCE 1
         CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
@@ -76,9 +77,19 @@ if(UNIX AND LINK_STATIC_LIBPROTOBUF)
         INSTALL_COMMAND make install
     )
 
+    set(Protobuf_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
+    set(Protobuf_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
+
+    add_library(protobuf::libprotobuf.a STATIC IMPORTED)
+    set_target_properties(protobuf::libprotobuf.a PROPERTIES
+        IMPORTED_LOCATION "${Protobuf_LIBRARY_STATIC}")
+
+    # mimic the behavior of FindProtobuf module
     set(Protobuf_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-    set(Protobuf_LIBRARY ${PROTOBUF_DIR}/lib/libprotobuf.a)
+    set(Protobuf_LIBRARY protobuf::libprotobuf.a) # use the static library
+    set(Protobuf_LIBRARIES ${Protobuf_LIBRARY})
     set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+    set(Protobuf_FOUND TRUE)
 else()
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 550a12f..c03a630 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -10,27 +10,24 @@ if(NOT DEFINED ONNX_PROTO_HEADER)
 endif()
 
 # Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED MKLDNN_LIBRARY)
-    message(FATAL_ERROR "MKLDNN_LIBRARY is not found")
+if(NOT DEFINED MKLDNN_LIBRARIES)
+    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
 endif()
-if(NOT DEFINED Protobuf_LIBRARY)
-    message(FATAL_ERROR "Protobuf_LIBRARY is not found")
+if(NOT DEFINED Protobuf_LIBRARIES)
+    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
 endif()
 
 file(GLOB_RECURSE SOURCES "." "*.cpp")
 add_library(menoh SHARED ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
 
-# configure MENOH_LINK_LIBRARIES
+# Link libraries to menoh
 if(LINK_STATIC_LIBGCC)
-    set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} -static-libgcc)
+    target_link_libraries(menoh PRIVATE -static-libgcc)
 endif()
 if(LINK_STATIC_LIBSTDCXX)
-    set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} -static-libstdc++)
+    target_link_libraries(menoh PRIVATE -static-libstdc++)
 endif()
-set(MENOH_LINK_LIBRARIES ${MENOH_LINK_LIBRARIES} ${MKLDNN_LIBRARY} ${Protobuf_LIBRARY})
-
-message(STATUS "MENOH_LINK_LIBRARIES: ${MENOH_LINK_LIBRARIES}")
-target_link_libraries(menoh PRIVATE ${MENOH_LINK_LIBRARIES})
+target_link_libraries(menoh PRIVATE ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES})
 
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8cfbde6..2935742 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,3 +1,11 @@
+# Note: The libraries can be static (.a) or shared (.so)
+if(NOT DEFINED MKLDNN_LIBRARIES)
+    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
+endif()
+if(NOT DEFINED Protobuf_LIBRARIES)
+    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+endif()
+
 add_executable(menoh_test
     np_io.cpp
     array.cpp
@@ -11,5 +19,5 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main mkldnn menoh)
+target_link_libraries(menoh_test PRIVATE gtest_main ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES} menoh)
 add_test(NAME menoh_test COMMAND menoh_test)
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index b227300..4441529 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -1,8 +1,9 @@
-if(NOT DEFINED Protobuf_LIBRARY)
-    message(FATAL_ERROR "Protobuf_LIBRARY is not found")
+# Note: The library can be static (.a) or shared (.so)
+if(NOT DEFINED Protobuf_LIBRARIES)
+    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
 endif()
 
 add_executable(onnx_viewer onnx_viewer.cpp)
-target_link_libraries(onnx_viewer ${Protobuf_LIBRARY} menoh)
+target_link_libraries(onnx_viewer PRIVATE ${Protobuf_LIBRARIES} menoh)
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
 install(TARGETS onnx_viewer RUNTIME DESTINATION bin)

From 69913b9b024e71ea9fedbca6479cb5e119058571 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 24 Aug 2018 11:55:31 +0900
Subject: [PATCH 019/321] add SetupProtobuf.cmake

---
 CMakeLists.txt            | 45 +-------------------------------------
 benchmark/CMakeLists.txt  | 10 ++++++++-
 cmake/SetupProtobuf.cmake | 46 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+), 45 deletions(-)
 create mode 100644 cmake/SetupProtobuf.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3b8ecf9..5088a55 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,50 +52,7 @@ mark_as_advanced(DOWNLOAD_LOCATION)
 include(ExternalProject)
 
 # protobuf setup
-set(PROTOBUF_VERSION "2.6.1")
-
-if(UNIX AND LINK_STATIC_LIBPROTOBUF)
-    set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
-    set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
-    set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
-
-    # Requires `-fPIC` for linking with a shared library
-    set(PROTOBUF_CFLAGS -fPIC)
-    set(PROTOBUF_CXXFLAGS -fPIC)
-    if(USE_OLD_GLIBCXX_ABI)
-        set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
-    endif()
-
-    ExternalProject_Add(Protobuf
-        PREFIX ${PROTOBUF_DIR}
-        URL ${PROTOBUF_URL}
-        URL_HASH ${PROTOBUF_HASH}
-        DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
-        BUILD_IN_SOURCE 1
-        CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
-        BUILD_COMMAND make
-        INSTALL_COMMAND make install
-    )
-
-    set(Protobuf_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
-    set(Protobuf_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
-
-    add_library(protobuf::libprotobuf.a STATIC IMPORTED)
-    set_target_properties(protobuf::libprotobuf.a PROPERTIES
-        IMPORTED_LOCATION "${Protobuf_LIBRARY_STATIC}")
-
-    # mimic the behavior of FindProtobuf module
-    set(Protobuf_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-    set(Protobuf_LIBRARY protobuf::libprotobuf.a) # use the static library
-    set(Protobuf_LIBRARIES ${Protobuf_LIBRARY})
-    set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
-    set(Protobuf_FOUND TRUE)
-else()
-    include(FindProtobuf)
-    find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
-endif()
-
-include_directories(${Protobuf_INCLUDE_DIR})
+include(SetupProtobuf)
 
 # ONNX setup
 set(ONNX_DIR ${EXTERNAL_DIR}/onnx)
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 2d8d19e..568d9d0 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,2 +1,10 @@
+# Note: The libraries can be static (.a) or shared (.so)
+if(NOT DEFINED MKLDNN_LIBRARIES)
+    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
+endif()
+if(NOT DEFINED Protobuf_LIBRARIES)
+    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+endif()
+
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
-target_link_libraries(vgg16_benchmark menoh)
+target_link_libraries(vgg16_benchmark ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES} menoh)
diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
new file mode 100644
index 0000000..40d22fc
--- /dev/null
+++ b/cmake/SetupProtobuf.cmake
@@ -0,0 +1,46 @@
+set(PROTOBUF_VERSION "2.6.1")
+
+if(UNIX AND LINK_STATIC_LIBPROTOBUF)
+    set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
+    set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
+    set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
+
+    # Requires `-fPIC` for linking with a shared library
+    set(PROTOBUF_CFLAGS -fPIC)
+    set(PROTOBUF_CXXFLAGS -fPIC)
+    if(USE_OLD_GLIBCXX_ABI)
+        set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
+    endif()
+
+    ExternalProject_Add(Protobuf
+        PREFIX ${PROTOBUF_DIR}
+        URL ${PROTOBUF_URL}
+        URL_HASH ${PROTOBUF_HASH}
+        DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
+        BUILD_IN_SOURCE 1
+        CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
+        BUILD_COMMAND make
+        INSTALL_COMMAND make install
+    )
+
+    set(Protobuf_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
+    set(Protobuf_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
+
+    add_library(protobuf::libprotobuf.a STATIC IMPORTED)
+    # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
+    # not installed during executing `cmake`
+    set_target_properties(protobuf::libprotobuf.a PROPERTIES
+        IMPORTED_LOCATION "${Protobuf_LIBRARY_STATIC}")
+
+    # mimic the behavior of FindProtobuf module
+    set(Protobuf_INCLUDE_DIR ${PROTOBUF_DIR}/include)
+    set(Protobuf_LIBRARY protobuf::libprotobuf.a) # use the static library
+    set(Protobuf_LIBRARIES ${Protobuf_LIBRARY})
+    set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+    set(Protobuf_FOUND TRUE)
+else()
+    include(FindProtobuf)
+    find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
+endif()
+
+include_directories(${Protobuf_INCLUDE_DIR})

From 36fc71b5cb980f1aa5c81c0ecdb8a4b3ab3c6ef4 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 24 Aug 2018 13:00:32 +0900
Subject: [PATCH 020/321] make dependency to mkldnn PUBLIC

---
 CMakeLists.txt           | 12 +++++++++++-
 benchmark/CMakeLists.txt |  5 +----
 menoh/CMakeLists.txt     |  5 ++++-
 test/CMakeLists.txt      |  5 +----
 tool/CMakeLists.txt      |  2 +-
 5 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5088a55..24a60a2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -17,6 +17,8 @@ option(ENABLE_BENCHMARK "Build benchmark" ON)
 option(ENABLE_EXAMPLE "Build example" ON)
 option(ENABLE_TOOL "Build tool" ON)
 
+option(SHOW_ALL_VARIABLES "Debug: show all variables" OFF)
+
 # C++ setup
 set(CMAKE_CXX_STANDARD 14)
 if("${CMAKE_BUILD_TYPE}" STREQUAL "")
@@ -45,7 +47,7 @@ include_directories("${PROJECT_SOURCE_DIR}")
 include_directories("${PROJECT_SOURCE_DIR}/include")
 
 set(EXTERNAL_DIR ${CMAKE_SOURCE_DIR}/external)
-set(DOWNLOAD_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/downloads CACHE PATH "")
+set(DOWNLOAD_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/downloads CACHE PATH "A directory to save the downloaded files.")
 mark_as_advanced(DOWNLOAD_LOCATION)
 
 # Enable ExternalProject_Add
@@ -104,3 +106,11 @@ add_subdirectory(menoh)
 
 message(STATUS "# add_subdirectory\(include\)")
 add_subdirectory(include)
+
+if(SHOW_ALL_VARIABLES)
+    get_cmake_property(_variableNames VARIABLES)
+    list(SORT _variableNames)
+    foreach(_variableName ${_variableNames})
+        message(STATUS "${_variableName}=${${_variableName}}")
+    endforeach()
+endif()
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 568d9d0..34b2314 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,10 +1,7 @@
 # Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED MKLDNN_LIBRARIES)
-    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
-endif()
 if(NOT DEFINED Protobuf_LIBRARIES)
     message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
 endif()
 
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
-target_link_libraries(vgg16_benchmark ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(vgg16_benchmark ${Protobuf_LIBRARIES} menoh)
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index c03a630..c70d549 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -27,7 +27,10 @@ endif()
 if(LINK_STATIC_LIBSTDCXX)
     target_link_libraries(menoh PRIVATE -static-libstdc++)
 endif()
-target_link_libraries(menoh PRIVATE ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES})
+# PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
+# Note: change it to PRIVATE after building mkldnn itself
+target_link_libraries(menoh PUBLIC ${MKLDNN_LIBRARIES})
+target_link_libraries(menoh PRIVATE ${Protobuf_LIBRARIES})
 
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2935742..00f8c85 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,7 +1,4 @@
 # Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED MKLDNN_LIBRARIES)
-    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
-endif()
 if(NOT DEFINED Protobuf_LIBRARIES)
     message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
 endif()
@@ -19,5 +16,5 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test PRIVATE gtest_main ${MKLDNN_LIBRARIES} ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(menoh_test gtest_main ${Protobuf_LIBRARIES} menoh)
 add_test(NAME menoh_test COMMAND menoh_test)
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 4441529..2ad48c7 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -4,6 +4,6 @@ if(NOT DEFINED Protobuf_LIBRARIES)
 endif()
 
 add_executable(onnx_viewer onnx_viewer.cpp)
-target_link_libraries(onnx_viewer PRIVATE ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(onnx_viewer ${Protobuf_LIBRARIES} menoh)
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
 install(TARGETS onnx_viewer RUNTIME DESTINATION bin)

From 3d8364ab124049e583facbbf08667abf94b4e1c3 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 24 Aug 2018 15:53:48 +0900
Subject: [PATCH 021/321] remove unused `include_directories`

---
 CMakeLists.txt | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24a60a2..6fd950e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,10 +53,10 @@ mark_as_advanced(DOWNLOAD_LOCATION)
 # Enable ExternalProject_Add
 include(ExternalProject)
 
-# protobuf setup
+# Setup protobuf
 include(SetupProtobuf)
 
-# ONNX setup
+# Generate source codes from ONNX protobuf schema
 set(ONNX_DIR ${EXTERNAL_DIR}/onnx)
 execute_process(COMMAND git submodule update --init -- ${ONNX_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=${ONNX_DIR} ${ONNX_DIR}/onnx/onnx.proto WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
@@ -64,10 +64,9 @@ execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=$
 set(ONNX_PROTO_HEADER ${ONNX_DIR}/onnx/onnx.pb.h)
 set(ONNX_PROTO_SRC ${ONNX_DIR}/onnx/onnx.pb.cc)
 
-include_directories(${EXTERNAL_DIR})
-include_directories(${ONNX_DIR})
+include_directories(${ONNX_DIR}) # for ONNX_PROTO_HEADER
 
-# MKLDNN setup
+# Setup MKLDNN
 find_package(MKLDNN "0.14")
 if (NOT MKLDNN_FOUND)
     message(FATAL_ERROR "MKLDNN is not found")

From c8f212b28dcd31ff31a8206bc85691cfca370678 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 24 Aug 2018 17:40:53 +0900
Subject: [PATCH 022/321] use the old `FindProtobuf` variable names

---
 CMakeLists.txt            |  4 ++--
 benchmark/CMakeLists.txt  |  6 +++---
 cmake/SetupProtobuf.cmake | 27 ++++++++++++++++-----------
 menoh/CMakeLists.txt      |  6 +++---
 test/CMakeLists.txt       |  6 +++---
 tool/CMakeLists.txt       |  6 +++---
 6 files changed, 30 insertions(+), 25 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6fd950e..73a4b7c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.9)
+cmake_minimum_required(VERSION 3.1)
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
@@ -59,7 +59,7 @@ include(SetupProtobuf)
 # Generate source codes from ONNX protobuf schema
 set(ONNX_DIR ${EXTERNAL_DIR}/onnx)
 execute_process(COMMAND git submodule update --init -- ${ONNX_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=${ONNX_DIR} ${ONNX_DIR}/onnx/onnx.proto WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+execute_process(COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=${ONNX_DIR} ${ONNX_DIR}/onnx/onnx.proto WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
 set(ONNX_PROTO_HEADER ${ONNX_DIR}/onnx/onnx.pb.h)
 set(ONNX_PROTO_SRC ${ONNX_DIR}/onnx/onnx.pb.cc)
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 34b2314..bcd8459 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED Protobuf_LIBRARIES)
-    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+if(NOT DEFINED PROTOBUF_LIBRARIES)
+    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
-target_link_libraries(vgg16_benchmark ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(vgg16_benchmark ${PROTOBUF_LIBRARIES} menoh)
diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 40d22fc..51f4901 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -1,6 +1,10 @@
 set(PROTOBUF_VERSION "2.6.1")
 
 if(UNIX AND LINK_STATIC_LIBPROTOBUF)
+    # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
+    # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
+    # build it ourselves.
+
     set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
     set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
     set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
@@ -23,24 +27,25 @@ if(UNIX AND LINK_STATIC_LIBPROTOBUF)
         INSTALL_COMMAND make install
     )
 
-    set(Protobuf_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
-    set(Protobuf_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
+    set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
+    set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
 
     add_library(protobuf::libprotobuf.a STATIC IMPORTED)
     # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
     # not installed during executing `cmake`
     set_target_properties(protobuf::libprotobuf.a PROPERTIES
-        IMPORTED_LOCATION "${Protobuf_LIBRARY_STATIC}")
-
-    # mimic the behavior of FindProtobuf module
-    set(Protobuf_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-    set(Protobuf_LIBRARY protobuf::libprotobuf.a) # use the static library
-    set(Protobuf_LIBRARIES ${Protobuf_LIBRARY})
-    set(Protobuf_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
-    set(Protobuf_FOUND TRUE)
+        IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
+
+    # Mimic the behavior of `FindProtobuf` module
+    # Use the old variable names to ensure backward compatibility
+    set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
+    set(PROTOBUF_LIBRARY protobuf::libprotobuf.a) # use the static library
+    set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
+    set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+    set(PROTOBUF_FOUND TRUE)
 else()
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
 endif()
 
-include_directories(${Protobuf_INCLUDE_DIR})
+include_directories(${PROTOBUF_INCLUDE_DIR})
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index c70d549..250cc4b 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -13,8 +13,8 @@ endif()
 if(NOT DEFINED MKLDNN_LIBRARIES)
     message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
 endif()
-if(NOT DEFINED Protobuf_LIBRARIES)
-    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+if(NOT DEFINED PROTOBUF_LIBRARIES)
+    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
 file(GLOB_RECURSE SOURCES "." "*.cpp")
@@ -30,7 +30,7 @@ endif()
 # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
 # Note: change it to PRIVATE after building mkldnn itself
 target_link_libraries(menoh PUBLIC ${MKLDNN_LIBRARIES})
-target_link_libraries(menoh PRIVATE ${Protobuf_LIBRARIES})
+target_link_libraries(menoh PRIVATE ${PROTOBUF_LIBRARIES})
 
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
 set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 00f8c85..451aac7 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,6 +1,6 @@
 # Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED Protobuf_LIBRARIES)
-    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+if(NOT DEFINED PROTOBUF_LIBRARIES)
+    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
 add_executable(menoh_test
@@ -16,5 +16,5 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(menoh_test gtest_main ${PROTOBUF_LIBRARIES} menoh)
 add_test(NAME menoh_test COMMAND menoh_test)
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 2ad48c7..04248c6 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -1,9 +1,9 @@
 # Note: The library can be static (.a) or shared (.so)
-if(NOT DEFINED Protobuf_LIBRARIES)
-    message(FATAL_ERROR "Protobuf_LIBRARIES is not found")
+if(NOT DEFINED PROTOBUF_LIBRARIES)
+    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
 add_executable(onnx_viewer onnx_viewer.cpp)
-target_link_libraries(onnx_viewer ${Protobuf_LIBRARIES} menoh)
+target_link_libraries(onnx_viewer ${PROTOBUF_LIBRARIES} menoh)
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
 install(TARGETS onnx_viewer RUNTIME DESTINATION bin)

From 2b987ae43fd3915f8bff81a8839feed3c718cc2e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 27 Aug 2018 00:41:47 +0900
Subject: [PATCH 023/321] fix preprocess for vgg16

---
 docs/tutorial.md                       | 21 ++++++++++++-------
 example/general_cnn_example_in_cpp.cpp | 29 +++++++++++++++++++-------
 example/vgg16_example_in_cpp.cpp       |  8 ++++---
 3 files changed, 40 insertions(+), 18 deletions(-)

diff --git a/docs/tutorial.md b/docs/tutorial.md
index 93496b5..4ff84ee 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -35,18 +35,22 @@ auto crop_and_resize(cv::Mat mat, cv::Size const&size) {
 
 Menoh takes images as NCHW format(N x Channels x Height x Width), but `Mat` of OpenCV holds image as HWC format(Height x Width x Channels).
 
-So next we define *reorder_to_chw *.
+In addition, VGG16 supposes that the input image is subtracted the average values of imagenet.
+
+So next we define *reorder_to_chw_and_subtract_imagenet_average*.
 
 ```cpp
-auto reorder_to_chw(cv::Mat const&mat) {
+auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const&mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
+    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
                   static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]);
+                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
+                  imagenet_average[c];
             }
         }
     }
@@ -59,16 +63,17 @@ In current case, the range of pixel value `data/VGG16.onnx` taking is \f$[0, 256
 However, sometimes model takes values scaled in range \f$[0.0, 1.0]\f$ or something. In that case, we can scale values here:
 
 ```cpp
-auto reorder_to_chw(cv::Mat const& mat) {
+auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const& mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
+    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]) /
-                  255.f;
+                  (static_cast<float>(
+                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
+                  imagenet_average[c]) / 255.f;
             }
         }
     }
@@ -89,7 +94,7 @@ const int  width = 224;
 cv::Mat image_mat = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);
 image_mat =
   crop_and_resize(std::move(image_mat), cv::Size(width, height));
-std::vector<float> image_data = reorder_to_chw(image_mat, scale);
+std::vector<float> image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat, scale);
 ```
 
 ## Setup model
diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index 010d3a6..d56cb16 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -27,16 +27,27 @@ auto crop_and_resize(cv::Mat mat, cv::Size const& size) {
     return resized;
 }
 
-auto reorder_to_nchw(cv::Mat const& mat) {
+auto reorder_to_nchw_and_subtract_imagenet_average(
+  cv::Mat const& mat, float reverse_scale, bool subtract_imagenet_average) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
+    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             // INFO cv::imread loads image BGR
             for(int c = 0; c < mat.channels(); ++c) {
-                data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]);
+                if(subtract_imagenet_average) {
+                    data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
+                      (static_cast<float>(
+                         mat.data[y * mat.step + x * mat.elemSize() + c]) -
+                       imagenet_average[c]) /
+                      reverse_scale;
+                } else {
+                    data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
+                      static_cast<float>(
+                        mat.data[y * mat.step + x * mat.elemSize() + c]) /
+                      reverse_scale;
+                }
             }
         }
     }
@@ -85,9 +96,10 @@ int main(int argc, char** argv) {
     a.add<std::string>("input_image", '\0', "input image path");
     a.add<int>("image_size", '\0', "input image width and height size");
     a.add<std::string>("model", '\0', "onnx model path");
-    a.add<float>("scale", '\0', "input scale");
+    a.add<float>("reverse_scale", '\0', "input reverse scale");
     a.add<std::string>("input_variable_name", '\0', "output variable name");
     a.add<std::string>("output_variable_name", '\0', "output variable name");
+    a.add<int>("is_subtract_imagenet_average", '\0', "output variable name");
     a.parse_check(argc, argv);
 
     auto height = a.get<int>("image_size");
@@ -102,9 +114,12 @@ int main(int argc, char** argv) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);
     }
-    auto scale = a.get<float>("scale");
+    auto reverse_scale = a.get<float>("reverse_scale");
     image_mat = crop_and_resize(std::move(image_mat), cv::Size(width, height));
-    auto image_data = reorder_to_nchw(image_mat);
+    bool is_subtract_imagenet_average =
+      a.get<int>("is_subtract_imagenet_average");
+    auto image_data = reorder_to_nchw_and_subtract_imagenet_average(
+      image_mat, reverse_scale, is_subtract_imagenet_average);
 
     // Aliases to onnx's node input and output tensor name
     auto conv1_1_in_name = a.get<std::string>("input_variable_name");
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index d46288d..f6f28e3 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -27,15 +27,17 @@ auto crop_and_resize(cv::Mat mat, cv::Size const& size) {
     return resized;
 }
 
-auto reorder_to_chw(cv::Mat const& mat) {
+auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const& mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
+    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
                   static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]);
+                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
+                  imagenet_average[c];
             }
         }
     }
@@ -108,7 +110,7 @@ int main(int argc, char** argv) {
                                  input_image_path);
     }
     image_mat = crop_and_resize(std::move(image_mat), cv::Size(width, height));
-    auto image_data = reorder_to_chw(image_mat);
+    auto image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat);
 
     // Load ONNX model data
     auto model_data = menoh::make_model_data_from_onnx(onnx_model_path);

From 57b17e7436f496bcc97f4b7a97096590674a0812 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 27 Aug 2018 00:46:09 +0900
Subject: [PATCH 024/321] update README

---
 README.md | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index 91e8da9..ff3be01 100644
--- a/README.md
+++ b/README.md
@@ -48,7 +48,7 @@ This codebase contains C API and C++ API.
 
 ## Build
 
-Execute below commands in root directory.
+Execute following commands in root directory.
 
 ```
 python retrieve_data.py
@@ -59,7 +59,7 @@ make
 
 ## Installation
 
-Execute below command in build directory created at Build section.
+Execute following command in build directory created at Build section.
 
 ```
 make install
@@ -67,23 +67,24 @@ make install
 
 # Run VGG16 example
 
-Execute below command in root directory.
+Execute following command in root directory.
 
 ```
 ./example/vgg16_example_in_cpp
 ```
 
-Result is below
+Result is here
 
 ```
 vgg16 example
--22.3708 -34.4082 -10.218 24.2962 -0.252342 -8.004 -27.0804 -23.0728 -7.05607 16.1343
+-23.149 -26.9167 -12.9911 10.3262 -0.845882 0.454192 -24.1435 -21.891 -3.98805 15.6863 
 top 5 categories are
-8 0.96132 n01514859 hen
-7 0.0369939 n01514668 cock
-86 0.00122795 n01807496 partridge
-82 0.000225824 n01797886 ruffed grouse, partridge, Bonasa umbellus
-97 3.83677e-05 n01847000 drake
+8 0.946072 n01514859 hen
+7 0.0485334 n01514668 cock
+86 0.00296125 n01807496 partridge
+82 0.000877083 n01797886 ruffed grouse, partridge, Bonasa umbellus
+97 0.000424042 n01847000 drake
+
 ```
 
 Please give `--help` option for details
@@ -97,7 +98,7 @@ Please give `--help` option for details
 
 Setup chainer
 
-Then, execute below commands in root directory.
+Then, execute following commands in root directory.
 
 ```
 python gen_test_data.py

From 3cdc9de451a69b94402e809ef7d47853293ef89e Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 27 Aug 2018 11:38:30 +0900
Subject: [PATCH 025/321] remove unnecessary dependencies

---
 benchmark/CMakeLists.txt  | 15 ++++++++++-----
 cmake/SetupProtobuf.cmake | 14 +++++++-------
 test/CMakeLists.txt       | 16 +++++++++++-----
 tool/CMakeLists.txt       |  4 ++++
 4 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index bcd8459..1003f77 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,7 +1,12 @@
-# Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED PROTOBUF_LIBRARIES)
-    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
-endif()
+option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
 
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
-target_link_libraries(vgg16_benchmark ${PROTOBUF_LIBRARIES} menoh)
+target_link_libraries(vgg16_benchmark menoh)
+
+if(NOT LINK_STATIC_LIBPROTOBUF)
+    if(DEFINED PROTOBUF_LIBRARIES)
+        target_link_libraries(vgg16_benchmark ${PROTOBUF_LIBRARIES})
+    else()
+        message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
+    endif()
+endif()
diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 51f4901..0de527f 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -30,19 +30,19 @@ if(UNIX AND LINK_STATIC_LIBPROTOBUF)
     set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
     set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
 
-    add_library(protobuf::libprotobuf.a STATIC IMPORTED)
-    # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
-    # not installed during executing `cmake`
-    set_target_properties(protobuf::libprotobuf.a PROPERTIES
-        IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
-
     # Mimic the behavior of `FindProtobuf` module
     # Use the old variable names to ensure backward compatibility
     set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-    set(PROTOBUF_LIBRARY protobuf::libprotobuf.a) # use the static library
+    set(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY_STATIC}) # use the static library
     set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
     set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
     set(PROTOBUF_FOUND TRUE)
+
+    add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
+    # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
+    # not installed during executing `cmake`
+    set_target_properties(protobuf::libprotobuf PROPERTIES
+        IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
 else()
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 451aac7..a6b50a4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,7 +1,4 @@
-# Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED PROTOBUF_LIBRARIES)
-    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
-endif()
+option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
 
 add_executable(menoh_test
     np_io.cpp
@@ -16,5 +13,14 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main ${PROTOBUF_LIBRARIES} menoh)
+target_link_libraries(menoh_test gtest_main menoh)
+
+if(NOT LINK_STATIC_LIBPROTOBUF)
+    if(DEFINED PROTOBUF_LIBRARIES)
+        target_link_libraries(menoh_test ${PROTOBUF_LIBRARIES})
+    else()
+        message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
+    endif()
+endif()
+
 add_test(NAME menoh_test COMMAND menoh_test)
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 04248c6..69b456f 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -4,6 +4,10 @@ if(NOT DEFINED PROTOBUF_LIBRARIES)
 endif()
 
 add_executable(onnx_viewer onnx_viewer.cpp)
+
+# onnx_viewer requires a explicit dependency to protobuf regardless of whether it is shared and static
+# because it has a reference to google::protobuf::internal::NameOfEnum abi:cxx11](google::protobuf::EnumDescriptor const*, int)
 target_link_libraries(onnx_viewer ${PROTOBUF_LIBRARIES} menoh)
+
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
 install(TARGETS onnx_viewer RUNTIME DESTINATION bin)

From b7ecb0feeeb070914778c61e755a28c54a9105c4 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 27 Aug 2018 12:10:59 +0900
Subject: [PATCH 026/321] remove `menoh::*` from the version script

---
 menoh/menoh.map | 1 -
 1 file changed, 1 deletion(-)

diff --git a/menoh/menoh.map b/menoh/menoh.map
index 160152f..a1fdd8f 100644
--- a/menoh/menoh.map
+++ b/menoh/menoh.map
@@ -4,7 +4,6 @@
       menoh_*;
     };
     extern "C++" {
-      menoh::*;
       menoh_impl::*;
       typeinfo*for?menoh_impl::*;
       vtable*for?menoh_impl::*;

From 4e47c038e53b133b278afea10dd894b2b9a13de1 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 27 Aug 2018 18:17:45 +0900
Subject: [PATCH 027/321] use ONNX directly instead of referencing it in
 libmenoh

---
 menoh/menoh.map     | 2 +-
 tool/CMakeLists.txt | 5 ++---
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/menoh/menoh.map b/menoh/menoh.map
index a1fdd8f..4a26cbf 100644
--- a/menoh/menoh.map
+++ b/menoh/menoh.map
@@ -3,11 +3,11 @@
     extern "C" {
       menoh_*;
     };
+    # TODO: Make `menoh_impl` private by removing dependencies from other modules
     extern "C++" {
       menoh_impl::*;
       typeinfo*for?menoh_impl::*;
       vtable*for?menoh_impl::*;
-      onnx::*;
     };
 
   local:
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 69b456f..06d7101 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -3,10 +3,9 @@ if(NOT DEFINED PROTOBUF_LIBRARIES)
     message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
-add_executable(onnx_viewer onnx_viewer.cpp)
+add_executable(onnx_viewer ${ONNX_PROTO_SRC} onnx_viewer.cpp)
 
-# onnx_viewer requires a explicit dependency to protobuf regardless of whether it is shared and static
-# because it has a reference to google::protobuf::internal::NameOfEnum abi:cxx11](google::protobuf::EnumDescriptor const*, int)
+# ONNX requires protobuf regardless of whether it is static and shared
 target_link_libraries(onnx_viewer ${PROTOBUF_LIBRARIES} menoh)
 
 set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")

From 02d803663188d74208ac49090795782fa128a84a Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 27 Aug 2018 19:25:00 +0900
Subject: [PATCH 028/321] revert 4e47c038 (existing two onnx model class in one
 binary cause crash)

---
 menoh/menoh.map     | 1 +
 tool/CMakeLists.txt | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/menoh/menoh.map b/menoh/menoh.map
index 4a26cbf..acf7183 100644
--- a/menoh/menoh.map
+++ b/menoh/menoh.map
@@ -8,6 +8,7 @@
       menoh_impl::*;
       typeinfo*for?menoh_impl::*;
       vtable*for?menoh_impl::*;
+      onnx::*;
     };
 
   local:
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
index 06d7101..c5adf58 100644
--- a/tool/CMakeLists.txt
+++ b/tool/CMakeLists.txt
@@ -3,7 +3,7 @@ if(NOT DEFINED PROTOBUF_LIBRARIES)
     message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
 endif()
 
-add_executable(onnx_viewer ${ONNX_PROTO_SRC} onnx_viewer.cpp)
+add_executable(onnx_viewer onnx_viewer.cpp)
 
 # ONNX requires protobuf regardless of whether it is static and shared
 target_link_libraries(onnx_viewer ${PROTOBUF_LIBRARIES} menoh)

From ee6ad8ba0081745a864c5cb92a7d08a6cd8e261f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 28 Aug 2018 00:09:27 +0900
Subject: [PATCH 029/321] fix resize function in vgg16 example

---
 docs/tutorial.md                       | 15 ++++-----------
 example/general_cnn_example_in_cpp.cpp | 12 +++---------
 example/vgg16_example_in_cpp.cpp       | 12 +++---------
 3 files changed, 10 insertions(+), 29 deletions(-)

diff --git a/docs/tutorial.md b/docs/tutorial.md
index 4ff84ee..72776e3 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -17,18 +17,11 @@ int main(int argc, char** argv) {
 ## Preprocessing input
 
 First of all, preprocessing input is required. `data/VGG16.onnx` takes 3 channels 224 x 224 sized image but input image
-is not always sized 224x224. So we define *crop_and_resize* function using OpenCV :
+is not always sized 224x224. So we define *resize* function using OpenCV :
 
 ```cpp
-auto crop_and_resize(cv::Mat mat, cv::Size const&size) {
-    auto short_edge = std::min(mat.size().width, mat.size().height);
-    cv::Rect roi;
-    roi.x = (mat.size().width - short_edge) / 2;
-    roi.y = (mat.size().height - short_edge) / 2;
-    roi.width = roi.height = short_edge;
-    cv::Mat cropped = mat(roi);
-    cv::Mat resized;
-    cv::resize(cropped, resized, size);
+auto resize(cv::Mat mat, cv::Size const&size) {
+    cv::resize(mat, resized, size);
     return resized;
 }
 ```
@@ -93,7 +86,7 @@ const int  width = 224;
 // Preprocessing input image
 cv::Mat image_mat = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);
 image_mat =
-  crop_and_resize(std::move(image_mat), cv::Size(width, height));
+  resize(std::move(image_mat), cv::Size(width, height));
 std::vector<float> image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat, scale);
 ```
 
diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index d56cb16..908cdc6 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -15,15 +15,9 @@
 
 #include "../external/cmdline.h"
 
-auto crop_and_resize(cv::Mat mat, cv::Size const& size) {
-    auto short_edge = std::min(mat.size().width, mat.size().height);
-    cv::Rect roi;
-    roi.x = (mat.size().width - short_edge) / 2;
-    roi.y = (mat.size().height - short_edge) / 2;
-    roi.width = roi.height = short_edge;
-    cv::Mat cropped = mat(roi);
+auto resize(cv::Mat const& mat, cv::Size const& size) {
     cv::Mat resized;
-    cv::resize(cropped, resized, size);
+    cv::resize(mat, resized, size);
     return resized;
 }
 
@@ -115,7 +109,7 @@ int main(int argc, char** argv) {
                                  input_image_path);
     }
     auto reverse_scale = a.get<float>("reverse_scale");
-    image_mat = crop_and_resize(std::move(image_mat), cv::Size(width, height));
+    image_mat = resize(std::move(image_mat), cv::Size(width, height));
     bool is_subtract_imagenet_average =
       a.get<int>("is_subtract_imagenet_average");
     auto image_data = reorder_to_nchw_and_subtract_imagenet_average(
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index f6f28e3..02629f4 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -15,15 +15,9 @@
 
 #include "../external/cmdline.h"
 
-auto crop_and_resize(cv::Mat mat, cv::Size const& size) {
-    auto short_edge = std::min(mat.size().width, mat.size().height);
-    cv::Rect roi;
-    roi.x = (mat.size().width - short_edge) / 2;
-    roi.y = (mat.size().height - short_edge) / 2;
-    roi.width = roi.height = short_edge;
-    cv::Mat cropped = mat(roi);
+auto resize(cv::Mat const& mat, cv::Size const& size) {
     cv::Mat resized;
-    cv::resize(cropped, resized, size);
+    cv::resize(mat, resized, size);
     return resized;
 }
 
@@ -109,7 +103,7 @@ int main(int argc, char** argv) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);
     }
-    image_mat = crop_and_resize(std::move(image_mat), cv::Size(width, height));
+    image_mat = resize(std::move(image_mat), cv::Size(width, height));
     auto image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat);
 
     // Load ONNX model data

From fa85238191d3cc205cc0daebd536f1d731cbb776 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 28 Aug 2018 14:59:24 +0900
Subject: [PATCH 030/321] add menoh_objlib

---
 cmake/ConfigureMenoh.cmake | 20 ++++++++++++++++++++
 menoh/CMakeLists.txt       | 31 +++++++++++++++----------------
 test/CMakeLists.txt        |  2 +-
 3 files changed, 36 insertions(+), 17 deletions(-)
 create mode 100644 cmake/ConfigureMenoh.cmake

diff --git a/cmake/ConfigureMenoh.cmake b/cmake/ConfigureMenoh.cmake
new file mode 100644
index 0000000..772c439
--- /dev/null
+++ b/cmake/ConfigureMenoh.cmake
@@ -0,0 +1,20 @@
+# SCOPE can be an empty string
+macro(menoh_link_libraries TARGET_NAME SCOPE)
+    # Link libraries to menoh
+    if(LINK_STATIC_LIBGCC)
+        target_link_libraries(${TARGET_NAME} ${SCOPE} -static-libgcc)
+    endif()
+    if(LINK_STATIC_LIBSTDCXX)
+        target_link_libraries(${TARGET_NAME} ${SCOPE} -static-libstdc++)
+    endif()
+
+    if(NOT ${SCOPE})
+	    # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
+	    # Note: change it to PRIVATE after building mkldnn itself
+	    target_link_libraries(${TARGET_NAME} PUBLIC ${MKLDNN_LIBRARIES})
+	else()
+	    target_link_libraries(${TARGET_NAME} ${MKLDNN_LIBRARIES})
+	endif()
+
+    target_link_libraries(${TARGET_NAME} ${SCOPE} ${PROTOBUF_LIBRARIES})
+endmacro()
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 250cc4b..4b4b06b 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -18,30 +18,29 @@ if(NOT DEFINED PROTOBUF_LIBRARIES)
 endif()
 
 file(GLOB_RECURSE SOURCES "." "*.cpp")
-add_library(menoh SHARED ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
 
-# Link libraries to menoh
-if(LINK_STATIC_LIBGCC)
-    target_link_libraries(menoh PRIVATE -static-libgcc)
-endif()
-if(LINK_STATIC_LIBSTDCXX)
-    target_link_libraries(menoh PRIVATE -static-libstdc++)
-endif()
-# PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
-# Note: change it to PRIVATE after building mkldnn itself
-target_link_libraries(menoh PUBLIC ${MKLDNN_LIBRARIES})
-target_link_libraries(menoh PRIVATE ${PROTOBUF_LIBRARIES})
-
-set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
-set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
+add_library(menoh_objlib OBJECT ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
+set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
-# remove private symbols
+add_library(menoh SHARED $<TARGET_OBJECTS:menoh_objlib>)
 if(NOT APPLE)
+    # Remove private symbols
     set_property(
         TARGET menoh APPEND_STRING PROPERTY
             LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
 endif()
 
+# Used in test/ subdirectory
+add_library(menoh_test_target SHARED $<TARGET_OBJECTS:menoh_objlib>)
+
+include(ConfigureMenoh)
+
+menoh_link_libraries(menoh PRIVATE)
+menoh_link_libraries(menoh_test_target PRIVATE)
+
+set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
+set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
+
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
     LIBRARY DESTINATION "lib"
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a6b50a4..ba5a840 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -13,7 +13,7 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main menoh)
+target_link_libraries(menoh_test gtest_main menoh_test_target)
 
 if(NOT LINK_STATIC_LIBPROTOBUF)
     if(DEFINED PROTOBUF_LIBRARIES)

From 820eae98df98f3879531a7c1f83143ec41f49ef3 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 28 Aug 2018 19:04:46 +0900
Subject: [PATCH 031/321] refactoring to use opencv functions

---
 docs/tutorial.md                       | 50 +++++++-------------------
 example/general_cnn_example_in_cpp.cpp | 39 +++++++-------------
 example/vgg16_example_in_cpp.cpp       | 21 +++++------
 3 files changed, 34 insertions(+), 76 deletions(-)

diff --git a/docs/tutorial.md b/docs/tutorial.md
index 72776e3..294ade4 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -17,56 +17,32 @@ int main(int argc, char** argv) {
 ## Preprocessing input
 
 First of all, preprocessing input is required. `data/VGG16.onnx` takes 3 channels 224 x 224 sized image but input image
-is not always sized 224x224. So we define *resize* function using OpenCV :
+is not always sized 224x224. So we use `resize()` function in OpenCV :
 
 ```cpp
-auto resize(cv::Mat mat, cv::Size const&size) {
-    cv::resize(mat, resized, size);
-    return resized;
-}
+cv::resize(image_mat, image_mat, cv::Size(224, 224));
 ```
 
-Menoh takes images as NCHW format(N x Channels x Height x Width), but `Mat` of OpenCV holds image as HWC format(Height x Width x Channels).
-
-In addition, VGG16 supposes that the input image is subtracted the average values of imagenet.
-
-So next we define *reorder_to_chw_and_subtract_imagenet_average*.
+VGG16 supposes that the input image is subtracted the average values of imagenet.
 
 ```cpp
-auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const&mat) {
-    assert(mat.channels() == 3);
-    std::vector<float> data(mat.channels() * mat.rows * mat.cols);
-    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
-    for(int y = 0; y < mat.rows; ++y) {
-        for(int x = 0; x < mat.cols; ++x) {
-            for(int c = 0; c < mat.channels(); ++c) {
-                data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
-                  imagenet_average[c];
-            }
-        }
-    }
-    return data;
-}
+image_mat.convertTo(image_mat, CV_32FC3); // change data type to float
+image_mat -= cv::Scalar(123.68, 116.779, 103.939);
 ```
 
-In current case, the range of pixel value `data/VGG16.onnx` taking is \f$[0, 256)\f$ and it matches the range of `Mat`. So we have not to scale the values now.
+Menoh takes images as NCHW format(N x Channels x Height x Width), but `Mat` of OpenCV holds image as HWC format(Height x Width x Channels).
 
-However, sometimes model takes values scaled in range \f$[0.0, 1.0]\f$ or something. In that case, we can scale values here:
+So next we define *reorder_to_chw*.
 
 ```cpp
-auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const& mat) {
+auto reorder_to_chw(cv::Mat const&mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
-    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  (static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
-                  imagenet_average[c]) / 255.f;
+                  mat.at<cv::Vec3f>(y, x)[c];
             }
         }
     }
@@ -84,10 +60,10 @@ const int height = 224;
 const int  width = 224;
 
 // Preprocessing input image
-cv::Mat image_mat = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);
-image_mat =
-  resize(std::move(image_mat), cv::Size(width, height));
-std::vector<float> image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat, scale);
+cv::resize(image_mat, image_mat, cv::Size(width, height));
+image_mat.convertTo(image_mat, CV_32FC3);
+image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+auto image_data = reorder_to_chw(image_mat);
 ```
 
 ## Setup model
diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index 908cdc6..ac2636c 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -15,33 +15,14 @@
 
 #include "../external/cmdline.h"
 
-auto resize(cv::Mat const& mat, cv::Size const& size) {
-    cv::Mat resized;
-    cv::resize(mat, resized, size);
-    return resized;
-}
-
-auto reorder_to_nchw_and_subtract_imagenet_average(
-  cv::Mat const& mat, float reverse_scale, bool subtract_imagenet_average) {
+auto reorder_to_chw(cv::Mat const& mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
-    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
-            // INFO cv::imread loads image BGR
             for(int c = 0; c < mat.channels(); ++c) {
-                if(subtract_imagenet_average) {
-                    data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                      (static_cast<float>(
-                         mat.data[y * mat.step + x * mat.elemSize() + c]) -
-                       imagenet_average[c]) /
-                      reverse_scale;
-                } else {
-                    data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                      static_cast<float>(
-                        mat.data[y * mat.step + x * mat.elemSize() + c]) /
-                      reverse_scale;
-                }
+                data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
+                  mat.at<cv::Vec3f>(y, x)[c];
             }
         }
     }
@@ -108,12 +89,18 @@ int main(int argc, char** argv) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);
     }
-    auto reverse_scale = a.get<float>("reverse_scale");
-    image_mat = resize(std::move(image_mat), cv::Size(width, height));
+
+    // Preprocess
     bool is_subtract_imagenet_average =
       a.get<int>("is_subtract_imagenet_average");
-    auto image_data = reorder_to_nchw_and_subtract_imagenet_average(
-      image_mat, reverse_scale, is_subtract_imagenet_average);
+    auto reverse_scale = a.get<float>("reverse_scale");
+    cv::resize(image_mat, image_mat, cv::Size(width, height));
+    image_mat.convertTo(image_mat, CV_32FC3);
+    if(is_subtract_imagenet_average) {
+        image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+    }
+    image_mat /= reverse_scale;
+    auto image_data = reorder_to_chw(image_mat);
 
     // Aliases to onnx's node input and output tensor name
     auto conv1_1_in_name = a.get<std::string>("input_variable_name");
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index 02629f4..b928759 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -15,23 +15,14 @@
 
 #include "../external/cmdline.h"
 
-auto resize(cv::Mat const& mat, cv::Size const& size) {
-    cv::Mat resized;
-    cv::resize(mat, resized, size);
-    return resized;
-}
-
-auto reorder_to_chw_and_subtract_imagenet_average(cv::Mat const& mat) {
+auto reorder_to_chw(cv::Mat const& mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
-    constexpr std::array<float, 3> imagenet_average{{123.68, 116.779, 103.939}};
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  static_cast<float>(
-                    mat.data[y * mat.step + x * mat.elemSize() + c]) -
-                  imagenet_average[c];
+                  mat.at<cv::Vec3f>(y, x)[c];
             }
         }
     }
@@ -103,8 +94,12 @@ int main(int argc, char** argv) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);
     }
-    image_mat = resize(std::move(image_mat), cv::Size(width, height));
-    auto image_data = reorder_to_chw_and_subtract_imagenet_average(image_mat);
+
+    // Preprocess
+    cv::resize(image_mat, image_mat, cv::Size(width, height));
+    image_mat.convertTo(image_mat, CV_32FC3);
+    image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+    auto image_data = reorder_to_chw(image_mat);
 
     // Load ONNX model data
     auto model_data = menoh::make_model_data_from_onnx(onnx_model_path);

From e0b09f05ce5f540c5346190fa0425da091a5181d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 29 Aug 2018 10:58:20 +0900
Subject: [PATCH 032/321] update README

---
 README.md | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/README.md b/README.md
index ff3be01..5d64967 100644
--- a/README.md
+++ b/README.md
@@ -77,14 +77,13 @@ Result is here
 
 ```
 vgg16 example
--23.149 -26.9167 -12.9911 10.3262 -0.845882 0.454192 -24.1435 -21.891 -3.98805 15.6863 
+-18.7495 -28.337 -17.3352 8.3209 -1.16396 -0.453321 -22.5098 -25.0265 -18.7067 11.1063 
 top 5 categories are
-8 0.946072 n01514859 hen
-7 0.0485334 n01514668 cock
-86 0.00296125 n01807496 partridge
-82 0.000877083 n01797886 ruffed grouse, partridge, Bonasa umbellus
-97 0.000424042 n01847000 drake
-
+8 0.876184 n01514859 hen
+7 0.111645 n01514668 cock
+86 0.00435782 n01807496 partridge
+82 0.00136959 n01797886 ruffed grouse, partridge, Bonasa umbellus
+97 0.00133743 n01847000 drake
 ```
 
 Please give `--help` option for details

From 6f721cd4481bf3d84c660097b5455f92858a0e8f Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Wed, 29 Aug 2018 17:58:25 +0900
Subject: [PATCH 033/321] fix version string

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e6d8397..35cfcfd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 set(MENOH_MAJOR_VERSION 1)
 set(MENOH_MINOR_VERSION 0)
-set(MENOH_PATCH_VERSION 2)
+set(MENOH_PATCH_VERSION )
 
 # Options
 option(BUILD_SHARED_LIBS "Build shared libs" ON)

From 340c0b52a6243c7989bfcff026fea1fd2e3a2131 Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Wed, 29 Aug 2018 17:58:56 +0900
Subject: [PATCH 034/321] fix

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 35cfcfd..df44b71 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 set(MENOH_MAJOR_VERSION 1)
 set(MENOH_MINOR_VERSION 0)
-set(MENOH_PATCH_VERSION )
+set(MENOH_PATCH_VERSION 3)
 
 # Options
 option(BUILD_SHARED_LIBS "Build shared libs" ON)

From 801d989213fe8c51772ad6459f159b1b51c561cd Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 29 Aug 2018 19:11:34 +0900
Subject: [PATCH 035/321] Add BUILDING.md

---
 BUILDING.md | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 README.md   |   2 +
 2 files changed, 110 insertions(+)
 create mode 100644 BUILDING.md

diff --git a/BUILDING.md b/BUILDING.md
new file mode 100644
index 0000000..b6d379e
--- /dev/null
+++ b/BUILDING.md
@@ -0,0 +1,108 @@
+# Building Menoh
+
+## Prerequisites
+To build Menoh, you require the following toolchains:
+
+Unix:
+- CMake (3.1 or later)
+- GCC (4.9 or later)
+
+macOS (OSX):
+- TODO
+
+Windows:
+- TODO
+
+You also need to install the dependent libraries on your system:
+
+- [Protocol Buffers](https://developers.google.com/protocol-buffers/) 2.6.1 or later
+    - Building instructions are [here](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md)
+- [MKL-DNN](https://github.com/intel/mkl-dnn) 0.14 or later (for `mkldnn` backend)
+    - Building instructions are [here](https://github.com/intel/mkl-dnn/blob/master/README.md#installation)
+
+You can install `protobuf` through the package manager instead of building it yourself. `mkl-dnn` package, unfortunatelly, is not available in many environments at the moment (except for `brew` in macOS).
+
+### on Debian/Ubuntu
+```
+apt-get install gcc g++ cmake-data cmake libopencv-dev libprotobuf-dev protobuf-compiler
+
+# See the MKL-DNN's instructions for details
+git clone https://github.com/intel/mkl-dnn.git
+cd mkl-dnn
+cd scripts && ./prepare_mkl.sh && cd ..
+mkdir -p build && cd build && cmake .. && make
+make install # as root
+```
+
+### macOS
+```
+brew update
+brew install protobuf mkl-dnn
+```
+
+### Windows
+TODO
+
+## Building
+
+### Unix
+Run the following command to build the source code:
+
+```
+git clone https://github.com/pfnet-research/menoh.git
+cd menoh
+mkdir -p build && cd build
+cmake ..
+make
+```
+
+To install Menoh into your system:
+
+```
+make install # as root
+```
+
+To run the example, you also need to download model data:
+
+```
+python retrieve_data.py
+```
+
+#### Static linking
+Menoh depends on several other libraries like `protobuf`. There is a chance to fail if the dependent libraries installed on the target system are not compatible with the built Menoh binary.
+
+To improve the portability, you can statically link Menoh with the dependent libraries. There is the following options for `cmake` command:
+
+- `LINK_STATIC_LIBGCC` for `libgcc`
+- `LINK_STATIC_LIBSTDCXX` for `libstdc++`
+- `LINK_STATIC_LIBPROTOBUF` for `libprotobuf`
+- `LINK_STATIC_MKLDNN` for `libmkldnn` (NOT supported in this version)
+
+`LINK_STATIC_LIBPROTOBUF` and `LINK_STATIC_MKLDNN` options does not require to the libraries installed in your system because it builds static libraries from the source.
+
+All options are disabled by default, and you can turn them on as below:
+
+```
+cmake \
+  -DLINK_STATIC_LIBGCC=OFF \
+  -DLINK_STATIC_LIBSTDCXX=OFF \
+  -DLINK_STATIC_LIBPROTOBUF=ON \
+  ..
+```
+
+Note that static linking is great for binary portability, but it increases the binary size and potentially introduces further weird problems depending on the combination. We strongly recommend to avoid using `LINK_STATIC_*` options and consider building the binary against the specific system where you run your Menoh application.
+
+#### Old `libstdc++` ABI support
+Menoh has `USE_OLD_GLIBCXX_ABI` option to build its C++ source codes against the old `libstdc++` ABI to improve [backward compatibility](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html) for the systems that depend on older GCC (`< 5.2`).
+
+Note that enabling this option may cause a problem if `protobuf` in your environment is compiled against the new ABI because its API includes `std::` data types. We recommend to use it along with `-DLINK_STATIC_LIBPROTOBUF=ON`:
+
+```
+cmake -DUSE_OLD_GLIBCXX_ABI=ON -DLINK_STATIC_LIBPROTOBUF=ON ..
+```
+
+### macOS (OS X)
+TODO
+
+### Windows
+TODO
diff --git a/README.md b/README.md
index 91e8da9..c62e688 100644
--- a/README.md
+++ b/README.md
@@ -57,6 +57,8 @@ cmake ..
 make
 ```
 
+See [BUILDING.md](BUILDING.md) for details.
+
 ## Installation
 
 Execute below command in build directory created at Build section.

From e0de97261fe619fdd1f946459c993f610fbf0975 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 30 Aug 2018 13:00:01 +0900
Subject: [PATCH 036/321] delete menoh_onnx_viewer

---
 CMakeLists.txt            |   5 --
 docs/Doxyfile             |   2 +-
 docs/image/vgg16_view.png | Bin 0 -> 24640 bytes
 docs/tutorial.md          |  60 ++-------------------
 tool/CMakeLists.txt       |   4 --
 tool/onnx_viewer.cpp      | 106 --------------------------------------
 6 files changed, 5 insertions(+), 172 deletions(-)
 create mode 100644 docs/image/vgg16_view.png
 delete mode 100644 tool/CMakeLists.txt
 delete mode 100644 tool/onnx_viewer.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index df44b71..899d006 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,6 @@ option(BUILD_SHARED_LIBS "Build shared libs" ON)
 option(ENABLE_TEST "Build test" OFF)
 option(ENABLE_BENCHMARK "Build benchmark" ON)
 option(ENABLE_EXAMPLE "Build example" ON)
-option(ENABLE_TOOL "Build tool" ON)
 
 # C++ setup
 set(CMAKE_CXX_STANDARD 14)
@@ -74,9 +73,5 @@ if(${ENABLE_EXAMPLE})
     add_subdirectory(example)
 endif()
 
-if(${ENABLE_TOOL})
-    add_subdirectory(tool)
-endif()
-
 add_subdirectory(menoh)
 add_subdirectory(include)
diff --git a/docs/Doxyfile b/docs/Doxyfile
index a603c50..bb2984c 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -930,7 +930,7 @@ EXAMPLE_RECURSIVE      = NO
 # that contain images that are to be included in the documentation (see the
 # \image command).
 
-IMAGE_PATH             = 
+IMAGE_PATH             = image
 
 # The INPUT_FILTER tag can be used to specify a program that doxygen should
 # invoke to filter for each input file. Doxygen will invoke the filter program
diff --git a/docs/image/vgg16_view.png b/docs/image/vgg16_view.png
new file mode 100644
index 0000000000000000000000000000000000000000..6224408196520d8c6239480062ade4a9bb43de20
GIT binary patch
literal 24640
zcmeIabySw?yDj`6BFn_ULJ1X=c9}?9#7jws5;oG((zxsdUj+oEyOnNqS%iYLGzv&b
zcb|Ft`|W+s-Y3RBdwhR<-}v?#!?8r(c%J*Y@9Ub^ob$TwsjA4WUct74qNvq0`IG7t
zwImFGy#82*f5|uyvyGy-DB8(mn%7?bYIbr}u3K0fo-F3twL{^;ibJ-$Zf`lCWqL&|
z?PC}lJuGn(&r+?lpDiI4N;)-P(_*$*)_e{4lpJuT;pC(IyZcTred6ssI{U6XTT=PT
zs^a@U$6X~xt`)VI4UX4W1mz{>*EMX4uQA<-FZTYhU1>A^@A>i`7rC@uf8e61KmYoF
z<qt1$sa!61y}asth0d_DvnK|7Ea)xH4|*v3-Q1(wlIPSpIJnot!=olnOK~H==AQ=Z
zJ<W^Gr=L!YdO)3hTw_|3a;cPc-MY|iB9<|_ug~-Ar9`;8x?X&(tK@fQkLK~?e?8`u
zPP*{vanH<npJ_{8_VE)ZeD)eiRYfus$^H>`bd9gKcZihR46m5jX?J&b=f(NS<twfw
zBxuKP5;`3rYWuV3%NJ$5T`S*tT*;4#>jl@{C8FP$IbB1n3g@-i#q3lk2bw$E-dt!e
z+RnUY``5ecc0CISh~rW8Eoy9Rw4+fe4DNlDX!T=u@v;8QR{lT#R81~i5Zl4(-^;l;
zb?5dP_PBVRWYhO|*F}{wcq<RRU@i*1{3U>A@7}$u*$x)j@fGce(~J$n+L+Ex^ozOA
zW%bxl7a5nTaWUuE_xYYbe|~Ikv|PY(ped^K*qX{D194jA!u;%Noh4l2<Wg1b?9wb-
z3%=0Bifm*aZ1TBt=Z^bK&z`DCs%ROxeLIn*&xFp@UgaseSMrSS-CbUahR>E$keB!7
z&d$!>nzU5(3Eq=rkb6026;)3iW5rgIU3-#&qRuY;*B>OjtE)91Z5LH<X=&+gEi7y<
zc(8ddxv3SaR%wPFzoi+av^CwVP9@iIFvASjDmva>aRO`fEIB#3A<ZP5(_^k8Nm*b2
zWs6f6`}Fj5to)OmaT?K&u@XK%C2lNRO)o4gT(OZqBH)mj=}1R0xpnTIwzoG%CMF8H
zbg(l0WsaRC8_9Rz5@u%llB@Jxp6ryVlq_#v*xwL!;?A0$jQTvMR09v4WW$;}obE9V
z>1Ofx8h*_f)f{_TWq)I4O_ucqCl{B#Myo>Q)J1%H-0AeVy!`x)n>YJiUi^z`rDm>!
z#q`uvQERIar~6c>!50zBCe@QCZ}!$E#vi}6qPV>L)cnkNRivU{Wg;`R|L<Zu1}bQK
zU6Mi73#)?Ins}Y)Tn}7*!2V13`E`;KGAtT<e|&gwy3jq}VX!6f%L|cs%~<sux7iFa
zhhH(zpKm#2S}lJ{dOl4%K{wRT(3#d(o2YSX#m0;2r)xq_Fn@UezS~E~P_3BGGyX-S
z_1mV_!HV!ZNrw4x%T}{>XSTX)be8yNrCwI<Z_3u#CHwFzR_CByw`yncQ#p%<G@3?N
zwry9MZI=p;RZ&L&x7QbXo3c}}QGEx}d3bpE`1ok}GWADnhki{oy9sE?Hpo|Ymil%6
z`jxQR@Y>rX<+pz^S$Gs&8xA|2VIKSL4ofN4<=C-fIZmTdBR{{quyhM{pNXC5Z}b}|
zIAm7a{Ya!Gt7~bfRl&3@4inwW%S+6zI|NV0<nNoy?>~A}GuBhZLo>*+tGK;-n`YR_
z<#>});lfOO!Q6-<yQH(GfKJl059eu<P1IHCrE1jHk=en*c&&KtnejTK@!B(1^-D@P
zS93_{3Y|_<{St7<qVeOyt>IqM3%c75o2$mEN2Z<su!1ZaUaoWPS{8TgnM_O5hP2p^
zkJ;m$Mt}Cy8F^^oxSUQmjf~ZZR-hk0eq1xdTrW}g^>In(G1VXmr?D27!C3S9lsJRj
z4DKGX#0X1=tXd>ivx{lU+-I%$Ri9c_U7u-XMAqCO*TILozdltCVZu8%H<#Ql&S0eI
z&w(N%Z0dt}3U(f{TTON~FZY*{lDhx!VV?1e$yN`eJ1m^F-4)^3G083&Pa`($QR#li
zBCQ#z;DZQhk!dyYtDa5b+AGuAgxKop>Vx4`bXE=yVG$9L#50*HxQ-_^rdq11-kXH=
zV{nmYeE7B0b#<SgPP-D?)^=7;a8qPdRGdjwRKx2FcksNU_FpP#%9N$#Su%ezT)dl^
znW^BzANk?I=6GCfPlmOlW9G`x%0=1frsigz=4=^38df(oefb}MsE+s6q?=Uj=Gn8S
zvEk#VPmK*tS=J|FV`E1~Mp7(Ru33|DOO?j28sfQPlVD7%`>Zm4)l++|r;<lVFXg0G
zoaXCCr)Oqn;_!W^a~%>Dd<C7#+Xp7B_ii<@&1~kBlU@{*k}_PJF89#HmML5nN@rzb
zi`yx4KL(H8WWq<-;56>IwlY$&^T!YRWe*#h6mmcKI1)kV+z&p4aY#DL(=EnwwG&UT
zSib!ABUiB_N4^=}z54y{TZIYhs7i!9&sEk}uYUD2a_6Hp;7l526grQ`VTr?wpYG}N
zHx7DzD<U^D#;PUH|K}WyMw>w#*Nl)~mu}IhZR9bZJ~KI(T$^~t?AxnzHja)uSFUtR
z&PsSJ<ek58p|h*Y*im54Yv-<AKF^*-3^eC9W=PJDRh`bUi{&mhO^<SE!ZP#F<Q{LY
zc)st#GXWi8EXwcYy_NbfEgNBuoadW2m)^Q_M}UV%1~Ic*ac@5NsZ*zDmH0THmoF1=
z)D&|zj5ReiRl2eF%}tM{+xKY;85QW~I`k`~F4h|d*QAz93DA0O+cGmV>k0bWElP3s
zRL5%cEJz^FO$;;(?Af!Y<ttNL=(>{(657_*)(&qY@aXT~z5D7`Om9uRB7Nu1onu}e
zb0-W94Fe7sKXw>s;_E51^`&DAAB>EM;N8Dp{mGLjBV%LL_csb?rkmEdOw2FL4hkGP
zq=h``kTa{Hu71$CY&+sd`9#_1!yIvIW9%J=@}k-VJ&gyOgw%1m_E-NzlD4t7uK51$
zj)m85`N}NocGis>d8DPK8*Sq@J&+mitJ6_ZdKe)dPOpkSrE_mR4|ntO7=#`j>~<1`
z*~J|sz8<2{pFVv`(q_KPq$wV>^YDkw_P@UEBd4@-aY1Uqe4r^Cr_uYbzy9jz@1K7&
zzr^!>q7&uik5o4^(I1bMjW^79MkMedvF+)eQwnr85la%WO_A^8^s`eGp7Dm(ry7%&
z(J!t{82$OB3dxBiI?2VkQRL6BNFx^F<-y895_*chf@%ofh}w7T8U@c}C>fUrkprr4
zV8Gd(6XY@=itu|v&Woc4A4v|BR<fZ1l4Wg2@zVoMA4^LWT_y)eY$^+uPIjA};N#_$
zCm(@B&0W8H<0DRKLk0$h05SWx9LGWAYKI;K+gCLQuMM5e&dRz{9izr#C**P1;g_zH
zlT%M(W{Y}7m`qK`F-Ef6=#}iZnh^<>v2Y})M=F?%bys**i+H|#v`&rk@`;X)mYQl~
zY@EdNC8?dnRR06U3UuV=$dC{&1k@s2-`@N&x|n@$L{qkH{MomE&3wPZdGN|tu0!VE
zR7bnY{T@7cfFlwuY>>l?OGn&Ie-SC^vEce>%f91ysD*>vp<54JE_(a+SaXiOON<#p
z{mcGx9|0Y01ZuMKgN2I=*BhGLHfhlBZ{C}9N^1IKso&nZAW4^JFJGFkEJk>!bQ#Rw
zL;Ib>0Qnwm6Y2fze_*C3IylX|e*YK$1D^)6>+h(A%dRGC-B*`fhdiwruPuaJXM#<_
zuNC*qps~CAO8!WRKuNH4;ikQYb46~9MfHHs`)i~Zr*Y)4G5a$_u6#WTaOQ1ioH1MA
zHd~E#L`)^2S36!SG&D40`QdWu#k|v*mWd>Q;u&T%Rw?=kYqb`*X+^8ByN%cA*x1@C
zW<Hj5ndk-<QLTzn*2=p!{K>{*>+*A3P1?J=d2zz=9F?)@3knM8&n_R=z$4>n)>|;a
z-lY#D92x35+Z?I5*@sVKceAnV;D=A2<dA$b1_zh5;X!=MV3%^$?Qckbio{be{c~Gm
zD+47V_!qC|r`?AS*KP_Mz~u#UHy@Zo?2h+XTu@L^$x!C9!5#}twrtMH$Z*_K*0lNs
zGLUw8kR-ybkdS`X*Taocl8$~aa>TdI9Sb~Sef-1yjj1)ei!(lJ;LPuD+AS=sGB7aU
zkeQch*&LT@TwVf5P*zqJXH-~V(^(Q36T@rY-=LLk)2XhYa6iMURaj0=&PPyBeQ(~-
zUqMbkx8|~WOnql2IaB$?VdYfkw>JPw?no`p*)lC%`Yotf()!0u#ApG$O$f&bPtd)4
zl<|!L;DFZ`f#kfM4?gTfvC#SDg${|SQOYkme*6f-LuzOshXm0($Du!fY(<S|l~^1q
z=Y{Dm9vTv{8gLvr0rRtyrC7>VkHvh4U*CSiE&{>Ua7e_|8M-I~71><9`sxMK-e$dq
zo`JuHjmutEl=ui}rCg)|u62hdSpeakPQCnS$&w{w)f%S=N(I#PTfxeE_RM*{T^0q4
z3ohgRjXFSM+IXY@m(lipwZ+)_h+}@-o#nws1Vl~^x03@}lVos4+;O1#^@UGk6OC4-
z&CSgj%X&GLUmj6&nfRrqs`^#Z@0&vTbw+0M%qfrQ&drHNg@)53omJ2HG`O4nJ8E+5
z%>u<83C4R><D>&Hckt{R&pR{OOMdTbju+nEYk`;K&FYeBa1ga(RClCXwHjg<^BWc9
zB{sL@yQEvU%Q`tb$00VbNx5b<_Z`MwP9zB!xb5`o^S6Gqw|DmS#Ur>iEHN-QPp~Ks
zm6q~ws%z$X5FuV3(UN1YNKSRP2nDF5Pp}P=v>o8O<ao74@3+_Cw^wZq`}@{P<E%%3
z`D}+wBS_pX^%WxN6l+ma=;4vu*fv-&n`9w#ooVH!qPjXAPS>Ghw`(`LsS<dtW8}sY
zUlRum&d1IDKI3q#opEg9w{N;M$J*=pxto3&sHn{GGYnl7taT9zU~aQA>#dFj+N!4W
zC_Xp;OHkze`#%uJuDrXwI!ck@?3Pjyls9kw_=^{{&O=f~ebqQ6$<tG||L9TeT-WK8
z{=#FF=(c05Mb}Gwg#>6bgC2`!S?fDaetOKF`XX-`SJzHbdEspE6i=wwa>c(CvsWlC
zF2*LMqvm?t(c2q`=xG8JH8Vfis_b`T`$ZgTgoM<@tt+{Vcj4Wd2<_^~nXXe;v38|)
zqD2g(3c#s|Jryh^v1`TA_4xkRz}fMRElzUy<|^^QybEVuZNJuJ*^(ElmwMR*1s!>a
zhVIjss(2WRcI$rSD0+*Gk7Rxju~$?~3^>+-)LA8dd#xr5?Ap%hXI(u8*iebG#2#fD
z0azP$E2+Ld|3S%b+3(`_D{|u@T$MrIH8pz2&!17)7R7I`zu0~4h@Y@QWlvQ!4-G*p
zxnL&Fd2--O-%*BdJMJ#=<~GQ-ks%okm}=v;ZSh%IM}~*J3wFsp?ncUR7)-q*iHJ8n
zGgE?ROYo}y{!2=JOS!gTDc>;m)~7~a{`~xyDzm5Ddp8k0mMzEDGJ)Y(hc*4LAO3S|
zP;~O`+qXE?_rVWXWX_}dBKQqQVwKi1>L;Ke*9H=1qE!Mb3m50Da{EbG0+NhJNw+O-
z74;eW^yqGa?*D%G?)R3!=AoxqHj5>mPFFxmJD|@_J(pR_<f&Af@8XEE-sEe@G2|KT
z!Iu1Spu_l+_tr-#GE(7$1EM?}v294jh`{;m`STe4Y@1l*rKr*+R68=TH`CnQ+!zXb
zGY|#@n7s@PRQ6j+eY7^?pi+(^ogB7k;AUZA5i-cBwiBhig+Nkpt#lnJ-lIUHRRF~v
za+xqkX88nC=InM*7yIk6SrM~&l>-ja07f+c$ehP}BSB?=9r9Ge)+)M)d)5e-eKhv>
z%DwXRh4EyMp0A-N0z_@2zL!vMkWQ(KVJK6tpwcF2*<y5fxB@R2N1fP%Gqfz8kxC^O
zPa|g%vDB>X&2>UiH5YvSs!F(qX2;e;npmb!Bg%M{zP`R4;FsMbKCdrmmg0&&d-8ut
zxcnRT<^SJ5aNL-hx>m(Qz1eUF1gFQj#f5oNNOvuuYHo6rrnubjAg5LW>8f447y<gP
z>Q^I(pg8TsIN*S7F{`K`bMmM?*X@$!-MRDl>TQRsLB$|+yTxlK5*{LzX~~-n|H3(X
z?m33iJ?&EIrp~g!Ge|zE7Sir>N3fqbmh8flJ_e@6n>%+c+xG2Be=vF8c@IiW!ZSBK
z%yA!hViqre>T8svoD7fb35GT`QGa2|Q_pX&kv4$W<L#nhjhR+2guCvkqK@F<=8i!|
z3)pwzc8^WaAIN*pkRDMZ^F8=*K4&{szclmb_3ixp{0c^H<343Ul4d!q9b6n795Y?g
zi?MHSF#m%UL_R~NIEN$+F#aduC4BXrF4_xm#i#lSX4~{xO`h|<W_VvZ0`G{wSWN#|
z@&^lxj=DPi@4x?kSmO<ZJ;96baGMz`9+O*@q@Nu|*i^6+4Y`iVBVFam72$I6NN4^H
zdp&<WIx~87jm`APCHwBLYQs87@-05kdbPASJ-9K@!aLvC{Aa!oubv>uN^|q`k9@xO
z^zhM0HT9aUa>M4$dr+@~i-<Y@;l6(hK|%khi~#}1fqh7UowtfAdiy+KX$Kc_wZ@!}
zfPzr9Zpj(LO)EJWikvT%`qm`qrLwMF8#3JfsSk-IN^!~AKMHSoZa)u9L||CL^xP%u
z;r#|{Y>pTk8|Tjs<l5NSRK7a*?!CtOqh%-8GTGck>QZ>j!NikX2{6D-12aT``*_tU
z>7F;&89~#Y1q)ilVA+%vit=A8Q!;3u!HTods4U1wVHK7Amb{_<;`L_SF6BB^mUv1|
z2Xw1R2Y_AS+{lBT{nVDD_#RIzWApTl@CWtBJ?*ZcEW?sUl~VusaHM{2+Gplt4jmwD
zX02F{mL30h`R=NbWm4G+6ZV*xd(CO%rK%Rsfr8w(BzV_ex3QaQ%zr?$Xw2~WaK7TD
zsO_(eJv=<I*M@(L3=Mrn0zQy_`^hf3lE%g}D>n<LH5L$n=i(CY(BEM4*rX=T2b`z<
z+|;mAqB7mkbyx<!Yb?0GNhl5rXx35m1Q7ak)FeyW;0>-7Z9#eYP2<zgg?pQ)^*X<_
zCk09eey!NBx#J9PFk20ObYrYX;T@Gdr-B5L-t#A0TynszSh%3713f~L#>Tyd5*lVP
zI>|xYCOAzFjhW{4JA2Cb|3H14ZczvZ#C>j9ZlkciZn?x$dqq2fPIv6sL2$eM_rIA)
z>;|Fk>^siVR{SaVCqq+}OR|WDN$Zl+;~vZhO=tKcn{tF`HpQJ0OQt1O>-dS18zDzs
zP*4ehz4HCN4Fr#1zr<tPvHf}WXjGjlsvS{LQIoE+z~9#s2JW{P0JQ;eL(FkNkTx^j
z6>L90V^65RDzn+}bMI~!1GiKLPS)zgYbz6;_Wb!U&}FG<o2XN}Wlu6h#LFMsdniUv
zR%g9s_d9<xiyfMD%iXP&Jz3WpCpSG{trSx=I^}#qypS!XCV0FyS2CceYTlz%#z#m^
z)n)T)?ReRRUd|@nc;m6kjO_XG4_QeoVy^A^+);`ZU%9Nek7gAS+Z8{YY*POB+Yu-J
zQ@ahv*+CR&figVkG;)y?gXhkjQ&3R&oy$eV#f_a8gMxxc`d`B-l`u6WF5LxK&j%R<
zg{<$37cY=bFPeFXylP>m9r}(c+84ZFgm`Kj1J|ypG|D^aO^KuBuw|2z?mZFuV57s;
z$=zfNG#3QMMQ)qu>!?>WZH<Uqkj#7fayxrvTH*qW(HDc)XGRN~!}ot!*&BY$!bc?Y
zg|Lxwby@J^(o9t;-04>brG3HTt&2m731y4!<K@lL4k{`tGh<b!P$3C{7m<ampp9KJ
z{wuZovU96rP2w3H)ZD<8zT6hgIa>HTDXWk@(-EK>XX^(uz~rj<)=bI~+8;;3?&s&N
zgjY^V$~(ev^dm4rMEu!>CVIqy%|8Ykldc}yo9<E&rxNU?^ELO$ir{<|tH)Cc@tN~s
z_aj}a(=26jCo(NtYx_7q*UkC39F*)`OgnFzCedu58Ed|dR+)L`0ynLk$v2a|Dnf;c
zR_VCtVWb@cfNkhDuEj2KO%>5O;Lmf%eaD3&-Bj#A8ljl{N~i@;y{ABN<U-Ifw;)Of
zVD%-FN61=F2p<cw>D8-0$=*M3`EyYv8zn(liOSB7ZeCiB_2|ONM>;}AN}C>}nM|&0
zRw}sExX@h7NRME1pV;6M=Jm2>JYw<DtB*ms+%#wY;5*zVr9t5e@_Dgcri**;N*P7x
zS#q~l-VVIO`TahJ5=c~wh+!~sVprRa{_{$)qrs=q5g2M-ojXBu{JRGShLo;QVlJDw
z(W}$VbO50gfheJDyz~{+3qv`0*@>MB(noUb$=MRjMH}I3vu}0CmK=~^cAhp3Yo1Wl
zNmiui*)+CB&D-WyFG`QLytOgri|KgQc)D=(RsV$Ry}w)d`_CLbGqF8=<tu*+#3V7B
zj=RfNZQ<Iyd2>EEe+8AYoCQfqNr;5WsNDO&wTOWt=&$eu;47`F(pa4ISTtT)y8Evy
zzy*h#$F8^m5Q0H?0hD>raX{aqwLr4ejA7^^>J0h1a=8IPma%fv$cx$KHldC;A~XHw
z1x*Ge9A%Fr>*t=!Y!0|S`LHFQsrAUKmuyVFsg1rHiM(jt{;?QD$M^5w2}4HC)6me6
zVEnP1(Q8MMNH+=Ua?vuldLf)(xq3fwdQ<}n^7t<g^XTaAjxnu?qtTK3&y!fO1`Lhe
zhwYN_;d}PRTsvo#KWchHbk1bhS;tR2_0#10m(~56@d&KOjk{@I`W8>n(<c4CF%Qgs
zGE(VjveMDYRN$+LRaf8Ko@~~2%D+%`)?hGi^f8@ICs6<uUoT>?2H37cmQ6=MmI{{k
zW{FQ<>8Xqa?W%V6Y>0&s601E3dW-rL8E6vx&|`dSe1bYUE+U^O(>vPRFZ{mF+I37<
zPwk3wi$5jZoglooMl<}4jo8&+2{xkQvDbE3%{$LH=Fbj`<k<1383{MW)-_bu<_)dw
zUzonBu*prKX5Q7l<2_Si{Y2@B@%iS(54>4gA?g~5r&An^e1(Dv!Pq70XRAXvdG+Y1
zv$He5goHk>L@n7cKMhzzFg6m&ikuyQ53NFXH%OKB6NkXd(e1$Vf|)<8*gKs{lH9v@
zC+^+5M^b;;OVMzgtQaI}*<OaBj&mnj-$=4cSsy!gL%J^Ik#uQ&@v%pyz8XhmjGE<D
zDjv@-rl-HiI2-@Bak7S~Y20a%qy*#pKkMrHCgZzem>l}Nr0x!8aCkorzkz$cTyHV`
z{{2Zp?0^6ZIAR^vTmV)=%f7d|0$(npt8n07yZ{?FZuH?9CmEk}G3!9eTvuc`XoUEk
zG6M+*&zjDE1*rw0+Uaz*O(ghX1ctq2DZrWSS7-6u!vc^w(D(V40NZ>|T%md9wJ%<$
z^L~DE8IZR5@mHLq{OrTdzXm5v-#WTfnM*rOsOR(_AQYg=%Og()q=2tLq)I9FJz1DM
zT|RbFPR{ro&tfWcv0d{^re?7ssHXoXb@x9~UkqL5;bMN>lE)j_a?n7wmR7*8mq-|P
zF!7Ik;9Llah~S3saq6R~{3%dGU?CoJNX9*T#(Ke?d-v{=`ucj^Me6fw-9+v9o}JXi
zBrt`f_(VY8^x%V?s3$w<9fU*^FlIny-XFHCW3ur^AzDgQ_N|_QP!(@`a50Fo0-7Bo
zj0dQT2J#DRa$Y{ZV!N%>s<SEUaeIW&`8Vv&fA9zSaKK9&dwU;lx7q$oLJ(sM^3eFz
z!fwU^y@ZZF1i=`6DmcT<DA`aFp?YC>^PD%q%P2GAk%hLJ2E!SEJsAgW%3psg)v*ep
z(PVBozZK4d-sap%#zHnbKusd;8LaJZ$<GDYnETf2%DQ~{a?{F)dx#W1-!J6Y_3T8Q
zdq$p_l3+sx%CmcS9I#}`(>-3jb;(wfErVc*Ou+d=-jfSxU%!5Rb%NdjfH+bQ5WSO#
z2n4yJ%JJhS1S24>4>ytT+dn>fYG-UW3|7hy(mVjnc#~~;4*)nlqNqq7dA0QL%yZZ$
zh>}9L1O7T>(Vz(&0Rkx)b@{INnwd9szj}INK@Y~d&(Ca?x(pU-#mbc$HZ~)SlgyO-
z1FjWEu^2UBG7qY=ZH*CXWWaBJ{%Va+fk0OQEsqrHi3Yja?Vr4KpfT6rHfWVy!5&Gt
z;Al|?B7RCbrx9eT94uupJ2{w{YY|MRhoN%oMlSVQ!pQhLyouVJg!WK}<43CeFTv7A
z;CWwfd+QSci6jnXoP$wCMTLp!(8Pp$$lAXCejysmMpp*P<abr(gi_2eJUo22asW57
z4dGQmNzRtGla0H#VCpzr2dTGGaW8yWSN_v!G2F4P(<5Y;23)91(A&k#%q(;AWKn&+
z9wBg}gWbWjsnj>*P5*pBY!Uddbmwu?KyZUVH$G5EWFK#j#g&<YB{3<R@ANa0`sKBR
z^1g*k56Qn1q5w)3TFKA>Z$gFECK<%Tg>Y<PVZp}1p={_1(A|B(O^N{%2o)*w^$=y~
zNH167QxP!5t__6{4G&_V34%SzkuP5^Oj=`WihTI^u^~_dl`nST*0|M__aS^C>y|As
z5bFdGcfsseLfYDI*M#-&Y-{7fjeU8(kI1|kZYZmsa?8lb5L$%jtKt)peukAJouwNg
z)Pkll8UFDBrFK9NTqm;=*_XetA&k=?RFFijootv0;<<k2DRJ6d94e{WyncNcsVCv&
z@v`Hf-pqrBiUHx-kZSDp@zJ(uFzxZQr@NtKR~T`KTr64(+BOE#u4!XNB9YM=3jkZM
z{QT@6Amx^GpOufk`>sP@tupG5YU5zHC>S2%AZ`TUMMe`&!#`wh-M-z6iyZ-N6G40W
z>v(rKP8U7Hy#BmP8jMs<g4#hj%nK7?VPOZYf1Jd9N)GK;68!>EJs#-V1QltNV(~s0
z1)f3Py|r?4fH2e1O&1VG7l_htS`l^&<sO&Z+3DT?cQj=PP8-pb^s_5<SEJlX(G`TG
zSTwY6kIGB$59if%b#-@ZPYkI9ibdj2Eb0$Xxfvwxfzj=MozCpJhy57qn+w*n6Bho?
zYA<e_n3&@&Ma&|LNWudMV}AXtR}iK-&$v+6Dle6vvZ6jB6vsi(B%IzFcCiRBVK`Gt
zxDzeNv(+h=6az(VW$A<yxpnJSEUX)dhgzs~h*Kil<`VX?GB$(;=;AS$EEFr<%Exss
zm%WSy6;@hPqjjm|S%qV(n{nf2R9v2(6jX&?Y!`KW0ymMh_%)&)BIQ8}vv!-PH>NL$
z&>N8cz#Q@!6}a{`W+n^C54IK>0ck#kQVS}?M10^_c5W`=E$9*8f!L2+JqoGgnt4A%
z8%=I4)7hs8xro!Gt|3wuu8u^PN9^L-;c{NJ*iIWaYzPMz*SL?<ZS0A<hQ=Y2N^YlX
z*W~H$3)9B<%N5Z0^a$WJ#Y&@~K6j8J9pAr)Vp(F03f)IWM^pRH<U6O&jP-=$L73ph
z0U}mG+<fqPAtu*gxwS%%GZCno1L2_An#k5z`$IruB#nTYR70iJ(a{kB!IFe=LUp4E
z_|-c-)$T<Upxk8a+Nf9;sBkObxWL+K!qX!;*<?GJU&d^~LY+D&;8~atdPtXX$&v(!
z$jXk3h?bT<7ZcUOZ)?#H@$;8tBx7G_)3jkLi}&;MtAQE;4}u8{gXxetn|k~D%#@Xt
z)6-dC*-%Icl5%S>g~bk@s7!?v=r?@@T{$jID6J|JU*jQb(`peAP8ZJf3Xo6Wkaln4
zF9zXdj`!4(ki*>vMg=*(M(o_*OU)3E5?WeXw7~$xbDKfG@6W<|o<XV~2cd!wBg#?P
z_ugL9ao9%KMc}l!Ge1mze`v>!w`}XzpI^<wQvPh>R0_xtvpZ|pmHZgqP$;Uuz5nom
z><nV4!m+;8IMCJ>f*Umf))#Xgiy<X!qfW?C2ACcWcEOWE=LQ5;p!a7?&X?IsLzS;U
zW&aGRqbyL|49_sb?UdyBGj6O-ajgy*xn*m%$HZyH_rg>GX28>coo?6uaW$=y@Po}x
zW#dT@L(B-_`1o-x3L=<+1ah5`Fe18wT*?N_7UrfW6Iy{lQ5H26xVhX;nmpFX_~z+d
zt`%=cUc@5$5;<`7*8L~x)p<^~@a6PAJtb8EVwzxB2-WSOWsAIBGehrKI@{X`&p@N2
zzHn`waC{euB3&g&A{KZt$|TjUM;#is+;8@=CfUdcxmtrb!-5y*<d7okK$66jOU)_?
z3ky4Z0&voS0-ibR3@N(5;h*|c#-I))Cg^YSIivFLID>8H<0q&g$Bv6R6jguc#*G`O
zo8m=UuAKn0O8huu4Q9!FP<#&<msOMWyo6~5uY|<h?<+oC;F=9z6>*jz7wa-ETlH$&
z+qqO6dLjU?+$8uFM`Qfw3#(qdGs8?H)6&3gtU^xAX@pR;<DlEW&8%3xS_@h$<cUN)
zgedXeSsj>F;t8sUDU(i)!RqZtR4W7TX*%w)z7!!z&9UnxXrJgyq>A>dsi_eZj{h{V
z(W^SQIR1FQTypgD0f3RJo69$(<Siog#3G7AtX1}%3}nA`^CplY4V2hHgB6~FA7KnK
zzXUjDBFn(Mnk@p4Rbrw*X<l3c>HelFwe}e6(Zi6vwSWv-053fS!RmRpKjT&V``Z;>
zs?Fp1Ar=Jv|A_gv?X^jL3IY3^vra4!n&F}81>N{%Q-AXR2p?G}c}^14NB<nWuqZ$r
zAzmDk)i`P96;eBP90L`m2IXacH3xOo3dj;HIP7v2Fv%r@yNZY7DL~vYDMI{hJj6j5
zC$$lAYtl?K0;N3+=|pjXD$9Q=NP>v<C>YJVnhM-<QT6ZC(a}Lnl?OO<iD`gMA_9RR
z4j)$^mJfFbvTr2F0^=A-s;%W(>U!!0Da8Ad3$?FYiD|jkzB+&C@0HHIvC*u^?K@7~
z=EaTyD6fXVJwE)2lSr{h=TBN(N0p)R^Bz1{?T|Dybd~6_i1Wm3MQYAE;?}6nusD-z
z@%ZuMhF9lqG#>^kgS+M8l(M{kvmxOooDOWDB$naU597cQj0HuK7##bNGvKqT+ic_-
ziU(f*cO6(E?&huIc6N5v$os@20P)+bKIIZULiQ1x3DQI_yp+xpzhZHF_2ZrW{luPW
z+%wKVrECV~egV6&JRPDAAC34mTihlM2x66<8@d5v8x~3Pl@X|2aH+s%zTCO@6!5)T
zxSvCS5#+c7JXYbUSj_G<DoB9!tUk#Do`yud)ZH4%>nLxxp@;aAyLbP<x1Iv!<BhX!
zS{)PmLd2>BPJuOR)(}|$>B^#?k&%(Oz_4T%O<5JfC(8m3DGm=0lOlrfNH7&NjuXc-
z*`@=1$BuU+ov^a9KC@_Gq&T*tnl#519|F~*m#9s$E_Oz(_l^^+$cw;lv8ei;2eP}&
z`)85jpaook!;dib0S8S0;WyFfNLJMl=!uO4lHCll7N=Pv5bv|_@Cz9xEY!8Dn*>fZ
zF?zWCn-ke{aCX<OUE_!#CWur7C|zH{*@SdJVkoJ3&!l~Nw{rP%HSj0R;oB&iWhCB9
z&=!RQ!JlQAlFx+-{?7x3t+f*cB3#k{V3hZbfA3HJ-&e3r8gL!M(=_VW55_1OfiXHa
z`5%RzTT^6n9o*&5M63)!MDS{m1!HMRSlSj;fXw%3>j7DCC5n!VNRxoYA;<-#rKJMR
zhc`XoIiRR?0r{jM$37mR%a^a8f$}1idz#y<gI27%Oj1%3jK|&tjgfM{$a@EI%?fUM
z09TIC@0t=oqZ%gP?3^6_ef!j)lUKtG$4vv5K^znCn1tid381pAJq2<Cj@c+Y4sv`=
z5lTRH?4l8s5?(1`9AB7(WLw=Pn@<=hLe5P)`*sQP;AI6D>P<Vbd=qow?%lEgNVRb5
z?dIg<g!4)TMH3PG$59LlAjxJ-5QKzcDjER1_}#mA1N#50<Hiui`MJ1`hQj*f2GdV1
z>cvAa`$5K6KsMGw93W<T5SSbJ)K9{U`xOrL-`2<$fF5jXHHSvxmZ^~AthdNL6J2Ba
z<!ie16>@ba)-r|s&j+%&x!C|tM1W$T)f@vCBO@ar!@MKSjRXJ7n(Zk!&Xp|P{QDS|
ztRd4XIPo?yAtOxb6uQrM^!2@n`iL))oG@dio|A8cUnmYrFv%apnnI91D6>g(qmZN5
zU8H7B{(CW|a6pYXcYwL+DBu7bddfb1g@m4VZTLJf9Km{{?dqD>;@l_HXpO_Ga=@BY
zMQo4^Zy5baah++~szwnQK;${N^+=qBLB`jvD`Ol-A566%YJmMGx=1twF$<-g*l`+p
zW4MWz1|`@`$J0}GGh-%%ofCKX<<0Fj_5BX&nb*n>bI!aofKTl!?z+E#gZrjCR+weJ
ziI3v4#R1{P6Hm??xzBd+N(eG{ce|IgFE`<Ec@&<h5}plu(W=0B6kn!QQIE(@CC+3d
znb-X;{pocFK_HTlhbLH@J6I48f{;e)K9ah5j~vk@|L)1a$kBHQ*h&Ybq(?&6QV<po
zeD;i8FU<cZzk`?nhB2+jCWWBOYG9<?3cZV*sCXb%<P5fRQ42w!dWJIn#2qb<Lv24n
zIv=iHZS%0dXr(v*gORFdEDZGA9&)83j2;1Sy)9{}d>=F&e(i+k|EjdXdiD>7HEaEw
zmg&(hA8+qBC--yRAvT?(0BJtb9`1kfrUd4e+BMIATJQPt7T1c7wIoTw@L8EqzWg~I
zWyIdXIdxJBA;&8DG5%KgPAp|+E`{&|X(h+H9WpIN7zye5v8M<r7hE=M{^v&_4**s@
z`|;xkB5#C|`}7ApT2UyNnS-!ox<Sf95_}4O0~{}J)^18;wt0?@2sPAKH8_t^xQICH
zPf{JZy1D87T<-r93rz}WQlx>r;e$yU8IP0>FJHb?@?(CpmdK9~kgq_l126NmN8Otd
zoeNifeS1xUcaJ)?MHU+5E0jzq|M?Fe)`r$aSk4}L&>t{gR<lUYg|J9Xy|LpvwF*VU
zKaDx4a4(OsdvYTKO1y$HY>M0b(Y}G=SiQ*oUv`}TCoD;xO4zI$i8CbJODd<U07lo2
zC$rP&@##d_2}@gUf2LKdHaMATs9tgdjMRQc;$^vqst&pc(Y*!s?W?eC-4pD()6vn9
zRGwZ<r{v}Df}~7Bp_|)}Q&NXRa0vFs|Nee809_w!a&!gMXTVD;06vKL5#!_gc1@mp
zt$WaI#*Q>X05kh=8^Gv8OxLhX=H=yaWV293gvu;B2@Vh8#Cx~W^AMC5iuBzoFJn+U
z#l!HsRqPXiUqIJQnaU`WH*VS#Mf$EpMfKpPP>1vYx_GFlj-vc=`Y8Vd2zGFzR;QU%
z*+GsVE^1QSq^8>D^jkIOL;`?)D<I_n1LLx89Qet8<Ef$Vq@E^?4|@&GMOLh&>YqIA
zSwgi9mLXxBxV@?Z5<3WazKsIfN>KTGB^&SDx>ettG6`9{aAAD!_(1a+M&>n|xV$RK
zGSnDgAnQu^7AE}D8sRm6nrgE?4|*r%4LW-GkXe-j#k3$J({H@Xmv)DqXC|_f4YC+g
zDeUNHz!ERI%>r&el8}%{v*}cTm#@#-Xc;A;O`7!%86YCk2+D-{x%-&3l-wgW(t5%V
zhzt<%?h`=iDdMVwnR7sV_zILyXCO3E8s<;^ct9!{5@KUysUn4kFk@{(tA-93XAa(*
z3YDYf(#iPPCXt&h1#V}o^2dFNvmGF(53MBCMNf9wgGiMV+D7ePjSZBNjTDVuxBdc)
zs8hj7u;;Djl+vfOZr`2&6#3`Q6<lXv_j<Dd<)aEv52>I!VBY8{YY2O~Te%WYme|(c
zZCrA62JGR`&22}nhLBPL!N1Xh1<8w;t0o5$!T6u3VR)0jPj5NJ@%5dG_7dtF;miJ$
zvcrEI=>6{@;Qt4HvvAzib?$-*BlQZLmS^EwPR?YI>&>={=>6EZb*sNU6T_QU(vG)q
z96b@N_%#89Tc;o1y{ii8b|Wa1s3X+1zX-8S1uexv`g)*TA{@|^;5Pd2LLMy~@YG(1
zqtq<xICX7Am+&`s>!=~_KS0ZqvkQ37hvQ1`=<JLH1%S10+i?}{yZu+t>4zqWP<nN;
zku<Wj1W6DVRmr7*6q;=*E$u6K`kbOB$<;Gob=1^6e-M7DjZb~3i)Ub<Rs+=nJBUvp
zhw<d-XcbB|Qm}wyerG3o7(fp+n+8av4wO~!JxwVpX)p0k1XpQV0;@Hwfa{ZtL=4I{
zfVH8KmI2^RVra!nv-UtvHNOBGJR2uRQoK%5QGdfm(P-|{9_{-t)#0@24~;w`)^q;)
zaW?E%blp9Vbu%b*Hz1uDAf?hks?1LoF4mA3KpLqK-~1ayD2Y{;Ul@xv5nDZ}0)+WQ
ze54n`wp&SOf3ISNG(!+R@tdK@8~?D`i15+(@7*J7xPw@?PExPlUF4w_lk>${l805M
zq!&bsi+Aohc|O+kZrmDmaUS2(r)wTZ`trL!TYA7kGRE}ynbHHkoEFC)Trum>u&cfs
zw~t?Ji%a4q{*7@H+}*oQuRD1>V|M!8k$#h3+^sh!`*O<c4^7VJ4-R&9cXqV94A^qE
z6Q-D^rZ)09M{w~#G+*eXXS1aak;E^5-ZBq%DL~qzphuqaW|m>~RP(*m6PVem?Ql6t
zAxQFqSeaWF{4P2WEJ(rL2Xr6RPI<1p&r5|9Eo3U+rPJS9%~EFS^w+-yVXJ|dcRJ<b
zy&jMtf9+iHCI(Ea0$t+3-fb#2i$n|f<sdE)My+7~{Q=uWchW|(T#K*LXZ>(VFsQ$b
z<fK;o{&ZY4&kM~6s|rn4G)BruFV3Z=q^2s%F;IK(-gZH2@%A}~@ml33F}9=Uj<5TT
zKv@4_hF!;`%Kafo-a*Qj=Vf(XVD2HiUOOKr?xBqG^zJ(+X3UNCr6TeUK#O?t<#H8#
zA^I7{7cY|Dlr?vVUVOU}G3o?9<l-g$yqKDmo3E7K?<^_%TzSAC*JLDRqs=qkb7Bn!
z_Z~m?g-#~>a7!qZCh<%;Sy_HiNVs8b#JjgQLByz@WMI|XTo%Ra{O!ekwy6L^C;pSI
z7EK}Qoh3c7o5lPeJLnL-3XcI5v>A$PdIY3WC=Gl7(Qp*p-mv6N{xOK{Mu^Te89qje
z^b)N(`}9{gJv?tK1%)xS4pvp}qRntQM4F1Y_1^C4m7KG{ooiP)^c!Rp=3a|Ee~LT)
zqW}KMh2?W)DC`MsCL<@;hgut!RaIHp+foZt7r=CP%+67&Yk46rZ{tz)@#PMbw(S(}
z>xX0IRkxyKV|esJzI*=pDCH*}{`=Wxr;jsfJ2hRbev#7HPby73m>TGLsKaz&6;wk@
zmy#T#r_1e~D?*A!M}(ttzMP3UQMgc&XGd#&@6JPW?!Berd~j-cqG8ri&b)o{55l6m
z_vX8l415n=oc#FWwnnQy5=%9h0K(qjso<ym?8~VEzT6&)x*A=wOk4HWy^CGtU1f7&
z_man|%J-a-r<)$K+(~OlwSS;6#Vk)(M=N<(c~s2EhC?f)hAc`xf3C(U7NF&zXO&d?
zDDK%*n5fA$GOS0R_&o8AN;h)fA$M=RX-#Cj14LVczFM)#&6AUU+%igwN6KGYS`K7N
z2IuCVHQFB@7G^ipb_|vC?{tbZoMv3k0YPKal{Hk+UhG1d+FRAB0iwO^H1%Qng7eSF
zfreLh_Z+Mm#-hZfD2j8C%mtVVo{yzRh_-*~?Jmd{{&d;c*kCeGr*K&nlvke0LZ!Ef
zvK-<LN`!Dl*}=MXD<84Z!L>-b7l39~3Nlk2dy>fZc)oAM!l2+;=v%eH(#B76l|Gpr
zJh4h=Lw+2#vT^#=T+pA>CFU}d#vQ9Zezq&)lWBGJJ0Jee)(umE=zBHTx^*i^Y+pD9
z$Yw@)VfN$wJu&$6u6I(NbMNo-dd?mn8RixWI4tAV!WQ~!UHBo}YVnz$@g6ZJS{Hi1
zW)?2tj1RkE-C7*4yN^jLF=;T<HGHphfcqC)x5DXdoj*HbO3fB|7E><yJoSmZ%r4gJ
zTC&yW4_=?a@=KuI(Eh81mZ6uy^vUsYE%<Z^RzOn=6mPBRAVz9r8zRQQHpR=X5fL|-
ztA*2&gRXp&uh-LKs}GO&b=$9aT`Ml8&ttWApPzFPwh-rHeqT<PsCCDyuw?~NPvyK~
zWImO}HHJlQQgJgfQt~RB?D7r@N&+2Ogk~S~_c_$pVXHy>IZ0$9B_*W-V+PN;%c)6*
ztC*-|4-w^Gzb@4ps9s*BHX`GjYhYX=kpMQHv=Du?IVme^3Y`=5_%@OE%&J#j?fgwl
z;V6-@3nT;zSZ!#0f9UwMfPjGF;TOu5mU+Jzc_psNEIF$Q`iqAq>X3Bi^C^;c0Q>nJ
zCmRc&NK+k~NrXhi<foPJw^<1}f87pw3oCMfosrT<VA-;9yK86EaL?oQx1Tl@g8hm@
zPn-q<ju`eIv2^xDCK>p2evf@1RS?zQ<VYGyE|sv7t`4Nc1MJNI_>|2Y>q1STa-3i8
zamm@)|FLbWyrN<i5TXy32ynEdyu93wo4Sf9boOPlWnDz^)A6BQojyN|WV`PBJ-d|Z
z|5z)6Z~<UDYQY#0wY|lcS(SJAivqRc5p0E|6@{b(bNVkmf1C1>XD%v_d#*SN)_qa#
zkt+CYZK#fUl586p9o;wd{ar($M<FpOppUnQ_?18;jo2GfSsJ*lTV-TU1oXqf_8)dL
zUBSwq_|!rDj=$e<Dh3avw<?;&sB3wMYWUqHyw&b#h$8lgKl3%+hTbw0QKB~4$V%+~
zO0<+pPJFx2l*V!N$=gS>6sswCIBiJd%Ac;PLEnswjEsdtAS#?X`sAbZi{Il8WPZa`
ztUE!B|MkQF%^Hjp6V@5NY;Z`6IkQnp{x)@^pFs>Eu%jtYxY5?eMiaIf&{f?@U5GeG
z*D-mz{^;t82Cq$$p`>K<rB;+d&;r6y@imQ0fOCOU;yNa1^rpChhd|TgGZdaz>ujl`
z?jfj#q}cXfyo;u)aqx<wnUK~@!LktN2)4_h^O_f5qEH@P0o8vR0xowC`d`Q|qf`R<
zrKJmVNzh@$Lmqj81b>@_GYPCGY3ZP2_wONd8sN2Q6$)%eLrfLqI;$hQk+0XSTSs{J
z{Ra*ZYcm9;7*xKF^V=z|LTnqZU?Nw+9yZe*?nP8bNTmcn!W3G!JvcBh5hq2I6I`M?
z?9m{HERU2U#QXU8L_#3YgZ0%x?-rBi-$j;U6xB3{DJNrP;)7R+DH3BrKqrSlx;Joi
zMO9vUW&#U4m_HeWQ4kS07621d0iQ_S3&zd4C(>^W^Ach~HB8QBQ*ZJS-zip4;#Y%C
zOT<RvpUKWPSnSM%vMwwT252pYmUbk0;M&-2WvQk${G!{}5bj7^eAZBUHI)@@?t4iu
z>I8LEZG^D;=<CjD_A7@qvWJW=0C#DAxKW66^5ZruUNo|Uged&Z>_u8EQFvZK<=p!<
z^ad;{7-ZmnW-CJo*J}h(ruT@>0Nt5d$9Z~4BRkyvmb%BWS<uBu5gmo_n}mKue`GH#
zHaU&oC~qqSUezM-i7F`MbH6{wV<t2MP?;|`3?GErO(4;MyzD(eU0|RgXV5{e@fc)h
zc7t+&zhoy7Os*cMvJR8Qu_pZnXxOVsH9qCnPYmeOoqjMJa$UM~X{!P=Rrl$R57l<K
zxd;EFl63za7A2i({|Ze1>xX|`oveEx8gMdOu6~wY81`DCz(`H9V7Z%4!WM-I1$#bx
z_|RGJ2VM%4d`nu)5^5yn#Ttr|IY!1=U`_|0M%0l^(kNrwRVL;#k?^xD(CklkidFe=
zX^LRg4l0B<2Dat(8#a(RD4?~7QA9ymxdyEvAfPUbaZs$HcraNq*nk?Kzzi~&n3(wB
zI#A-Gcz<NcvQn1t+C0ac0R0Rc)sISBs4Ny7<+j6f8P}FEF%A1lP)$rN0nDC_nsBWk
zYgk+0@_Fv_4tWxkdD#402sqaM7WU|HSoBK19AaNN84HgaX|{;dON}Bj8eAwZ9xn}9
zi=f340?NNTe{v_dIQ|#L)}7AJyuYMo4dm+F_-tGG;VIF6IGnq8T-Zml{pZh0@ENw~
z-Zm2j8JvNZYl!KFaM={sWrKK$#*XhrItA|41h_f~jSn1fM_(SbLS$gq3W=jBDJf)h
z5<01ierl=54aw<otf^l}ZFP7T{vc%Ka`l;0gqH>eyCnD#c-hC-Hwp~mg{?`Kpc4=i
zH8BLVwY4qrKOioC#`foDxHBKXpUVc7ptyT+8+Cd398Vj=eyAA4PRzd$lQ2>)&#|WJ
z$&lyk#(w8cADx3Rh#>2mfk7xKD*BUsrRNS-wKj&=9*ge3EkHV+no$K8+mod~!)z5w
z8nhug_1s{Q`jeg6bI087B^+yQyS_X%A4n-VT<bQqTjG8Qj9%KHO(T4T4dT+$4pv#C
z-)0>X$J)kB3mwbXcP@>#z1zVnfk6qvwEGVp9C*3Zb2<6StMCUzMjJiLQ}lnlBnzgp
z0Q1A!WLU2qRXcf|`Av<{$l+w_9gWff9|19@8i~wGYz4*08}^2=t#{nf_mOx;=#cf1
z?Ice2Y@t@+X%c5Cb~8Mu|N4XHHvXUep|4bS-1l!f^<qIx)2wS%g;DEjE#2s~*}2Ug
zle_vWBOjO_egV#)Jw<ZYt`qRe*&NxfprrJ<ZWa7NT1St1B4T!=xPeO~h9JoDquZ<C
zk%W5QjoN%VK$%V^&A@8WwF@>RBE;aI(JXVzHJJ0w{EeL}+H#i6xgMNcoU9EA64Fe$
z>6PIT9CBiLwAS!B56R}3I2#+Gs&#|eNKfGX$rvYL&X9W#A8JC2mG$CC3<(Kw{qhx_
zQd%V}1Ns?OO<8JmyS6tB#Nb=jkMe(JAa_u+z|~0-nQl6uKNB58aghHcXMd%Nxy_`Z
zEk6oI&2py0(w<>nUSF4FC9U&tH`L<yt&lFPkG4Lr5S#F8JB{uaZE$JMZFO`h=k@E?
z*$!NONII91nFtvS)Nud)eRcRlpoxu2o&X7ZF|#op`l??)xM58c74}3H`}XP>RO@HI
z=kRRaYpB_nVKFM%Xa$}@0qO7=H_@$;H)rY!7b3^T?53xNJ}jp!A8%Bn>c-^tq|?o(
zvdSV2DszJq9DG%2IWPSaHx$D`YjKz_LF4X%RR2bc#l}AqUrNebEyg}_b<2BsVL>%E
z!NG0VS4_%4(dxETxKHXb)6qGR@%r~tah$G^pQrqWDkg5d8=Evq?kFD3j45cy?iTV9
zFxbf%JiZYuwHngQMhrp&6HWRNQJE1@9rXW`!O>X^%K<Bb&J0g=jpRAeXv|)L_=9Mv
z4r5rF`@D14RQ#>+UWK^jERtj1OO_-xMc00LWF$mcu1?-WCGkZ}_+(zIvycuMQ}h?v
zKC8WWn5{bX78=*m?JQod_fSx)J8VBb+|7}ao7=gyvF+adfWo;mLb|UtyqJAzX5Zz;
zTpT_x<|1X#SSTHJpJld>#ivBfD^_)&q<nE<2QAvYcyU&_q2J-lOHmE%12T*QTzmqE
z{uoGS(^8XKFdzC{(wjj)9}f-AH~J+#)26J~rgce)*r+8bN&0No_DZPrR|vLR5oZdC
zDnMN0P(X;+TYe2C!y?1_=8%t&mOkBX#IASsC!f82(VK%4<2OXBkB>BtvQGCDj`cn-
zH0k`w$vUSiDp_~%+a*^AmB$NneoUv==4u=`Ur;f!dU#}fSpAE%#7^4j*Cxr_vG($Z
zy7pNFX!>!x%?G<Ng#zz^EccrjY~6e39r<bFw<h(LzLO&6-?%VoiOep*{3U-<V)QrX
z)`|Ya$dlR&UXt1&Tl=bG!*Toom1sbOy$$K4KT<1XE5&MoWK(z1(b13FAm^q1J8S!R
zE$=V86Bj2!gpDtYXL{tD1atQkvn6r<x+gvLRQU2-&ffuJg?#jg%7rzw%8!9}p82}#
zC2m_heKOcWUD<DcYP!Sh_1tT+nR^Z#sLHN{WGe$VLh_rRz9WWva=^#~F==2l3~`P}
z2y~7i5Re9JG-t0o7|cE1Qzb|A4iKiOGJgx4Fd7IBZKv)FqvAIcd+OY2cC6HAIQM(j
zkH-Ra*MlU32T~+E=VWMfBkQ_M6Ax+ON$KD`$5eytjhdIWAJ>{ox4F6$s83T`vAVL`
z964<GUQG+3dz6`lLldADY7qf$mo9H=n!{KVVvT?%O1wuHanu#b05s<fxJ`&vW4*&_
zCtG0(A~L#0lu`w#Zqn&NY}^3VLPLVo{oUju8*GP4`mYDYO+Ggl$uj7!Ilr~7Ylg4K
zbG?rCk#d8qj+FUc`$r-+<3dx$$K!f?yyJu$SNsjQNDRHGr4=#P#(DIMh&|$$jI8V?
z-DN!`oeVg1r?akxa*IBQfzcFx;W${XRfx=gG3xFDp-Hee_Rxr}x&jxn=J$oTbnjtT
zkVp&}VQ|jZ5y+k&_&MHUs3Rp=U~3hIkV+z}?F;U7i-nuqCUq>dOvy<{>Fsrk3$BLB
zeG*Z-?fLtZdSxsYr53HK-D_Z=N_zNk6_~nGh*x0jRf%^M*Nj%atT#6L^Fzcc-w7%n
z6Fj;KU{m4)tR|5UOgWhpwxrZv$lu?;0X>V{v7qi{Qz>4tEH7TqKDN<{6<_8QPmQ~W
zh6b&PjdQ!>L65#;aEyhyyXc<L*aY*UYDu=;ynVgHcz=^_u-xsQM#<%I+jUQ`Hr1?t
zd$a0v`t%*~fZ0B)3I4PTsIY|GvYj2TH%oZ@4@8cDH=Zv@DoynI6LS&RtGJ^n2;RDu
zmX@S31UA_uG+c^KrkmHR)9t2)&Y=|`^61E13-)N|)g#ZqJwSo)Mn@MhdB8tzvdf8L
zl>~CnN@83dJw9^AHr>3L!|7Y|nBBX$I8J>v9EUWaff(B+xs@V(BUK)JA|g70L9vN)
zjEX&jW<SOnvTg}aa^|xeSvBm*&3z#u*|hSP#WaFGDJ0PA6d>W0Qd)py5R21Jib7bM
zR&aX-2L}gT`%zLdGHAs<en)!ln3sf2rwU`#04KcS>O{Q<d*y>JJ>nLHLJJa*t(Y;S
z`y9g5>OcuMm3HHW(Wv%K$ulYsble=9=b1OC#2?GdtJ4*pbN1Who-a^7@jh5RNmNQ2
z@QioIj_(1p001zdtA{v67!}rzo`ySQ<)6jLzI%-<FB(#loZA0+4x%+-sf4_H3tzV6
zQICFGVHzD4a7=G86Z{C@z0cF9;V_*6;bAC}44sI+sPZm|5&(^KeqogH&n||UM@zY;
zUfaN9vX8y}I(oJaRjo@RQ}OuEWF+)#NvSuF+C}|&b0+}i!iZmC3|O3~3zRSnP0yY@
zIVZM^VkEd4g5Q6VN$IG7O$6kYBArY`Ax%LrRMR8K&^ItPnRY?&mS8r~-_y3}d_ZGj
zoeSsG8ZrZiWJx$CElpf4EtAO5KRFI3?%<~kZ*E+NzUkHKKIus2<6QX~(zsyywK><Z
z50kQN_`--$2=41ay|UaVfWUASlOD26S0(Ii?9`V$?9^396q97jg8m|7Ey$$N(n<GZ
zG>rhCRl&hAvfU5wCHNfSnBOoji?l0{<`2v%QUfUAp&|ci!?DXlBgSzk+B^n&26Kap
z3szbQx@y>-rp-C&@cs(Yh{Ie$QZg{!3%ws~qBaq~$qVArgO^Fb!@~okTl9P{HBZ=1
zjF0~wTm`StoUfNZdLn?Jp85MbHI6b+BVl)!d?k}GNiz#D5;>~CPZMXv%Kl+#Ayew4
z=EpP=4f9VEqYfVLZ`4d|q$q5>yS`yEk|ycWfhYUmg^#OHt!3v~1cR`^s+;0oNJ9_q
z#2!q!knXFa#9#&&8}Xmv66-H9>Cj=43r8uFBY`bGdhw4x{>VyPzisVWE}EkzI&qxp
zm6@rtEl|=s2L_VhO(;fJi&<?#1(<tF=O##WzdKqmlC8|fVQ$JA&E)!kiu4HNyI4GL
zr^g162QeA%pnb0<G4n%_BVq-bHV3wk_Qogkb90|W!mL9HhK_e@(#-^X&nE7WKrZb2
zyE|Q?lSYd(b>j2k6vfH~Ft6v!16u{@5U3O~Vw@&(35ZP<Dj`CgDSUD5zB(&YQ&KLb
z){i`#L~vQiL;&H2Wv$si6-*4_Ho-B)VbGfy0v;K(+Pu(Lss|?;dPq8KT0poGw@>D?
z)s*U=*j2<fOGXkPPr)kp1cBaO@smM;s~!R=*sUs1BF|pD=xgf2oLm}_88PuP24LIo
zg3-0_Ok~y=o0we;nW_X`l|WtR?$A4yN4k)F2?s@}C1mGnvI6Mm>T;!HPT$Kju0QKG
z!J$Fg;xU85(H^}xkJL^wTp4P6+mLM=O^h9|0>%T)&HQ+<7taFIhr%(oDGn#27ZnVA
zjQve@5QIp-E%B;yICVUckV!++1WK7|%*i~25kzFY;VP_9?vk+m`H&35g?$hPB^zYi
z0LA6`XE1K7A<H^^v~me`bm6t0zCBCRB%(5DW`#kxX~N<;$3X$@gx^Dnz&cl{acluE
zh)VJ+Dp4gl2Guv9Vmw>noCw6_8YB2ftj%)U@NY`8|L70IiVN=k_3PIk_ussAtN3y%
zpO8?$uNMuE@XKY5lP6C~?asCR<i)8&Y}v4}65~6Wizke!O64CJkE+R$o>}yI6jh5X
z%gx?c=9faE7lfA6h3@%?5m7{ULF?zFxdg>(e`~a6o9Diso*n`-L7;~dPZ%0qiIWVH
zp%z$b(h!c`rf1y$0yS$BUx3{tyghaRY3;)hji;CzLfAnJ@foDsy|Zop3~x{vM)whc
z0D^8E^q>AFKQu7GC`jCFWEfjz6=t!L?m5^3g{`ctK#Q2bFG6=WprOYm1UqpD0u2)9
zd%cMEA3sQkAu@$ll778YQ$JFJ+HY9{{zT%pg!Rb%UlyPZn>8LvxEeglq{S86Fp7i`
zjG6ihOE{UufNf;j{WY}gLW{?uTj$T8=vg#D2~3YbkSh9ql~A_y2!wiCrE<CbE+B0D
zl8g@}X7idDwRhQ8_;SL-I*)aS!g<&SD~umE*w`y%U>U~V5i1n24Ph4we<H1Hi1no1
zgXEKh1VIu$9daT5C2AnD{Prj#GzvSBIfy_jm7V)M7Um?f(FPEU6(i@v6x;+p*zH}H
zQ*Jv$h<qy5G>PG>SI~&j3b6C_&}4a_cpd$s<aEbVUv7A9KV}cY7?8%Thn_oM#D`0n
zjft?!=z>B;y{`@4GO?*iziSF~iz3|~%mnDHczCbyX7H`IyK<bH;KfVwe+@RompdMD
zrM7ipLIkfO@;qJz8-0pk>3uJ+Om01t#`t>*8W=9ZyjTO$;1#G&AzCfEZ~{L8a~I*)
z<T>#alWa1&9V9ThsL?EpF`QFboDwQcNdS`~ASn15knXeJu#6r`1`J;isoF<vd4s4J
z4g2Tx>@4Y_DJd&+uyjOV0yn@4D-;><i(Ode23`tcd#SB3v=<s35Sm-Gb)ujm+p+`p
zifTBB2-E#fQ(>7K<QQM>`hJHlePU)mZ2la6D$+&ECn3?qa|h*<9gS{>K{GU+B-{Kr
zkHrOWIU2Cq;#;HeC#S<7A%sMs5#3j3-`bCgZ(jrM*Ax#mbIjGs5eG~LwU`Pq!!6F0
zFJ6JW!MQ8Yk(&l1trqYBB#JP|u7sHe%hkvpxM*264qAgmCvpP0$uJm^?H=j+o4~5W
zGC=yNg7$&JCu1fKLeHnE<GosF5W%VVJpmL>b28!wksm(s(#~&CAFrU+7xqF>&VDEg
z5+A}rpfoxH^a+0zA>em#ZbGc?#Up0V*(c3*6nxrf0|4j@(=l|CfoQ2s01k!?gTv?}
zZ9`x+wJ<mcWlT%O^x#i@G8YJv2v=@%l5voeEZhXb0?!L!dUhj~AFO!Qu%nG34VnVp
z2wxy&4)OTnW=P6dnEE6w)<yny95d5_4Dn(^+nUMCpe`d(K*ga+lO6%15qAGMdXlSm
zZ||Kf%S#|cy&wg2y9-b&prbzAeJUscv#jBX`Czx5bR&;J{on_&fg+!OXnL=HRtRZ&
zMJdK4<#>)2Ne5*QMiLg;u~JMA!Nc4t0jL^HSOV;$j|SfCE?fT@M^w5W_(CaUWY6PK
z==~xS7s0xDE&<gy^d=Uh@9P>>>P_-gwZ#81zOQJ)FjHjNfj|(PAQ)zYf*oOtS+QnK
zEvARA{4fP#85vmx?I53o9x+o{B)8yLC?S*&HWk;MZTXC=AB&crry>9Iv$j`NR#rzT
pZ-WNf?fVfLQb}>K8r+&=9=XSyN7meHBZK)VnvBZHq~mA*`foAK`x*cM

literal 0
HcmV?d00001

diff --git a/docs/tutorial.md b/docs/tutorial.md
index 4ff84ee..c1553a6 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -100,67 +100,15 @@ std::vector<float> image_data = reorder_to_chw_and_subtract_imagenet_average(ima
 ## Setup model
 ONNX model has some named variables. To build model, we have to set names of input variables and output variables.
 
-We can checks them with `tool/menoh_onnx_viewer`. At `menoh/build`:
+We can checks them with [Netron](https://github.com/lutzroeder/Netron):
 
 ```
-tool/menoh_onnx_viewer ../data/VGG16.onnx
+netron ../data/VGG16.onnx
 ```
 
-That emits:
+Then you can see the content by accessing *localhost:8080* with browser like below.
 
-```
-ONNX version is 1
-domain is 
-model version is 0
-producer name is Chainer
-producer version is 3.1.0
-parameter list
-name: /conv5_3/b dims: 512  values: min_value: -0.500367 max_value: 9.43155 
-name: /conv5_3/W dims: 512 512 3 3  values: min_value: -0.0928848 max_value: 0.286997 
-
-...
-
-node list
-node num is 40
-0:Conv
-	input0: 140326425860192
-	input1: /conv1_1/W
-	input2: /conv1_1/b
-	output0: 140326201104648
-	attribute0: dilations ints: 1 1 
-	attribute1: kernel_shape ints: 3 3 
-	attribute2: pads ints: 1 1 1 1 
-	attribute3: strides ints: 1 1 
-1:Relu
-	input0: 140326201104648
-	output0: 140326201105432
-2:Conv
-	input0: 140326201105432
-	input1: /conv1_2/W
-	input2: /conv1_2/b
-	output0: 140326201105544
-	attribute0: dilations ints: 1 1 
-	attribute1: kernel_shape ints: 3 3 
-	attribute2: pads ints: 1 1 1 1 
-	attribute3: strides ints: 1 1 
-
-...
-
-32:FC
-	input0: 140326200777360
-	input1: /fc6/W
-	input2: /fc6/b
-	output0: 140326200777584
-	attribute0: axis int: 1
-	attribute1: axis_w int: 1
-
-...
-
-39:Softmax
-	input0: 140326200803456
-	output0: 140326200803680
-	attribute0: axis int: 1
-```
+\image html vgg16_view.png
 
 VGG16 has one input and one output. So now we can check that the input name is *140326425860192* (input of 0:Conv) and the output name is *140326200803680* (output of 39:Softmax).
 
diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt
deleted file mode 100644
index 250926e..0000000
--- a/tool/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-add_executable(onnx_viewer onnx_viewer.cpp)
-target_link_libraries(onnx_viewer menoh)
-set_target_properties(onnx_viewer PROPERTIES OUTPUT_NAME "menoh_onnx_viewer")
-install(TARGETS onnx_viewer RUNTIME DESTINATION bin)
diff --git a/tool/onnx_viewer.cpp b/tool/onnx_viewer.cpp
deleted file mode 100644
index d27a192..0000000
--- a/tool/onnx_viewer.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "../external/cmdline.h"
-#include <external/onnx/onnx/onnx.pb.h>
-
-namespace menoh_impl {
-    onnx::ModelProto load_onnx_model_proto(std::string const& filename);
-}
-
-int main(int argc, char** argv) {
-    if(argc == 1) {
-        std::cout << "please set ONNX file path" << std::endl;
-        return 0;
-    }
-    auto onnx_model_path = argv[1];
-    auto onnx_model = menoh_impl::load_onnx_model_proto(onnx_model_path);
-
-    std::cout << "ONNX version is " << onnx_model.ir_version() << std::endl;
-    std::cout << "opset_import_size is " << onnx_model.opset_import_size() << std::endl;
-    for(int i = 0; i < onnx_model.opset_import_size(); ++i) {
-        std::cout << onnx_model.opset_import(i).version() << " ";
-    }
-    std::cout << "\n";
-    std::cout << "domain is " << onnx_model.domain() << std::endl;
-    std::cout << "model version is " << onnx_model.model_version() << std::endl;
-    std::cout << "producer name is " << onnx_model.producer_name() << std::endl;
-    std::cout << "producer version is " << onnx_model.producer_version() << std::endl;
-
-    auto const& graph = onnx_model.graph();
-
-    std::cout << "parameter list\n";
-    for(auto const& tensor : graph.initializer()) {
-        std::cout << "name: " << tensor.name();
-        std::cout << " dtype: " << TensorProto_DataType_Name(tensor.data_type());
-        std::cout << " dims: ";
-        for(int j = 0; j < tensor.dims_size(); ++j) {
-            std::cout << tensor.dims(j) << " ";
-        }
-        if(tensor.has_raw_data() && tensor.data_type() == onnx::TensorProto_DataType_FLOAT) {
-            std::cout << " values: ";
-            auto f = static_cast<float const*>(static_cast<void const*>(tensor.raw_data().c_str()));
-            std::vector<float> floats;
-            std::copy(f, f+tensor.raw_data().length()/sizeof(float), std::back_inserter(floats));
-            auto max_value = *std::max_element(floats.begin(), floats.end());
-            auto min_value = *std::min_element(floats.begin(), floats.end());
-            std::cout << "min_value: " << min_value << " ";
-            std::cout << "max_value: " << max_value << " ";
-        }
-        std::cout << "\n";
-    }
-    std::cout << "\n";
-
-    std::cout << "node list\n";
-    std::cout << "node num is " << graph.node_size() << std::endl;
-    for(int i = 0; i < graph.node_size(); ++i) {
-        auto node = graph.node(i);
-        std::cout << i << ":" << node.op_type() << std::endl;
-        for(int j = 0; j < node.input_size(); ++j) {
-            std::cout << "\tinput" << j << ": " << node.input(j) << std::endl;
-        }
-        for(int j = 0; j < node.output_size(); ++j) {
-            std::cout << "\toutput" << j << ": " << node.output(j) << std::endl;
-        }
-        for(int j = 0; j < node.attribute_size(); ++j) {
-            auto attribute = node.attribute(j);
-            std::cout << "\tattribute" << j << ": " << attribute.name() << " ";
-                      //<< "type: " << AttributeProto_AttributeType_Name(attribute.type()) << " ";
-            if(attribute.has_f()) {
-                std::cout << "float"
-                          << ": " << attribute.f() << std::endl;
-            }
-            if(attribute.has_i()) {
-                std::cout << "int"
-                          << ": " << attribute.i() << std::endl;
-            }
-            if(attribute.has_s()) {
-                std::cout << "string"
-                          << ": " << attribute.s() << std::endl;
-            }
-            if(attribute.floats_size()) {
-                std::cout << "floats: ";
-                for(int k = 0; k < attribute.floats_size(); ++k) {
-                    std::cout << attribute.floats(k) << " ";
-                }
-                std::cout << "\n";
-            }
-            if(attribute.ints_size()) {
-                std::cout << "ints: ";
-                for(int k = 0; k < attribute.ints_size(); ++k) {
-                    std::cout << attribute.ints(k) << " ";
-                }
-                std::cout << "\n";
-            }
-            if(attribute.strings_size()) {
-                std::cout << "strings: ";
-                for(int k = 0; k < attribute.strings_size(); ++k) {
-                    std::cout << attribute.strings(k) << " ";
-                }
-                std::cout << "\n";
-            }
-            /* TODO
-            if (attribute.tensors_size()) {
-                std::cout << "\t\ttensors";
-            }
-            */
-        }
-    }
-}

From f4a3a07657693ecd72943a7e528de77243259d46 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 30 Aug 2018 15:57:47 +0900
Subject: [PATCH 037/321] made a fix based on the review comments

---
 BUILDING.md               | 12 +++---
 benchmark/CMakeLists.txt  | 10 -----
 cmake/SetupProtobuf.cmake | 84 ++++++++++++++++++++-------------------
 menoh/CMakeLists.txt      |  4 +-
 test/CMakeLists.txt       | 10 -----
 5 files changed, 52 insertions(+), 68 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index b6d379e..19cd38f 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -4,8 +4,8 @@
 To build Menoh, you require the following toolchains:
 
 Unix:
-- CMake (3.1 or later)
-- GCC (4.9 or later)
+- CMake 3.1 or later
+- GCC 4.9 or later
 
 macOS (OSX):
 - TODO
@@ -22,7 +22,7 @@ You also need to install the dependent libraries on your system:
 
 You can install `protobuf` through the package manager instead of building it yourself. `mkl-dnn` package, unfortunatelly, is not available in many environments at the moment (except for `brew` in macOS).
 
-### on Debian/Ubuntu
+### Debian/Ubuntu
 ```
 apt-get install gcc g++ cmake-data cmake libopencv-dev libprotobuf-dev protobuf-compiler
 
@@ -69,16 +69,16 @@ python retrieve_data.py
 ```
 
 #### Static linking
-Menoh depends on several other libraries like `protobuf`. There is a chance to fail if the dependent libraries installed on the target system are not compatible with the built Menoh binary.
+Menoh depends on several other libraries like `protobuf`. In Unix like systems, there is a chance to fail if you take the binary you built to other system because sometimes the dependent libraries installed on the system are not compatible with it.
 
-To improve the portability, you can statically link Menoh with the dependent libraries. There is the following options for `cmake` command:
+To improve the portability, you can statically link Menoh with its dependencies. There is the following options for `cmake` command:
 
 - `LINK_STATIC_LIBGCC` for `libgcc`
 - `LINK_STATIC_LIBSTDCXX` for `libstdc++`
 - `LINK_STATIC_LIBPROTOBUF` for `libprotobuf`
 - `LINK_STATIC_MKLDNN` for `libmkldnn` (NOT supported in this version)
 
-`LINK_STATIC_LIBPROTOBUF` and `LINK_STATIC_MKLDNN` options does not require to the libraries installed in your system because it builds static libraries from the source.
+If you use `LINK_STATIC_LIBPROTOBUF` and `LINK_STATIC_MKLDNN`, you don't need to install the libraries on your system because they build static library from the source.
 
 All options are disabled by default, and you can turn them on as below:
 
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 1003f77..2d8d19e 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,12 +1,2 @@
-option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
-
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
 target_link_libraries(vgg16_benchmark menoh)
-
-if(NOT LINK_STATIC_LIBPROTOBUF)
-    if(DEFINED PROTOBUF_LIBRARIES)
-        target_link_libraries(vgg16_benchmark ${PROTOBUF_LIBRARIES})
-    else()
-        message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
-    endif()
-endif()
diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 0de527f..a0c8faf 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -1,48 +1,52 @@
 set(PROTOBUF_VERSION "2.6.1")
 
-if(UNIX AND LINK_STATIC_LIBPROTOBUF)
+if(LINK_STATIC_LIBPROTOBUF)
     # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
     # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
-    # build it ourselves.
-
-    set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
-    set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
-    set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
-
-    # Requires `-fPIC` for linking with a shared library
-    set(PROTOBUF_CFLAGS -fPIC)
-    set(PROTOBUF_CXXFLAGS -fPIC)
-    if(USE_OLD_GLIBCXX_ABI)
-        set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
+    # build it by ourselves.
+
+    if(UNIX)
+        set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
+        set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
+        set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
+
+        # Requires `-fPIC` for linking with a shared library
+        set(PROTOBUF_CFLAGS -fPIC)
+        set(PROTOBUF_CXXFLAGS -fPIC)
+        if(USE_OLD_GLIBCXX_ABI)
+            set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
+        endif()
+
+        ExternalProject_Add(Protobuf
+            PREFIX ${PROTOBUF_DIR}
+            URL ${PROTOBUF_URL}
+            URL_HASH ${PROTOBUF_HASH}
+            DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
+            BUILD_IN_SOURCE 1
+            CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
+            BUILD_COMMAND make
+            INSTALL_COMMAND make install
+        )
+
+        set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
+        set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
+
+        # Mimic the behavior of `FindProtobuf` module
+        # Use the old variable names to ensure backward compatibility
+        set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
+        set(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY_STATIC}) # use the static library
+        set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
+        set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+        set(PROTOBUF_FOUND TRUE)
+
+        add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
+        # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
+        # not installed during executing `cmake`
+        set_target_properties(protobuf::libprotobuf PROPERTIES
+            IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
+    else()
+        message(FATAL_ERROR "LINK_STATIC_LIBPROTOBUF is supported only in UNIX-like environments")
     endif()
-
-    ExternalProject_Add(Protobuf
-        PREFIX ${PROTOBUF_DIR}
-        URL ${PROTOBUF_URL}
-        URL_HASH ${PROTOBUF_HASH}
-        DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
-        BUILD_IN_SOURCE 1
-        CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
-        BUILD_COMMAND make
-        INSTALL_COMMAND make install
-    )
-
-    set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
-    set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
-
-    # Mimic the behavior of `FindProtobuf` module
-    # Use the old variable names to ensure backward compatibility
-    set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-    set(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY_STATIC}) # use the static library
-    set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
-    set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
-    set(PROTOBUF_FOUND TRUE)
-
-    add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
-    # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
-    # not installed during executing `cmake`
-    set_target_properties(protobuf::libprotobuf PROPERTIES
-        IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
 else()
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 4b4b06b..8dd1f4c 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -23,8 +23,8 @@ add_library(menoh_objlib OBJECT ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
 add_library(menoh SHARED $<TARGET_OBJECTS:menoh_objlib>)
-if(NOT APPLE)
-    # Remove private symbols
+if(NOT APPLE AND NOT MSVC)
+    # Remove private symbols (Note: it works in MINGW but not in MSVC)
     set_property(
         TARGET menoh APPEND_STRING PROPERTY
             LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ba5a840..d27878b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,5 +1,3 @@
-option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
-
 add_executable(menoh_test
     np_io.cpp
     array.cpp
@@ -15,12 +13,4 @@ add_executable(menoh_test
 )
 target_link_libraries(menoh_test gtest_main menoh_test_target)
 
-if(NOT LINK_STATIC_LIBPROTOBUF)
-    if(DEFINED PROTOBUF_LIBRARIES)
-        target_link_libraries(menoh_test ${PROTOBUF_LIBRARIES})
-    else()
-        message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
-    endif()
-endif()
-
 add_test(NAME menoh_test COMMAND menoh_test)

From 88b6b77ac4e7f3008f5f48546f451d2d61ca0aac Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 30 Aug 2018 17:40:02 +0900
Subject: [PATCH 038/321] update comment in vgg16 example

---
 example/vgg16_example_in_cpp.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index f6f28e3..2c57b79 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -80,7 +80,8 @@ int main(int argc, char** argv) {
     std::cout << "vgg16 example" << std::endl;
 
     // Aliases to onnx's node input and output tensor name
-    // Please use `/tool/onnx_viewer`
+    // Please use [Netron](https://github.com/lutzroeder/Netron)
+    // See Menoh tutorial for more information.
     const std::string conv1_1_in_name = "140326425860192";
     const std::string fc6_out_name = "140326200777584";
     const std::string softmax_out_name = "140326200803680";

From 92a7613b31c54394cfca1ec4490f0f903056d014 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 30 Aug 2018 18:46:28 +0900
Subject: [PATCH 039/321] remove global `onnx::*` symbols from `libmenoh`

---
 menoh/menoh.map | 1 -
 1 file changed, 1 deletion(-)

diff --git a/menoh/menoh.map b/menoh/menoh.map
index acf7183..4a26cbf 100644
--- a/menoh/menoh.map
+++ b/menoh/menoh.map
@@ -8,7 +8,6 @@
       menoh_impl::*;
       typeinfo*for?menoh_impl::*;
       vtable*for?menoh_impl::*;
-      onnx::*;
     };
 
   local:

From 63633ed0014728127ca1fded4f3460127d6ce080 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 30 Aug 2018 19:01:37 +0900
Subject: [PATCH 040/321] fix wrong channel order

---
 README.md                              | 13 +++++++------
 docs/tutorial.md                       |  4 ++--
 example/general_cnn_example_in_cpp.cpp |  2 +-
 example/vgg16_example_in_cpp.cpp       |  2 +-
 4 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 5d64967..c68e94f 100644
--- a/README.md
+++ b/README.md
@@ -77,13 +77,14 @@ Result is here
 
 ```
 vgg16 example
--18.7495 -28.337 -17.3352 8.3209 -1.16396 -0.453321 -22.5098 -25.0265 -18.7067 11.1063 
+-18.1883 -26.5022 -20.0474 13.5325 -0.107129 0.76102 -23.9688 -24.218 -21.6314 14.2164 
 top 5 categories are
-8 0.876184 n01514859 hen
-7 0.111645 n01514668 cock
-86 0.00435782 n01807496 partridge
-82 0.00136959 n01797886 ruffed grouse, partridge, Bonasa umbellus
-97 0.00133743 n01847000 drake
+8 0.885836 n01514859 hen
+7 0.104591 n01514668 cock
+86 0.00313584 n01807496 partridge
+82 0.000934658 n01797886 ruffed grouse, partridge, Bonasa umbellus
+97 0.000839487 n01847000 drake
+
 ```
 
 Please give `--help` option for details
diff --git a/docs/tutorial.md b/docs/tutorial.md
index 294ade4..4e019e1 100644
--- a/docs/tutorial.md
+++ b/docs/tutorial.md
@@ -23,11 +23,11 @@ is not always sized 224x224. So we use `resize()` function in OpenCV :
 cv::resize(image_mat, image_mat, cv::Size(224, 224));
 ```
 
-VGG16 supposes that the input image is subtracted the average values of imagenet.
+VGG16 supposes that the input image is subtracted the mean values of images included in imagenet.
 
 ```cpp
 image_mat.convertTo(image_mat, CV_32FC3); // change data type to float
-image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+image_mat -= cv::Scalar(103.939, 116.779, 123.68); // subtract BGR mean
 ```
 
 Menoh takes images as NCHW format(N x Channels x Height x Width), but `Mat` of OpenCV holds image as HWC format(Height x Width x Channels).
diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index ac2636c..2148582 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -97,7 +97,7 @@ int main(int argc, char** argv) {
     cv::resize(image_mat, image_mat, cv::Size(width, height));
     image_mat.convertTo(image_mat, CV_32FC3);
     if(is_subtract_imagenet_average) {
-        image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+        image_mat -= cv::Scalar(103.939, 116.779, 123.68); // subtract BGR mean
     }
     image_mat /= reverse_scale;
     auto image_data = reorder_to_chw(image_mat);
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index b928759..426015e 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -98,7 +98,7 @@ int main(int argc, char** argv) {
     // Preprocess
     cv::resize(image_mat, image_mat, cv::Size(width, height));
     image_mat.convertTo(image_mat, CV_32FC3);
-    image_mat -= cv::Scalar(123.68, 116.779, 103.939);
+    image_mat -= cv::Scalar(103.939, 116.779, 123.68); // subtract BGR mean
     auto image_data = reorder_to_chw(image_mat);
 
     // Load ONNX model data

From 39c2dd8b0c27bd43825a45cc8f64a95fd8347f2b Mon Sep 17 00:00:00 2001
From: swd <swda.durl@gmail.com>
Date: Thu, 30 Aug 2018 20:31:29 +0900
Subject: [PATCH 041/321] For Windows

---
 BUILDING.md | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index 19cd38f..5f08083 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -11,7 +11,8 @@ macOS (OSX):
 - TODO
 
 Windows:
-- TODO
+- git
+- Visual Studio 2015
 
 You also need to install the dependent libraries on your system:
 
@@ -41,7 +42,8 @@ brew install protobuf mkl-dnn
 ```
 
 ### Windows
-TODO
+
+None
 
 ## Building
 
@@ -105,4 +107,46 @@ cmake -DUSE_OLD_GLIBCXX_ABI=ON -DLINK_STATIC_LIBPROTOBUF=ON ..
 TODO
 
 ### Windows
-TODO
+
+Please specify your directory into (CMake_Install_Dir).
+
+#### mkl-dnn
+
+```
+git clone https://github.com/intel/mkl-dnn.git
+cd mkl-dnn/scripts
+.\prepare_mkl.bat
+cd ..
+mdir build
+cd build
+cmake .. -G "Visual Studio 14 Win64"  -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
+cmake --build . --config Debug --target install
+cmake --build . --config Release --target install
+cd ../..
+```
+
+#### protobuf
+
+Download and unzip https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.zip
+
+```
+cd protobuf-3.6.1/cmake
+mdir build
+cd build
+cmake .. -G "Visual Studio 14" -A x64 -Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
+cmake --build . --config Debug --target install
+cmake --build . --config Release --target install
+cd ../../..
+```
+
+#### menoh
+
+```
+git clone https://github.com/pfnet-research/menoh.git
+cd menoh
+mdir build
+cd build
+cmake .. -G "Visual Studio 14 Win64" -DCMAKE_PREFIX_PATH=CMake_Install_Dir) -DCMAKE_INSTALL_PREFIX=CMake_Install_Dir) -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DENABLE_TOOL=OFF
+cmake --build . --config Debug --target install
+cmake --build . --config Release --target install
+```

From 4a453f320857a2635d73dc57cee75823904151b5 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 31 Aug 2018 11:00:01 +0900
Subject: [PATCH 042/321] update notification_email for Coverity Scan

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 844e662..40bab41 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,7 +22,7 @@ matrix:
                   project:
                       name: "pfnet-research/menoh"
                       description: "Menoh: DNN inference library"
-                  notification_email: sakai@preferred.jp
+                  notification_email: menoh-oss@preferred.jp
                   build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan

From a14ba333a0a7556d2f78b49a9cf102eacb7a18e0 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 31 Aug 2018 11:52:37 +0900
Subject: [PATCH 043/321] Update BUILDING.md

---
 BUILDING.md | 74 ++++++++++++++++++++++++-----------------------------
 1 file changed, 34 insertions(+), 40 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index 5f08083..9b692a3 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -1,4 +1,5 @@
 # Building Menoh
+You need to install [prerequisites](#prerequisites) for your platform before [building](#building) Menoh.
 
 ## Prerequisites
 To build Menoh, you require the following toolchains:
@@ -11,17 +12,16 @@ macOS (OSX):
 - TODO
 
 Windows:
-- git
 - Visual Studio 2015
 
 You also need to install the dependent libraries on your system:
 
-- [Protocol Buffers](https://developers.google.com/protocol-buffers/) 2.6.1 or later
-    - Building instructions are [here](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md)
-- [MKL-DNN](https://github.com/intel/mkl-dnn) 0.14 or later (for `mkldnn` backend)
-    - Building instructions are [here](https://github.com/intel/mkl-dnn/blob/master/README.md#installation)
+- [Protocol Buffers](https://developers.google.com/protocol-buffers/) 2.6.1 or later (building instructions are [here](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md))
+- [MKL-DNN](https://github.com/intel/mkl-dnn) 0.14 or later (for `mkldnn` backend) (building instructions are [here](https://github.com/intel/mkl-dnn/blob/master/README.md#installation))
 
-You can install `protobuf` through the package manager instead of building it yourself. `mkl-dnn` package, unfortunatelly, is not available in many environments at the moment (except for `brew` in macOS).
+`protobuf` can be installed through most package managers instead of building it yourself. `mkl-dnn` package, unfortunatelly, is not available in many environments at the moment (except for `brew` in macOS).
+
+Note that you can use ProtoBuf either version 2 or 3, but, for example, if you build Menoh with `protoc` ver 3 you should use the binary with runtime ver 3.
 
 ### Debian/Ubuntu
 ```
@@ -42,8 +42,34 @@ brew install protobuf mkl-dnn
 ```
 
 ### Windows
+Please replace `(CMake_Install_Dir)` in the following with your working directory.
+
+#### ProtoBuf
+Download and unzip https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.zip
 
-None
+```
+cd protobuf-3.6.1/cmake
+mdir build
+cd build
+cmake .. -G "Visual Studio 14" -A x64 -Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
+cmake --build . --config Debug --target install
+cmake --build . --config Release --target install
+cd ../../..
+```
+
+#### MKL-DNN
+```
+git clone https://github.com/intel/mkl-dnn.git
+cd mkl-dnn/scripts
+.\prepare_mkl.bat
+cd ..
+mdir build
+cd build
+cmake .. -G "Visual Studio 14 Win64"  -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
+cmake --build . --config Debug --target install
+cmake --build . --config Release --target install
+cd ../..
+```
 
 ## Building
 
@@ -107,39 +133,7 @@ cmake -DUSE_OLD_GLIBCXX_ABI=ON -DLINK_STATIC_LIBPROTOBUF=ON ..
 TODO
 
 ### Windows
-
-Please specify your directory into (CMake_Install_Dir).
-
-#### mkl-dnn
-
-```
-git clone https://github.com/intel/mkl-dnn.git
-cd mkl-dnn/scripts
-.\prepare_mkl.bat
-cd ..
-mdir build
-cd build
-cmake .. -G "Visual Studio 14 Win64"  -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
-cmake --build . --config Debug --target install
-cmake --build . --config Release --target install
-cd ../..
-```
-
-#### protobuf
-
-Download and unzip https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.zip
-
-```
-cd protobuf-3.6.1/cmake
-mdir build
-cd build
-cmake .. -G "Visual Studio 14" -A x64 -Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
-cmake --build . --config Debug --target install
-cmake --build . --config Release --target install
-cd ../../..
-```
-
-#### menoh
+Please replace `(CMake_Install_Dir)` in the following with your working directory.
 
 ```
 git clone https://github.com/pfnet-research/menoh.git

From ea58902ea1086bfab1884e51a390f259a9207106 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 31 Aug 2018 17:35:06 +0900
Subject: [PATCH 044/321] run `protoc` for ONNX in build time

---
 CMakeLists.txt              |  9 +--------
 cmake/GenerateOnnxSrc.cmake | 25 +++++++++++++++++++++++++
 menoh/CMakeLists.txt        | 17 +++++++++++------
 3 files changed, 37 insertions(+), 14 deletions(-)
 create mode 100644 cmake/GenerateOnnxSrc.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed48197..f585d18 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,14 +56,7 @@ include(ExternalProject)
 include(SetupProtobuf)
 
 # Generate source codes from ONNX protobuf schema
-set(ONNX_DIR ${EXTERNAL_DIR}/onnx)
-execute_process(COMMAND git submodule update --init -- ${ONNX_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-execute_process(COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} -I=${ONNX_DIR} --cpp_out=${ONNX_DIR} ${ONNX_DIR}/onnx/onnx.proto WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-
-set(ONNX_PROTO_HEADER ${ONNX_DIR}/onnx/onnx.pb.h)
-set(ONNX_PROTO_SRC ${ONNX_DIR}/onnx/onnx.pb.cc)
-
-include_directories(${ONNX_DIR}) # for ONNX_PROTO_HEADER
+include(GenerateOnnxSrc)
 
 # Setup MKLDNN
 find_package(MKLDNN "0.14")
diff --git a/cmake/GenerateOnnxSrc.cmake b/cmake/GenerateOnnxSrc.cmake
new file mode 100644
index 0000000..0c2d8b5
--- /dev/null
+++ b/cmake/GenerateOnnxSrc.cmake
@@ -0,0 +1,25 @@
+set(ONNX_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/onnx)
+
+if(NOT EXISTS "${ONNX_OUTPUT_DIR}")
+    file(MAKE_DIRECTORY "${ONNX_OUTPUT_DIR}")
+endif()
+
+set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
+execute_process(COMMAND git submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
+set(ONNX_PROTO_HEADER ${ONNX_OUTPUT_DIR}/onnx/onnx.pb.h)
+set(ONNX_PROTO_SRC ${ONNX_OUTPUT_DIR}/onnx/onnx.pb.cc)
+
+set(ONNX_GENERATED_OUTPUTS ${ONNX_PROTO_HEADER} ${ONNX_PROTO_SRC})
+
+add_custom_target(gen_onnx_outputs DEPENDS ${ONNX_GENERATED_OUTPUTS})
+add_custom_command(
+    OUTPUT ${ONNX_GENERATED_OUTPUTS}
+    COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
+    ARGS -I ${ONNX_SRC_DIR} --cpp_out . ${ONNX_SRC_DIR}/onnx/onnx.proto
+    DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} ${ONNX_SRC_DIR}/onnx/onnx.proto
+    COMMENT "Generating ONNX source files"
+    WORKING_DIRECTORY ${ONNX_OUTPUT_DIR}
+    VERBATIM)
+
+include_directories(${ONNX_OUTPUT_DIR}) # for ONNX_PROTO_HEADER
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 8dd1f4c..9bd995b 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -19,9 +19,17 @@ endif()
 
 file(GLOB_RECURSE SOURCES "." "*.cpp")
 
-add_library(menoh_objlib OBJECT ${SOURCES} ${ONNX_PROTO_SRC} ${ONNX_PROTO_HEADER})
+# Create a object library for generating shared library
+add_library(menoh_objlib OBJECT ${SOURCES})
+
+add_dependencies(menoh_objlib gen_onnx_outputs)
+target_sources(menoh_objlib PRIVATE ${ONNX_PROTO_SRC})
+
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
+include(ConfigureMenoh)
+
+# menoh
 add_library(menoh SHARED $<TARGET_OBJECTS:menoh_objlib>)
 if(NOT APPLE AND NOT MSVC)
     # Remove private symbols (Note: it works in MINGW but not in MSVC)
@@ -29,13 +37,10 @@ if(NOT APPLE AND NOT MSVC)
         TARGET menoh APPEND_STRING PROPERTY
             LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
 endif()
+menoh_link_libraries(menoh PRIVATE)
 
-# Used in test/ subdirectory
+# menoh_test_target: only used in `test` subdirectory
 add_library(menoh_test_target SHARED $<TARGET_OBJECTS:menoh_objlib>)
-
-include(ConfigureMenoh)
-
-menoh_link_libraries(menoh PRIVATE)
 menoh_link_libraries(menoh_test_target PRIVATE)
 
 set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)

From fccd03fc204fb813a9c01e4c675d07f45e5988ba Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 31 Aug 2018 17:50:58 +0900
Subject: [PATCH 045/321] fix location of onnx.pb.h

---
 menoh/onnx.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 0cae032..21d4d19 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -12,7 +12,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 
-#include <external/onnx/onnx/onnx.pb.h>
+#include <onnx/onnx.pb.h>
 
 #include <menoh/array.hpp>
 #include <menoh/dtype.hpp>

From 64667012bd0e39f85784c61b6417338d9f794e8f Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Sun, 2 Sep 2018 12:53:19 +0900
Subject: [PATCH 046/321] travis: add jobs for linking dependent libraries
 statically

---
 .travis.yml | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index 2d23ddf..64b819d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,12 @@
 dist: trusty
 sudo: required
 language: cpp
+addons:
 matrix:
     include:
         - os: osx
+        - os: osx
+          env: STATIC=1
         - os: linux
           addons:
               apt:
@@ -26,6 +29,21 @@ matrix:
                   build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
+        - os: linux
+          env: STATIC=1
+          addons:
+              apt:
+                  sources:
+                      - ubuntu-toolchain-r-test
+                      - sourceline: 'ppa:maarten-fonville/protobuf'
+                  packages:
+                      - gcc-7
+                      - g++-7
+                      - cmake-data
+                      - cmake
+                      - libopencv-dev
+                      - libprotobuf-dev
+                      - protobuf-compiler
 env:
     global:
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
@@ -73,16 +91,28 @@ script:
     #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
     # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
     - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
+    - |
+      if [ -n "$STATIC" ]; then
+        if [ "$TRAVIS_OS_NAME" = "osx" ]; then
+          STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON"
+        else
+          STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON -DLINK_STATIC_LIBSTDCXX=ON -DLINK_STATIC_LIBGCC=ON"
+        fi
+      else
+        STATIC_OPTION=""
+      fi
     - mkdir build
     - cd build
     - |
       if [ "$TRAVIS_OS_NAME" == "osx" ]; then
         cmake -DENABLE_TEST=ON \
+        $STATIC_OPTION \
         ..
       else
         cmake -DENABLE_TEST=ON \
         -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" \
         -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" \
+        $STATIC_OPTION \
         ..
       fi
     - make

From 62cf66f5e89488f6a1fed15953ae659b3b2633a0 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Sun, 2 Sep 2018 14:08:27 +0900
Subject: [PATCH 047/321] travis: stop installing protobuf package when
 unnecessary

---
 .travis.yml | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 64b819d..c4e1309 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -35,15 +35,12 @@ matrix:
               apt:
                   sources:
                       - ubuntu-toolchain-r-test
-                      - sourceline: 'ppa:maarten-fonville/protobuf'
                   packages:
                       - gcc-7
                       - g++-7
                       - cmake-data
                       - cmake
                       - libopencv-dev
-                      - libprotobuf-dev
-                      - protobuf-compiler
 env:
     global:
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
@@ -64,7 +61,8 @@ install:
         brew upgrade python
         export PATH=/usr/local/opt/python/libexec/bin:$PATH
         brew install numpy || true
-        brew install opencv mkl-dnn protobuf
+        brew install opencv mkl-dnn
+        if [ -z "$STATIC" ]; then brew install protobuf; fi
       else
         pyenv local 3.6
       fi

From 8a8c0ef97e01237d902a8124f01705c1a4c9aca6 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Sun, 2 Sep 2018 14:46:40 +0900
Subject: [PATCH 048/321] travis: print shared object dependencies using ldd or
 otool -L

---
 .travis.yml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index c4e1309..1c9c3d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -115,3 +115,9 @@ script:
       fi
     - make
     - ./test/menoh_test
+    - |
+      if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+        otool -L menoh/libmenoh.dylib
+      else
+        ldd menoh/libmenoh.so
+      fi

From f70ff08f18f1ad56e99505d03192dad31f3bb9b6 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 31 Aug 2018 10:55:14 +0900
Subject: [PATCH 049/321] use protobuf 3.6.1 when building with
 LINK_STATIC_LIBPROTOBUF

This is because protobuf-2.6.1 is too old that bundled config.guess
cannot detect MINGW+MSYS2 environment.
---
 cmake/SetupProtobuf.cmake | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index a0c8faf..b33f863 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -6,9 +6,10 @@ if(LINK_STATIC_LIBPROTOBUF)
     # build it by ourselves.
 
     if(UNIX)
-        set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION})
-        set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protobuf-${PROTOBUF_VERSION}.tar.gz")
-        set(PROTOBUF_HASH MD5=f3916ce13b7fcb3072a1fa8cf02b2423)
+        set(PROTOBUF_VERSION_STATIC "3.6.1")
+        set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION_STATIC})
+        set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_STATIC}/protobuf-cpp-${PROTOBUF_VERSION_STATIC}.tar.gz")
+        set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
 
         # Requires `-fPIC` for linking with a shared library
         set(PROTOBUF_CFLAGS -fPIC)

From ad211d2c75e7a02cae54fee071345e0822ed2850 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 29 Aug 2018 18:22:27 +0900
Subject: [PATCH 050/321] enable LINK_STATIC_LIBPROTOBUF on MINGW

---
 cmake/SetupProtobuf.cmake | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index b33f863..5ddaf6e 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -5,7 +5,7 @@ if(LINK_STATIC_LIBPROTOBUF)
     # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
     # build it by ourselves.
 
-    if(UNIX)
+    if(UNIX OR MINGW)
         set(PROTOBUF_VERSION_STATIC "3.6.1")
         set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION_STATIC})
         set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_STATIC}/protobuf-cpp-${PROTOBUF_VERSION_STATIC}.tar.gz")

From 3a76eca9df6d3f6bcd5246fc79f60d8a3b669f5a Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Thu, 30 Aug 2018 10:22:46 +0900
Subject: [PATCH 051/321] appveyor: add a job for building libmenoh that
 statically link dependent libraries

---
 appveyor.yml | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/appveyor.yml b/appveyor.yml
index f8000cb..a999bcb 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,6 +10,8 @@ image:
 environment:
   matrix:
     - TARGET: mingw
+    - TARGET: mingw
+      STATIC: 1
     - TARGET: msvc
 
 install:
@@ -57,7 +59,14 @@ build_script:
 - cd build
 - if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.15-win64\bin;c:\projects\menoh\mkl-dnn-0.15-win64\include;c:\projects\menoh\mkl-dnn-0.15-win64\lib
 - if [%TARGET%]==[mingw] (
-    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
+    if [%STATIC%]==[1] (
+      set STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON -DLINK_STATIC_LIBSTDCXX=ON -DLINK_STATIC_LIBGCC=ON"
+    ) else (
+      set STATIC_OPTION=""
+    )
+  )
+- if [%TARGET%]==[mingw] (
+    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON -DLINK_STATIC_LIBPROTOBUF=ON -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
     make
   ) else (
     cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DENABLE_TOOL=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&

From 47d6df07b4bc5fd5c88db90c221e2718602ec1dd Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 3 Sep 2018 14:45:44 +0900
Subject: [PATCH 052/321] remove `Libs.private`

---
 include/menoh.pc.in | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/menoh.pc.in b/include/menoh.pc.in
index 69e9d4d..f07440f 100644
--- a/include/menoh.pc.in
+++ b/include/menoh.pc.in
@@ -8,5 +8,4 @@ Description: DNN inference library written in C++
 Version: @MENOH_MAJOR_VERSION@.@MENOH_MINOR_VERSION@.@MENOH_PATCH_VERSION@
 
 Libs: -L${libdir} -lmenoh
-Libs.private: @MKLDNN_LIBRARY@ @PROTOBUF_LIBRARY@
 Cflags: -I${includedir}

From dc030d1df88e1d510b83a6fb7f9243f5cd2ccb40 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Sep 2018 13:58:18 +0900
Subject: [PATCH 053/321] travis: add suffix to MKL-DNN installation directory

This is desirable because the cache is invalidated when MKL-DNN is
upgraded.
---
 .travis.yml               | 10 ++++++----
 .travis/install_mkldnn.sh |  6 +++---
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 1c9c3d9..20fa4ee 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,12 +43,14 @@ matrix:
                       - libopencv-dev
 env:
     global:
+        - MKL_DNN_REV: v0.15
+        - MKL_DNN_INSTALL_SUFFIX: -0.15
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
         #   via the "travis encrypt" command using the project repo's public key
         - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
 cache:
     directories:
-        - $HOME/mkl-dnn
+        - $HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}
 before_install:
     - |
       if [ "$TRAVIS_OS_NAME" = "linux" ]; then
@@ -84,7 +86,7 @@ before_script:
       fi
       cmake --version
       make --version
-    - ls -R $HOME/mkl-dnn
+    - ls -R $HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}
 script:
     #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
     # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
@@ -108,8 +110,8 @@ script:
         ..
       else
         cmake -DENABLE_TEST=ON \
-        -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" \
-        -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" \
+        -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/include" \
+        -DMKLDNN_LIBRARY="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib/libmkldnn.so" \
         $STATIC_OPTION \
         ..
       fi
diff --git a/.travis/install_mkldnn.sh b/.travis/install_mkldnn.sh
index 29fa3c9..7750d5f 100644
--- a/.travis/install_mkldnn.sh
+++ b/.travis/install_mkldnn.sh
@@ -1,11 +1,11 @@
-if [ ! -d "$HOME/mkl-dnn/lib" ]; then
+if [ ! -d "$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib" ]; then
     git clone https://github.com/intel/mkl-dnn.git
     cd mkl-dnn
-    git checkout v0.15
+    git checkout $MKL_DNN_REV
     cd scripts && bash ./prepare_mkl.sh && cd ..
     sed -i 's/add_subdirectory(examples)//g' CMakeLists.txt
     sed -i 's/add_subdirectory(tests)//g' CMakeLists.txt
-    mkdir -p build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/mkl-dnn .. && make
+    mkdir -p build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX} .. && make
     make install
     cd ..
 else

From eadb767b8ded543ab2e4e193a9665ee051f36726 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Sep 2018 14:24:36 +0900
Subject: [PATCH 054/321] write MINGW build instruction

---
 BUILDING.md | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/BUILDING.md b/BUILDING.md
index 9b692a3..fbf522f 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -14,6 +14,9 @@ macOS (OSX):
 Windows:
 - Visual Studio 2015
 
+Windows (MINGW):
+- [MSYS2](http://www.msys2.org/)
+
 You also need to install the dependent libraries on your system:
 
 - [Protocol Buffers](https://developers.google.com/protocol-buffers/) 2.6.1 or later (building instructions are [here](https://github.com/protocolbuffers/protobuf/blob/master/src/README.md))
@@ -71,6 +74,33 @@ cmake --build . --config Release --target install
 cd ../..
 ```
 
+### Windows (MINGW)
+```
+pacman -S mingw-w64-x86_64-toolchain
+pacman -S git
+pacman -S mingw-w64-x86_64-cmake
+pacman -S mingw-w64-x86_64-protobuf mingw-w64-x86_64-protobuf-c
+```
+
+#### Installing MKL-DNN from binary package
+```
+curl -omingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
+pacman -S --noconfirm mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
+```
+
+#### Installing MKL-DNN from source
+```
+git clone https://github.com/intel/mkl-dnn.git
+cd mkl-dnn
+cd scripts && ./prepare_mkl.sh && cd ..
+mkdir -p build
+cd build
+MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
+  cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64
+make
+make install
+```
+
 ## Building
 
 ### Unix
@@ -144,3 +174,14 @@ cmake .. -G "Visual Studio 14 Win64" -DCMAKE_PREFIX_PATH=CMake_Install_Dir) -DCM
 cmake --build . --config Debug --target install
 cmake --build . --config Release --target install
 ```
+
+### Windows (MINGW)
+
+```
+git clone https://github.com/pfnet-research/menoh.git
+cd menoh
+mkdir -p build && cd build
+MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
+  cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64
+make
+```

From eb5106193269b7aff9432a437026dde64f886a6c Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Sep 2018 14:32:10 +0900
Subject: [PATCH 055/321] use MKL-DNN 0.16 on Travis-CI and AppVeyor

---
 .travis.yml  |  4 ++--
 appveyor.yml | 10 +++++-----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 20fa4ee..f015ed3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,8 +43,8 @@ matrix:
                       - libopencv-dev
 env:
     global:
-        - MKL_DNN_REV: v0.15
-        - MKL_DNN_INSTALL_SUFFIX: -0.15
+        - MKL_DNN_REV: v0.16
+        - MKL_DNN_INSTALL_SUFFIX: -0.16
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
         #   via the "travis encrypt" command using the project repo's public key
         - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
diff --git a/appveyor.yml b/appveyor.yml
index a999bcb..17cd152 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -26,11 +26,11 @@ install:
 
 - if [%TARGET%]==[mingw] (
     pacman -S --needed --noconfirm mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-opencv mingw-w64-x86_64-protobuf mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python3-numpy mingw-w64-x86_64-hdf5 mingw-w64-x86_64-ca-certificates &&
-    curl -omingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz &&
-    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
+    curl -omingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz &&
+    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz
   ) else (
-    curl -omkl-dnn-0.15-win64.zip -L --insecure https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mkl-dnn-0.15-win64.zip &&
-    7z x mkl-dnn-0.15-win64.zip &&
+    curl -omkl-dnn-0.16-win64.zip -L --insecure https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mkl-dnn-0.16-win64.zip &&
+    7z x mkl-dnn-0.16-win64.zip &&
     call appveyor\install_protoc_msvc.bat
   )
 
@@ -57,7 +57,7 @@ before_build:
 build_script:
 - mkdir build
 - cd build
-- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.15-win64\bin;c:\projects\menoh\mkl-dnn-0.15-win64\include;c:\projects\menoh\mkl-dnn-0.15-win64\lib
+- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.16-win64\bin;c:\projects\menoh\mkl-dnn-0.16-win64\include;c:\projects\menoh\mkl-dnn-0.16-win64\lib
 - if [%TARGET%]==[mingw] (
     if [%STATIC%]==[1] (
       set STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON -DLINK_STATIC_LIBSTDCXX=ON -DLINK_STATIC_LIBGCC=ON"

From 10699699ae5b0b2104ff65e66ca0627ac9c51636 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Sep 2018 14:42:36 +0900
Subject: [PATCH 056/321] write build instruction for macOS

---
 BUILDING.md | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index fbf522f..698309d 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -9,7 +9,8 @@ Unix:
 - GCC 4.9 or later
 
 macOS (OSX):
-- TODO
+- XCode
+- [Homebrew](https://brew.sh/)
 
 Windows:
 - Visual Studio 2015
@@ -160,7 +161,15 @@ cmake -DUSE_OLD_GLIBCXX_ABI=ON -DLINK_STATIC_LIBPROTOBUF=ON ..
 ```
 
 ### macOS (OS X)
-TODO
+
+```
+git clone https://github.com/pfnet-research/menoh.git
+cd menoh
+mkdir -p build && cd build
+cmake ..
+make
+make install
+```
 
 ### Windows
 Please replace `(CMake_Install_Dir)` in the following with your working directory.

From c85cce3062f8a1e1ee52a75cc43c0a4a975fb7c5 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 4 Sep 2018 17:54:01 +0900
Subject: [PATCH 057/321] add make_model_data_from_onnx_data_on_memory()

---
 include/menoh/menoh.h |  4 ++++
 menoh/menoh.cpp       | 19 +++++++++++++--
 menoh/model_data.hpp  |  2 +-
 menoh/node.hpp        | 11 +++++----
 menoh/onnx.cpp        | 55 ++++++++++++++++++++++++++-----------------
 menoh/onnx.hpp        | 18 +++++++-------
 test/common.hpp       | 28 +++++++++++++++++++---
 test/mkldnn.cpp       |  6 +++--
 test/model.cpp        |  2 +-
 test/onnx.cpp         | 51 ++++++++++++++++++++++++++++++++++++---
 10 files changed, 150 insertions(+), 46 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 2fc016f..b61a42b 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -88,6 +88,10 @@ typedef struct menoh_model_data* menoh_model_data_handle;
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx(
   const char* onnx_filename, menoh_model_data_handle* dst_handle);
+/*! \brief make model_data from onnx binary data on memory
+ */
+menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
+  const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle);
 /*! \brief Model_data delete function
  *
  * Users must call to release memory resources allocated for
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 4a80620..c1d0b31 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -36,7 +36,9 @@ namespace menoh_impl {
             auto cont =
               std::copy(prefix, prefix + std::char_traits<char>::length(prefix),
                         arr.begin());
-            std::copy(message, message + (static_cast<size_t>(arr.end() - cont) - 1), cont);
+            std::copy(message,
+                      message + (static_cast<size_t>(arr.end() - cont) - 1),
+                      cont);
 
         } else {
             std::copy(message, message + message_size, arr.data());
@@ -80,9 +82,22 @@ struct menoh_model_data {
 menoh_error_code
 menoh_make_model_data_from_onnx(const char* onnx_filename,
                                 menoh_model_data_handle* dst_handle) {
+    return check_error([&]() {
+        *dst_handle =
+          std::make_unique<menoh_model_data>(
+            menoh_model_data{
+              menoh_impl::make_model_data_from_onnx_file(onnx_filename)})
+            .release();
+        return menoh_error_code_success;
+    });
+}
+menoh_error_code menoh_make_model_data_from_onnx_data_on_memory(
+  const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle) {
     return check_error([&]() {
         *dst_handle = std::make_unique<menoh_model_data>(
-                        menoh_model_data{menoh_impl::load_onnx(onnx_filename)})
+                        menoh_model_data{
+                          menoh_impl::make_model_data_from_onnx_data_on_memory(
+                            onnx_data, size)})
                         .release();
         return menoh_error_code_success;
     });
diff --git a/menoh/model_data.hpp b/menoh/model_data.hpp
index c76b7ca..10ce57e 100644
--- a/menoh/model_data.hpp
+++ b/menoh/model_data.hpp
@@ -2,10 +2,10 @@
 #define MENOH_MODEL_DATA_HPP
 
 #include <algorithm>
+#include <iterator>
 #include <string>
 #include <unordered_set>
 #include <vector>
-#include <iterator>
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp>
diff --git a/menoh/node.hpp b/menoh/node.hpp
index 9c57a80..b676282 100644
--- a/menoh/node.hpp
+++ b/menoh/node.hpp
@@ -20,6 +20,7 @@ namespace menoh_impl {
     };
 
     bool operator==(node const& a, node const& b);
+    inline bool operator!=(node const& a, node const& b) { return !(a == b); }
     bool operator<(node const& a, node const& b);
 
     int optional_attribute_int(node const& n, std::string const& attr_name,
@@ -47,11 +48,11 @@ namespace menoh_impl {
                         std::unordered_map<std::string, std::vector<int>> const&
                           variable_dims_table);
 
-    std::vector<int>
-    calc_2d_output_dims_for_conv_transpose(menoh_impl::node const& node, int output_channel_num,
-                        std::unordered_map<std::string, std::vector<int>> const&
-                          variable_dims_table);
-                          
+    std::vector<int> calc_2d_output_dims_for_conv_transpose(
+      menoh_impl::node const& node, int output_channel_num,
+      std::unordered_map<std::string, std::vector<int>> const&
+        variable_dims_table);
+
 } // namespace menoh_impl
 
 #endif // MENOH_NODE_HPP
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 21d4d19..98e9a62 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -23,24 +23,6 @@
 
 namespace menoh_impl {
 
-    onnx::ModelProto load_onnx_model_proto(std::string const& filename) {
-        namespace gpio = ::google::protobuf::io;
-
-        std::ifstream ifs(filename, std::ios::binary);
-        if(!ifs) {
-            throw invalid_filename(filename);
-        }
-        gpio::IstreamInputStream iis(&ifs);
-        gpio::CodedInputStream cis(&iis);
-        cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
-                               std::numeric_limits<int>::max());
-        onnx::ModelProto onnx_model;
-        if(!onnx_model.ParseFromCodedStream(&cis)) {
-            throw onnx_parse_error(filename);
-        }
-        return onnx_model;
-    }
-
     auto tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt) {
         if(tpdt == onnx::TensorProto_DataType_FLOAT) {
             return dtype_t::float_;
@@ -185,15 +167,14 @@ namespace menoh_impl {
         return node_list;
     }
 
-    model_data load_onnx(std::string const& filename) {
-        auto onnx_model = load_onnx_model_proto(filename);
 
+    model_data make_model_from_onnx(onnx::ModelProto& onnx_model) {
         // onnx opset version check
         if(onnx_model.opset_import_size() != 0) {
             int version = onnx_model.opset_import(0).version();
             if(MENOH_SUPPORTED_ONNX_OPSET_VERSION < version) {
                 throw unsupported_onnx_opset_version(
-                  filename, version, MENOH_SUPPORTED_ONNX_OPSET_VERSION);
+                  version, MENOH_SUPPORTED_ONNX_OPSET_VERSION);
             }
         }
 
@@ -230,6 +211,38 @@ namespace menoh_impl {
         return model_data{node_list, parameter_table};
     }
 
+    model_data make_model_data_from_onnx_file(std::string const& filename) {
+        namespace gpio = ::google::protobuf::io;
+
+        std::ifstream ifs(filename, std::ios::binary);
+        if(!ifs) {
+            throw invalid_filename(filename);
+        }
+        gpio::IstreamInputStream iis(&ifs);
+        gpio::CodedInputStream cis(&iis);
+        cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
+                               std::numeric_limits<int>::max());
+        onnx::ModelProto onnx_model;
+        if(!onnx_model.ParseFromCodedStream(&cis)) {
+            throw onnx_parse_error(filename);
+        }
+        return make_model_from_onnx(onnx_model);
+    }
+
+    model_data make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data, int32_t size) {
+        namespace gpio = ::google::protobuf::io;
+        gpio::ArrayInputStream ais(onnx_data, size);
+        /*
+        ais.SetTotalBytesLimit(std::numeric_limits<int>::max(),
+                               std::numeric_limits<int>::max());
+        */
+        onnx::ModelProto onnx_model;
+        if(!onnx_model.ParseFromZeroCopyStream(&ais)) {
+            throw onnx_parse_error("parse binary onnx data on memory");
+        }
+        return make_model_from_onnx(onnx_model);
+    }
+
     std::vector<std::string>
     extract_model_input_name_list(menoh_impl::model_data const& model_data) {
         auto all_input_name_set =
diff --git a/menoh/onnx.hpp b/menoh/onnx.hpp
index 34c7730..1cadd04 100644
--- a/menoh/onnx.hpp
+++ b/menoh/onnx.hpp
@@ -21,14 +21,13 @@ namespace menoh_impl {
 
     class unsupported_onnx_opset_version : public exception {
     public:
-        unsupported_onnx_opset_version(std::string const& filename,
-                                       int actual_version,
+        unsupported_onnx_opset_version(int actual_version,
                                        int supported_version)
-          : exception(
-              menoh_error_code_unsupported_onnx_opset_version,
-              "menoh unsupported onnx opset version error: " + filename +
-                " has onnx opset version " + std::to_string(actual_version) +
-                " > " + std::to_string(supported_version)) {}
+          : exception(menoh_error_code_unsupported_onnx_opset_version,
+                      "menoh unsupported onnx opset version error: given onnx "
+                      "has opset version " +
+                        std::to_string(actual_version) + " > " +
+                        std::to_string(supported_version)) {}
     };
 
     class invalid_attribute_type : public exception {
@@ -40,7 +39,10 @@ namespace menoh_impl {
                         attribute_type + " for \"" + attribute_name + "\"") {}
     };
 
-    model_data load_onnx(std::string const& filename);
+    model_data make_model_data_from_onnx_file(std::string const& filename);
+    model_data
+    make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data,
+                                             int32_t size);
 
     std::vector<std::string>
     extract_model_input_name_list(menoh_impl::model_data const& model_data);
diff --git a/test/common.hpp b/test/common.hpp
index 8064b4c..31474a2 100644
--- a/test/common.hpp
+++ b/test/common.hpp
@@ -1,6 +1,8 @@
 #ifndef MENOH_TEST_COMMON_HPP
 #define MENOH_TEST_COMMON_HPP
 
+#include <menoh/array.hpp>
+
 namespace menoh_impl {
 
     template <typename Iter1, typename Iter2>
@@ -23,7 +25,8 @@ namespace menoh_impl {
     }
 
     template <typename Iter1, typename Iter2>
-    auto assert_near_list(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, float eps) {
+    auto assert_near_list(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2,
+                          float eps) {
         ASSERT_EQ(std::distance(first1, last1), std::distance(first2, last2))
           << "size is different";
         int i = 0;
@@ -40,8 +43,27 @@ namespace menoh_impl {
     auto assert_near_list(List1 const& list1, List2 const& list2, float eps) {
         using std::begin;
         using std::end;
-        assert_near_list(begin(list1), end(list1), begin(list2), end(list2), eps);
+        assert_near_list(begin(list1), end(list1), begin(list2), end(list2),
+                         eps);
+    }
+
+    inline bool is_near_array(array const& lhs, array const& rhs,
+                              float eps = 1e-4) {
+        assert(lhs.dtype() == dtype_t::float_);
+        assert(rhs.dtype() == dtype_t::float_);
+        if(total_size(lhs) != total_size(rhs)) {
+            return false;
+        }
+        auto size = total_size(lhs);
+        for(auto i = 0; i < size; ++i) {
+            float l = *(static_cast<float*>(lhs.data()) + i);
+            float r = *(static_cast<float*>(rhs.data()) + i);
+            if(!(l - eps < r && r < l + eps)) {
+                return false;
+            }
+        }
+        return true;
     }
-}
+} // namespace menoh_impl
 
 #endif // MENOH_TEST_COMMON_HPP
diff --git a/test/mkldnn.cpp b/test/mkldnn.cpp
index 518ba37..8faf743 100644
--- a/test/mkldnn.cpp
+++ b/test/mkldnn.cpp
@@ -21,7 +21,8 @@ namespace menoh_impl {
 
         TEST_F(MKLDNNTest, run_onnx_model) {
             static mkldnn::engine engine(mkldnn::engine::cpu, 0);
-            auto model_data = load_onnx("../data/VGG16.onnx");
+            auto model_data =
+              make_model_data_from_onnx_file("../data/VGG16.onnx");
             // model_data = trim_redundant_nodes(model_data);
 
             auto input_name_list = extract_model_input_name_list(model_data);
@@ -78,7 +79,8 @@ namespace menoh_impl {
             std::vector<int> input_dims{batch_size, channel_num, height, width};
 
             // Load ONNX model data
-            auto model_data = menoh_impl::load_onnx("../data/VGG16.onnx");
+            auto model_data =
+              menoh_impl::make_model_data_from_onnx_file("../data/VGG16.onnx");
 
             auto cpu_count =
               mkldnn::engine::get_count(mkldnn::engine::kind::cpu);
diff --git a/test/model.cpp b/test/model.cpp
index 3e14981..e610c91 100644
--- a/test/model.cpp
+++ b/test/model.cpp
@@ -28,7 +28,7 @@ namespace menoh_impl {
 
             // Load ONNX model data
             auto model_data = std::make_unique<menoh_impl::model_data>(
-              menoh_impl::load_onnx("../data/VGG16.onnx"));
+              menoh_impl::make_model_data_from_onnx_file("../data/VGG16.onnx"));
 
             // Construct computation primitive list and memories
             auto model = menoh_impl::model(
diff --git a/test/onnx.cpp b/test/onnx.cpp
index f91b153..849cc57 100644
--- a/test/onnx.cpp
+++ b/test/onnx.cpp
@@ -7,13 +7,18 @@
 
 #include <menoh/model_data.hpp>
 #include <menoh/onnx.hpp>
+#include "common.hpp"
 
 namespace menoh_impl {
     namespace {
-        class ONNXTest : public ::testing::Test {};
+        class ONNXTest : public ::testing::Test {
+        public:
+            std::string model_filename{"../data/VGG16.onnx"};
+        };
 
-        TEST_F(ONNXTest, load_onnx_model) {
-            auto model_data = menoh_impl::load_onnx("../data/VGG16.onnx");
+        TEST_F(ONNXTest, make_model_data_from_onnx_file) {
+            auto model_data =
+              menoh_impl::make_model_data_from_onnx_file(model_filename);
             std::cout << "param table" << std::endl;
             std::cout << "node list size: " << model_data.node_list.size()
                       << std::endl;
@@ -46,5 +51,45 @@ namespace menoh_impl {
             }
         }
 
+        TEST_F(ONNXTest, make_model_data_from_onnx_data_on_memory) {
+            std::fstream input(model_filename, std::ios::in | std::ios::binary);
+            std::istreambuf_iterator<char> begin(input);
+            std::istreambuf_iterator<char> end;
+            std::vector<char> buffer(begin, end);
+            auto model_data_from_memory =
+              make_model_data_from_onnx_data_on_memory(
+                static_cast<uint8_t*>(static_cast<void*>(buffer.data())),
+                buffer.size());
+
+            auto model_data_from_file =
+              menoh_impl::make_model_data_from_onnx_file(model_filename);
+
+            ASSERT_EQ(model_data_from_memory.node_list.size(),
+                      model_data_from_file.node_list.size());
+
+            std::sort(model_data_from_memory.node_list.begin(),
+                      model_data_from_memory.node_list.end());
+            std::sort(model_data_from_file.node_list.begin(),
+                      model_data_from_file.node_list.end());
+            ASSERT_EQ(model_data_from_memory.node_list,
+                      model_data_from_file.node_list);
+
+            ASSERT_EQ(
+              model_data_from_memory.parameter_name_and_array_list.size(),
+              model_data_from_file.parameter_name_and_array_list.size());
+
+            for(auto const& p :
+                model_data_from_memory.parameter_name_and_array_list) {
+                auto param_iter = std::find_if(
+                  model_data_from_file.parameter_name_and_array_list.begin(),
+                  model_data_from_file.parameter_name_and_array_list.end(),
+                  [&p](auto e) { return e.first == p.first; });
+                ASSERT_NE(
+                  param_iter,
+                  model_data_from_file.parameter_name_and_array_list.end());
+                ASSERT_TRUE(is_near_array(p.second, param_iter->second));
+            }
+        }
+
     } // namespace
 } // namespace menoh_impl

From ebbc94e913d2c9a892934e1a5a36602da6d453fc Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Tue, 4 Sep 2018 18:05:14 +0900
Subject: [PATCH 058/321] remove comment out

---
 menoh/onnx.cpp | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 98e9a62..174ff5d 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -232,10 +232,6 @@ namespace menoh_impl {
     model_data make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data, int32_t size) {
         namespace gpio = ::google::protobuf::io;
         gpio::ArrayInputStream ais(onnx_data, size);
-        /*
-        ais.SetTotalBytesLimit(std::numeric_limits<int>::max(),
-                               std::numeric_limits<int>::max());
-        */
         onnx::ModelProto onnx_model;
         if(!onnx_model.ParseFromZeroCopyStream(&ais)) {
             throw onnx_parse_error("parse binary onnx data on memory");

From 23363aeb7a3108c4aca9dbfb5ffd9ba1b564ac40 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 4 Sep 2018 18:17:16 +0900
Subject: [PATCH 059/321] little fix

---
 test/onnx.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/test/onnx.cpp b/test/onnx.cpp
index 849cc57..c5a705b 100644
--- a/test/onnx.cpp
+++ b/test/onnx.cpp
@@ -7,6 +7,7 @@
 
 #include <menoh/model_data.hpp>
 #include <menoh/onnx.hpp>
+
 #include "common.hpp"
 
 namespace menoh_impl {
@@ -52,7 +53,7 @@ namespace menoh_impl {
         }
 
         TEST_F(ONNXTest, make_model_data_from_onnx_data_on_memory) {
-            std::fstream input(model_filename, std::ios::in | std::ios::binary);
+            std::ifstream input(model_filename, std::ios::binary);
             std::istreambuf_iterator<char> begin(input);
             std::istreambuf_iterator<char> end;
             std::vector<char> buffer(begin, end);

From 6736eb1955b60e4cd1256077de5e8b9ee33e0733 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 4 Sep 2018 22:39:19 +0900
Subject: [PATCH 060/321] update C++ binding

---
 include/menoh/menoh.hpp | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index ec10b6b..ba637f3 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -118,6 +118,15 @@ namespace menoh {
           menoh_make_model_data_from_onnx(onnx_filename.c_str(), &h));
         return model_data(h);
     }
+    //! Make model_data from onnx binary data on memory
+    inline model_data
+    make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data,
+                                             uint32_t size) {
+        menoh_model_data_handle h;
+        MENOH_CPP_API_ERROR_CHECK(
+          menoh_make_model_data_from_onnx_data_on_memory(onnx_data, size, &h));
+        return model_data(h);
+    }
     /** @} */
 
     /** @addtogroup cpp_vpt Veriable profile table

From 024cb65baf156a5d4b9598465f763780bcecef27 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 13:56:51 +0900
Subject: [PATCH 061/321] remove useless line

---
 menoh/node.hpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/menoh/node.hpp b/menoh/node.hpp
index b676282..4849d6d 100644
--- a/menoh/node.hpp
+++ b/menoh/node.hpp
@@ -20,7 +20,6 @@ namespace menoh_impl {
     };
 
     bool operator==(node const& a, node const& b);
-    inline bool operator!=(node const& a, node const& b) { return !(a == b); }
     bool operator<(node const& a, node const& b);
 
     int optional_attribute_int(node const& n, std::string const& attr_name,

From a34b5d024483c8ebbd852b776586bb083cc099a9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 14:04:29 +0900
Subject: [PATCH 062/321] add comments in test code

---
 test/onnx.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/test/onnx.cpp b/test/onnx.cpp
index c5a705b..798f681 100644
--- a/test/onnx.cpp
+++ b/test/onnx.cpp
@@ -85,9 +85,13 @@ namespace menoh_impl {
                   model_data_from_file.parameter_name_and_array_list.begin(),
                   model_data_from_file.parameter_name_and_array_list.end(),
                   [&p](auto e) { return e.first == p.first; });
+
+                // check if param which has same name is found
                 ASSERT_NE(
                   param_iter,
                   model_data_from_file.parameter_name_and_array_list.end());
+
+                // check if parameter has same values
                 ASSERT_TRUE(is_near_array(p.second, param_iter->second));
             }
         }

From f9f3e2daba9a3e4e3147256eee65c122115af57f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 14:54:04 +0900
Subject: [PATCH 063/321] update version 1.0.3 -> 1.1.0

---
 CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f585d18..a3d3a32 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.1)
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 set(MENOH_MAJOR_VERSION 1)
-set(MENOH_MINOR_VERSION 0)
-set(MENOH_PATCH_VERSION 3)
+set(MENOH_MINOR_VERSION 1)
+set(MENOH_PATCH_VERSION 0)
 
 # Options
 option(BUILD_SHARED_LIBS "Build shared libs" ON)

From aece2d17509b1301614f3d728ee6ba6735547a7f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 15:11:15 +0900
Subject: [PATCH 064/321] add document

---
 include/menoh/menoh.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index b61a42b..aa0dceb 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -89,6 +89,8 @@ typedef struct menoh_model_data* menoh_model_data_handle;
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx(
   const char* onnx_filename, menoh_model_data_handle* dst_handle);
 /*! \brief make model_data from onnx binary data on memory
+ *
+ * \note Users can free onnx_data buffer after calling menoh_make_model_data_from_onnx().
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
   const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle);

From 9cb600a8e83a8c2fc7df3266b965b91f4ab66e49 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 15:11:29 +0900
Subject: [PATCH 065/321] modify test code to indicate usage

---
 test/onnx.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/onnx.cpp b/test/onnx.cpp
index 798f681..f2fa869 100644
--- a/test/onnx.cpp
+++ b/test/onnx.cpp
@@ -61,6 +61,7 @@ namespace menoh_impl {
               make_model_data_from_onnx_data_on_memory(
                 static_cast<uint8_t*>(static_cast<void*>(buffer.data())),
                 buffer.size());
+            buffer.clear(); // buffer can be cleared here
 
             auto model_data_from_file =
               menoh_impl::make_model_data_from_onnx_file(model_filename);

From 2505cfe0d67ebfe4e23ac14222c7b436f3572e01 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 5 Sep 2018 19:38:24 +0900
Subject: [PATCH 066/321] remove random operation

---
 menoh/onnx.cpp | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 21d4d19..0290aec 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -5,7 +5,6 @@
 #include <fstream>
 #include <functional>
 #include <numeric>
-#include <random>
 #include <unordered_map>
 #include <utility>
 
@@ -202,10 +201,6 @@ namespace menoh_impl {
         trim_dropout(node_list);
         trim_reshape(node_list);
 
-        std::random_device rd;
-        std::mt19937 g(rd());
-        std::shuffle(node_list.begin(), node_list.end(), g);
-
         std::vector<std::string> all_parameter_name_list;
         all_parameter_name_list.reserve(
           onnx_model.graph().initializer().size());

From f589540b5d4013434de3e3a725898b0ae4d80dff Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Thu, 6 Sep 2018 12:36:52 +0900
Subject: [PATCH 067/321] Make data directory

---
 .gitignore      | 1 -
 data/.gitignore | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 data/.gitignore

diff --git a/.gitignore b/.gitignore
index 6425fde..342b9b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 build*
-data/*
 external/protobuf/
 runx/onnx/onnx.pb.cc
 runx/onnx/onnx.pb.h
diff --git a/data/.gitignore b/data/.gitignore
new file mode 100644
index 0000000..d6b7ef3
--- /dev/null
+++ b/data/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore

From 1e9aca37d26ea1727f76d2cae9a52133c811fa54 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 4 Jul 2018 16:50:33 +0900
Subject: [PATCH 068/321] change interface

`menoh_variable_profile_table_builder_add_input_profile_dims_2/4` is
replaced with `menoh_variable_profile_table_builder_add_input_profile`
---
 example/vgg16_example_in_c.c |  5 +++--
 include/menoh/menoh.h        | 24 +++++-------------------
 include/menoh/menoh.hpp      | 24 ++++++------------------
 menoh/menoh.cpp              | 19 ++++---------------
 4 files changed, 18 insertions(+), 54 deletions(-)

diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index b93afe0..762acec 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -29,8 +29,9 @@ int main() {
     menoh_variable_profile_table_builder_handle vpt_builder;
     ERROR_CHECK(menoh_make_variable_profile_table_builder(&vpt_builder));
 
-    ERROR_CHECK(menoh_variable_profile_table_builder_add_input_profile_dims_4(
-      vpt_builder, conv1_1_in_name, menoh_dtype_float, 1, 3, 224, 224));
+    const int32_t input_dims[] = {1, 3, 224, 224};
+    ERROR_CHECK(menoh_variable_profile_table_builder_add_input_profile(
+      vpt_builder, conv1_1_in_name, menoh_dtype_float, 4, input_dims));
 
     ERROR_CHECK(menoh_variable_profile_table_builder_add_output_profile(
       vpt_builder, fc6_out_name, menoh_dtype_float));
diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 2fc016f..488ad27 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -108,8 +108,7 @@ void MENOH_API menoh_delete_model_data(menoh_model_data_handle model_data);
  * This struct configure profiles of variables.
  *
  * See
- *  - menoh_variable_profile_table_builder_add_input_profile_dims_2()
- *  - menoh_variable_profile_table_builder_add_input_profile_dims_4()
+ *  - menoh_variable_profile_table_builder_add_input_profile()
  *  - menoh_variable_profile_table_builder_add_output_profile().
  */
 struct menoh_variable_profile_table_builder;
@@ -128,27 +127,14 @@ menoh_error_code MENOH_API menoh_make_variable_profile_table_builder(
 void MENOH_API menoh_delete_variable_profile_table_builder(
   menoh_variable_profile_table_builder_handle builder);
 
-/*! \brief Add 2D input profile
+/*! \brief Add input profile
  *
- * Input profile contains name, dtype and dims (num, size). This 2D input is
- * conventional batched 1D inputs.
+ * Input profile contains name, dtype and dims.
  */
 menoh_error_code MENOH_API
-menoh_variable_profile_table_builder_add_input_profile_dims_2(
+menoh_variable_profile_table_builder_add_input_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype, int32_t num, int32_t size);
-
-/*! \brief Add 4D input profile
- *
- * Input profile contains name, dtype and dims (num, channel, height, width).
- * This 4D input is conventional batched image inputs. Image input is
- * 3D(channel, height, width).
- */
-menoh_error_code MENOH_API
-menoh_variable_profile_table_builder_add_input_profile_dims_4(
-  menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype, int32_t num, int32_t channel, int32_t height,
-  int32_t width);
+  menoh_dtype dtype, int32_t dims_size, const int32_t* dims);
 
 /*! \brief Add output profile
  *
diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index ec10b6b..4f221b8 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -70,6 +70,8 @@ namespace menoh {
     };
     /** @} */
 
+    enum class dtype_t { float_ = menoh_dtype_float };
+
     class variable_profile_table;
 
     /** @addtogroup cpp_model_data Model data
@@ -122,7 +124,6 @@ namespace menoh {
 
     /** @addtogroup cpp_vpt Veriable profile table
      * @{ */
-    enum class dtype_t { float_ = menoh_dtype_float };
 
     struct variable_profile {
         dtype_t dtype;
@@ -199,23 +200,10 @@ namespace menoh {
         //! Add input profile. That profile contains name, dtype and dims.
         void add_input_profile(std::string const& name, dtype_t dtype,
                                std::vector<int32_t> const& dims) {
-            if(dims.size() == 2) {
-                MENOH_CPP_API_ERROR_CHECK(
-                  menoh_variable_profile_table_builder_add_input_profile_dims_2(
-                    impl_.get(), name.c_str(), static_cast<menoh_dtype>(dtype),
-                    dims.at(0), dims.at(1)));
-            } else if(dims.size() == 4) {
-                MENOH_CPP_API_ERROR_CHECK(
-                  menoh_variable_profile_table_builder_add_input_profile_dims_4(
-                    impl_.get(), name.c_str(), static_cast<menoh_dtype>(dtype),
-                    dims.at(0), dims.at(1), dims.at(2), dims.at(3)));
-            } else {
-                throw error(error_code_t::invalid_dims_size,
-                            "menoh invalid dims size error (2 or 4 is valid): "
-                            "dims size of " +
-                              name + " is specified " +
-                              std::to_string(dims.size()));
-            }
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_variable_profile_table_builder_add_input_profile(
+                impl_.get(), name.c_str(), static_cast<menoh_dtype>(dtype),
+                dims.size(), dims.data()));
         }
 
         //! Add output profile. That profile contains name, dtype.
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 4a80620..fc442e6 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -114,24 +114,13 @@ void menoh_delete_variable_profile_table_builder(
     delete builder;
 }
 
-menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_2(
+menoh_error_code menoh_variable_profile_table_builder_add_input_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype, int32_t num, int32_t size) {
+  menoh_dtype dtype, int32_t dims_size, const int32_t* dims) {
     return check_error([&]() {
-        std::vector<int> dims = {num, size};
         builder->input_name_and_dtype_and_dims_list.push_back(
-          std::make_tuple(std::string(name), dtype, dims));
-        return menoh_error_code_success;
-    });
-}
-menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_4(
-  menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype, int32_t num, int32_t channel, int32_t height,
-  int32_t width) {
-    return check_error([&]() {
-        std::vector<int> dims = {num, channel, height, width};
-        builder->input_name_and_dtype_and_dims_list.push_back(
-          std::make_tuple(std::string(name), dtype, dims));
+          std::make_tuple(std::string(name), dtype,
+                          std::vector<int32_t>(dims, dims + dims_size)));
         return menoh_error_code_success;
     });
 }

From 601c560f7d840160d9a6714e7d26cb61c8fefc6f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 18 Jul 2018 16:37:51 +0900
Subject: [PATCH 069/321] re-define
 menoh_variable_profile_table_builder_add_input_profile_dims_2/4 for backward
 compatibility.

---
 include/menoh/menoh.h | 24 ++++++++++++++++++++++++
 menoh/menoh.cpp       | 22 ++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 488ad27..099ae80 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -136,6 +136,30 @@ menoh_variable_profile_table_builder_add_input_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
   menoh_dtype dtype, int32_t dims_size, const int32_t* dims);
 
+/*! \brief Add 2D input profile
+ *
+ * Input profile contains name, dtype and dims (num, size). This 2D input is
+ * conventional batched 1D inputs.
+ */
+[[deprecated("please use menoh_variable_profile_table_builder_add_input_profile() instead")]]
+menoh_error_code MENOH_API
+menoh_variable_profile_table_builder_add_input_profile_dims_2(
+  menoh_variable_profile_table_builder_handle builder, const char* name,
+  menoh_dtype dtype, int32_t num, int32_t size);
+
+/*! \brief Add 4D input profile
+ *
+ * Input profile contains name, dtype and dims (num, channel, height, width).
+ * This 4D input is conventional batched image inputs. Image input is
+ * 3D(channel, height, width).
+ */
+[[deprecated("please use menoh_variable_profile_table_builder_add_input_profile() instead")]]
+menoh_error_code MENOH_API
+menoh_variable_profile_table_builder_add_input_profile_dims_4(
+  menoh_variable_profile_table_builder_handle builder, const char* name,
+  menoh_dtype dtype, int32_t num, int32_t channel, int32_t height,
+  int32_t width);
+
 /*! \brief Add output profile
  *
  * Output profile contains name and dtype. Its dims are calculated automatically
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index fc442e6..0026f8b 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -125,6 +125,28 @@ menoh_error_code menoh_variable_profile_table_builder_add_input_profile(
     });
 }
 
+menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_2(
+  menoh_variable_profile_table_builder_handle builder, const char* name,
+  menoh_dtype dtype, int32_t num, int32_t size) {
+    return check_error([&]() {
+        std::vector<int> dims = {num, size};
+        builder->input_name_and_dtype_and_dims_list.push_back(
+          std::make_tuple(std::string(name), dtype, dims));
+        return menoh_error_code_success;
+    });
+}
+menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_4(
+  menoh_variable_profile_table_builder_handle builder, const char* name,
+  menoh_dtype dtype, int32_t num, int32_t channel, int32_t height,
+  int32_t width) {
+    return check_error([&]() {
+        std::vector<int> dims = {num, channel, height, width};
+        builder->input_name_and_dtype_and_dims_list.push_back(
+          std::make_tuple(std::string(name), dtype, dims));
+        return menoh_error_code_success;
+    });
+}
+
 menoh_error_code menoh_variable_profile_table_builder_add_output_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
   menoh_dtype dtype) {

From 7ad7e5710e951c7c42fa157a3af6ebc934688c2e Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Thu, 6 Sep 2018 13:28:16 +0900
Subject: [PATCH 070/321] Revert "Make data directory"

This reverts commit f589540b5d4013434de3e3a725898b0ae4d80dff.
---
 .gitignore      | 1 +
 data/.gitignore | 2 --
 2 files changed, 1 insertion(+), 2 deletions(-)
 delete mode 100644 data/.gitignore

diff --git a/.gitignore b/.gitignore
index 342b9b0..6425fde 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 build*
+data/*
 external/protobuf/
 runx/onnx/onnx.pb.cc
 runx/onnx/onnx.pb.h
diff --git a/data/.gitignore b/data/.gitignore
deleted file mode 100644
index d6b7ef3..0000000
--- a/data/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*
-!.gitignore

From 1e5c57c3bb8791d0614e76b254375fc6e64e044e Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Thu, 6 Sep 2018 13:46:37 +0900
Subject: [PATCH 071/321] Make data directory before using it

---
 gen_test_data.py | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/gen_test_data.py b/gen_test_data.py
index c063276..53a0163 100644
--- a/gen_test_data.py
+++ b/gen_test_data.py
@@ -1,3 +1,6 @@
+import errno
+import os
+import os.path
 import sys
 import subprocess
 
@@ -12,6 +15,16 @@ def call(cmd):
     print('')
 
 
+try:
+    os.mkdir('data')
+except OSError as e:
+    if e.errno != errno.EEXIST:
+        traceback.print_exc()
+        sys.exit(1)
+    if not os.path.isdir('data'):
+        sys.stderr.write('Failed to create data directory. Is there a regular file named `data`?\n')
+        sys.exit(1)
+
 pyexe = sys.executable
 
 # Generate input data

From 06fb6c91c8734db652de1d24830afb2ee1e2d35a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 6 Sep 2018 15:05:06 +0900
Subject: [PATCH 072/321] add MENOH_DEPRECATED_ATTRIBUTE

---
 include/menoh/menoh.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 099ae80..ed4f999 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -22,6 +22,16 @@
 #define MENOH_ERROR_MESSAGE_MAX_LENGTH 1024
 #endif
 
+#ifdef __cplusplus
+#define MENOH_DEPRECATED_ATTRIBUTE( message ) [[deprecated( message )]]
+#else
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
+#define MENOH_DEPRECATED_ATTRIBUTE( message ) __declspec(deprecated( message ))
+#else
+#define MENOH_DEPRECATED_ATTRIBUTE( message ) __attribute__((deprecated( message )))
+#endif
+#endif
+
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 
 #ifdef __cplusplus
@@ -141,7 +151,7 @@ menoh_variable_profile_table_builder_add_input_profile(
  * Input profile contains name, dtype and dims (num, size). This 2D input is
  * conventional batched 1D inputs.
  */
-[[deprecated("please use menoh_variable_profile_table_builder_add_input_profile() instead")]]
+MENOH_DEPRECATED_ATTRIBUTE("please use menoh_variable_profile_table_builder_add_input_profile() instead")
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_input_profile_dims_2(
   menoh_variable_profile_table_builder_handle builder, const char* name,
@@ -153,7 +163,7 @@ menoh_variable_profile_table_builder_add_input_profile_dims_2(
  * This 4D input is conventional batched image inputs. Image input is
  * 3D(channel, height, width).
  */
-[[deprecated("please use menoh_variable_profile_table_builder_add_input_profile() instead")]]
+MENOH_DEPRECATED_ATTRIBUTE("please use menoh_variable_profile_table_builder_add_input_profile() instead")
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_input_profile_dims_4(
   menoh_variable_profile_table_builder_handle builder, const char* name,

From 229e54750f25669b14dcd251d327989f06513051 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 6 Sep 2018 15:09:41 +0900
Subject: [PATCH 073/321] little fix

---
 include/menoh/menoh.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index ed4f999..5de0006 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -24,13 +24,11 @@
 
 #ifdef __cplusplus
 #define MENOH_DEPRECATED_ATTRIBUTE( message ) [[deprecated( message )]]
-#else
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
+#elif (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
 #define MENOH_DEPRECATED_ATTRIBUTE( message ) __declspec(deprecated( message ))
 #else
 #define MENOH_DEPRECATED_ATTRIBUTE( message ) __attribute__((deprecated( message )))
 #endif
-#endif
 
 #endif // DOXYGEN_SHOULD_SKIP_THIS
 

From 925a6720f8a5dee454d51b116d3cae4f04e9f7d4 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 6 Sep 2018 15:11:34 +0900
Subject: [PATCH 074/321] fix code style by clang-format

---
 include/menoh/menoh.h | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 5de0006..c6846b1 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -5,7 +5,7 @@
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
+#if(defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
 #define MENOH_API __declspec(dllexport)
 #else
 #define MENOH_API
@@ -23,11 +23,11 @@
 #endif
 
 #ifdef __cplusplus
-#define MENOH_DEPRECATED_ATTRIBUTE( message ) [[deprecated( message )]]
-#elif (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
-#define MENOH_DEPRECATED_ATTRIBUTE( message ) __declspec(deprecated( message ))
+#define MENOH_DEPRECATED_ATTRIBUTE(message) [[deprecated(message)]]
+#elif(defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
+#define MENOH_DEPRECATED_ATTRIBUTE(message) __declspec(deprecated(message))
 #else
-#define MENOH_DEPRECATED_ATTRIBUTE( message ) __attribute__((deprecated( message )))
+#define MENOH_DEPRECATED_ATTRIBUTE(message) __attribute__((deprecated(message)))
 #endif
 
 #endif // DOXYGEN_SHOULD_SKIP_THIS
@@ -149,7 +149,8 @@ menoh_variable_profile_table_builder_add_input_profile(
  * Input profile contains name, dtype and dims (num, size). This 2D input is
  * conventional batched 1D inputs.
  */
-MENOH_DEPRECATED_ATTRIBUTE("please use menoh_variable_profile_table_builder_add_input_profile() instead")
+MENOH_DEPRECATED_ATTRIBUTE(
+  "please use menoh_variable_profile_table_builder_add_input_profile() instead")
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_input_profile_dims_2(
   menoh_variable_profile_table_builder_handle builder, const char* name,
@@ -161,7 +162,8 @@ menoh_variable_profile_table_builder_add_input_profile_dims_2(
  * This 4D input is conventional batched image inputs. Image input is
  * 3D(channel, height, width).
  */
-MENOH_DEPRECATED_ATTRIBUTE("please use menoh_variable_profile_table_builder_add_input_profile() instead")
+MENOH_DEPRECATED_ATTRIBUTE(
+  "please use menoh_variable_profile_table_builder_add_input_profile() instead")
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_input_profile_dims_4(
   menoh_variable_profile_table_builder_handle builder, const char* name,

From 6f1facf19e4f4085d8ec14c5007f621758642a4c Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 6 Sep 2018 15:30:35 +0900
Subject: [PATCH 075/321] check C++ version and gcc

---
 include/menoh/menoh.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index c6846b1..1713f39 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -22,12 +22,14 @@
 #define MENOH_ERROR_MESSAGE_MAX_LENGTH 1024
 #endif
 
-#ifdef __cplusplus
+#if defined(__cplusplus) && __cplusplus >= 201402L
 #define MENOH_DEPRECATED_ATTRIBUTE(message) [[deprecated(message)]]
 #elif(defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
 #define MENOH_DEPRECATED_ATTRIBUTE(message) __declspec(deprecated(message))
-#else
+#elif defined(__GNUC__)
 #define MENOH_DEPRECATED_ATTRIBUTE(message) __attribute__((deprecated(message)))
+#else
+#define MENOH_DEPRECATED_ATTRIBUTE(message)
 #endif
 
 #endif // DOXYGEN_SHOULD_SKIP_THIS

From f67c0935cb84daf2aa9666eb562272385ce4c70f Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 7 Sep 2018 13:17:03 +0900
Subject: [PATCH 076/321] travis: add suffix to MKL-DNN installation directory
 (continued)

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 20fa4ee..509d0ba 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,7 @@ matrix:
                       name: "pfnet-research/menoh"
                       description: "Menoh: DNN inference library"
                   notification_email: menoh-oss@preferred.jp
-                  build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn/lib/libmkldnn.so" .
+                  build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
         - os: linux

From eb9c3bfdf1e083e94c1764d10dbfbbae35ef3ae6 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 7 Sep 2018 15:55:02 +0900
Subject: [PATCH 077/321] travis: shorten the coverity_scan's
 build_command_prepend line

c.f. https://github.com/pfnet-research/menoh/pull/86#issuecomment-419320357
---
 .travis.yml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 509d0ba..2f028f8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,7 +26,11 @@ matrix:
                       name: "pfnet-research/menoh"
                       description: "Menoh: DNN inference library"
                   notification_email: menoh-oss@preferred.jp
-                  build_command_prepend: cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 && cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib/libmkldnn.so" .
+                  build_command_prepend: >-
+                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
+                      cmake
+                      -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/include"
+                      -DMKLDNN_LIBRARY="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
         - os: linux

From 7a58ca4048d49a9592c95b8da83d44252ec4c03c Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 7 Sep 2018 16:05:32 +0900
Subject: [PATCH 078/321] appveyor: define environmental variables for MKL-DNN
 version and MINGW package release version

c.f. https://github.com/pfnet-research/menoh/pull/87#discussion_r215842932
---
 appveyor.yml | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/appveyor.yml b/appveyor.yml
index 17cd152..90e1e4a 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -24,13 +24,16 @@ install:
 - if [%TARGET%]==[mingw] set PATH=C:\msys64\mingw64\bin;C:\msys64\usr\bin;%PATH%
 - if [%TARGET%]==[msvc] set PATH=C:\Miniconda3-x64;C:\Miniconda3-x64\Scripts;C:\Miniconda3-x64\Library\bin;%PATH%
 
+- set MKL_DNN_VER=0.16
+- set MINGW_MKL_DNN_PKG_REL=1
+
 - if [%TARGET%]==[mingw] (
     pacman -S --needed --noconfirm mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake mingw-w64-x86_64-opencv mingw-w64-x86_64-protobuf mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-pip mingw-w64-x86_64-python3-numpy mingw-w64-x86_64-hdf5 mingw-w64-x86_64-ca-certificates &&
-    curl -omingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz &&
-    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.16-1-x86_64.pkg.tar.xz
+    curl -omingw-w64-x86_64-mkl-dnn-%MKL_DNN_VER%-%MINGW_MKL_DNN_PKG_REL%-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-%MKL_DNN_VER%-%MINGW_MKL_DNN_PKG_REL%-x86_64.pkg.tar.xz &&
+    pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-%MKL_DNN_VER%-%MINGW_MKL_DNN_PKG_REL%-x86_64.pkg.tar.xz
   ) else (
-    curl -omkl-dnn-0.16-win64.zip -L --insecure https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mkl-dnn-0.16-win64.zip &&
-    7z x mkl-dnn-0.16-win64.zip &&
+    curl -omkl-dnn-%MKL_DNN_VER%-win64.zip -L --insecure https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mkl-dnn-%MKL_DNN_VER%-win64.zip &&
+    7z x mkl-dnn-%MKL_DNN_VER%-win64.zip &&
     call appveyor\install_protoc_msvc.bat
   )
 
@@ -57,7 +60,7 @@ before_build:
 build_script:
 - mkdir build
 - cd build
-- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-0.16-win64\bin;c:\projects\menoh\mkl-dnn-0.16-win64\include;c:\projects\menoh\mkl-dnn-0.16-win64\lib
+- if [%TARGET%]==[msvc] set PATH=%PATH%;c:\protobuf-3.6.0-msvc\bin;c:\protobuf-3.6.0-msvc\include;c:\protobuf-3.6.0-msvc\lib;c:\projects\menoh\mkl-dnn-%MKL_DNN_VER%-win64\bin;c:\projects\menoh\mkl-dnn-%MKL_DNN_VER%-win64\include;c:\projects\menoh\mkl-dnn-%MKL_DNN_VER%-win64\lib
 - if [%TARGET%]==[mingw] (
     if [%STATIC%]==[1] (
       set STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON -DLINK_STATIC_LIBSTDCXX=ON -DLINK_STATIC_LIBGCC=ON"

From 572beb695a76cd6426a6e2f878df0880574f7452 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 7 Sep 2018 16:06:15 +0900
Subject: [PATCH 079/321] add new APIs to construct model_data by hand

- menoh_make_model_data()
- menoh_model_data_add_new_node()
- menoh_model_data_add_input_name_to_current_node()
- menoh_model_data_add_output_name_to_current_node()
- menoh_model_data_add_attribute_int_to_current_node()
- menoh_model_data_add_attribute_float_to_current_node()
- menoh_model_data_add_attribute_ints_to_current_node()
- menoh_model_data_add_attribute_floats_to_current_node()
- menoh_model_data_add_initializer()
---
 include/menoh/menoh.h   | 51 ++++++++++++++++++++++++
 include/menoh/menoh.hpp | 70 ++++++++++++++++++++++++++++++++-
 menoh/menoh.cpp         | 86 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 205 insertions(+), 2 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index aa0dceb..8ece6d6 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -94,6 +94,57 @@ menoh_error_code MENOH_API menoh_make_model_data_from_onnx(
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
   const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API
+menoh_make_model_data(menoh_model_data_handle* dst_handle);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_new_node(
+  menoh_model_data_handle model_data, const char* op_type);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_input_name_to_current_node(
+  menoh_model_data_handle model_data, const char* input_name);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_output_name_to_current_node(
+  menoh_model_data_handle model_data, const char* output_name);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_attribute_int_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name,
+  int32_t value);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, float value);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API
+menoh_model_data_add_attribute_ints_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
+  const int* value);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API
+menoh_model_data_add_attribute_floats_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
+  const float* value);
+/*! \brief //TODO
+ *
+ */
+menoh_error_code MENOH_API menoh_model_data_add_initializer(
+  menoh_model_data_handle model_data, const char* initializer_name,
+  menoh_dtype dtype, int32_t dims_size, const int32_t* dims, void* buffer_handle);
 /*! \brief Model_data delete function
  *
  * Users must call to release memory resources allocated for
diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index ba637f3..4ec254a 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -70,6 +70,8 @@ namespace menoh {
     };
     /** @} */
 
+    enum class dtype_t { float_ = menoh_dtype_float };
+
     class variable_profile_table;
 
     /** @addtogroup cpp_model_data Model data
@@ -77,6 +79,12 @@ namespace menoh {
     //! model data class
     class model_data {
     public:
+        model_data() : impl_(nullptr, menoh_delete_model_data) {
+            menoh_model_data_handle h;
+            MENOH_CPP_API_ERROR_CHECK(menoh_make_model_data(&h));
+            impl_.reset(h);
+        }
+
         /*! \note Normally users needn't call this constructer. Use
          * make_model_data_from_onnx() instead.
          */
@@ -105,6 +113,66 @@ namespace menoh {
          */
         void optimize(variable_profile_table const& vpt);
 
+        void add_new_node(std::string const& op_type) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_new_node(impl_.get(), op_type.c_str()));
+        }
+
+        void add_input_name_to_current_node(std::string const& input_name) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_input_name_to_current_node(
+                impl_.get(), input_name.c_str()));
+        }
+
+        void add_output_name_to_current_node(std::string const& output_name) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_output_name_to_current_node(
+                impl_.get(), output_name.c_str()));
+        }
+
+        void
+        add_attribute_int_to_current_node(std::string const& attribute_name,
+                                          int32_t value) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_attribute_int_to_current_node(
+                impl_.get(), attribute_name.c_str(), value));
+        }
+
+        void
+        add_attribute_ints_to_current_node(std::string const& attribute_name,
+                                           std::vector<int32_t> const& value) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_attribute_ints_to_current_node(
+                impl_.get(), attribute_name.c_str(), value.size(),
+                value.data()));
+        }
+
+        void
+        add_attribute_float_to_current_node(std::string const& attribute_name,
+                                            float value) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_attribute_float_to_current_node(
+                impl_.get(), attribute_name.c_str(), value));
+        }
+
+        void
+        add_attribute_floats_to_current_node(std::string const& attribute_name,
+                                             std::vector<float> const& value) {
+            MENOH_CPP_API_ERROR_CHECK(
+              menoh_model_data_add_attribute_floats_to_current_node(
+                impl_.get(), attribute_name.c_str(), value.size(),
+                value.data()));
+        }
+
+        void add_initializer(std::string const& initializer_name, dtype_t dtype,
+                             std::vector<int> const& dims,
+                             void* buffer_handle) {
+            MENOH_CPP_API_ERROR_CHECK(menoh_model_data_add_initializer(
+              impl_.get(), initializer_name.c_str(),
+              static_cast<menoh_dtype>(dtype), dims.size(), dims.data(),
+              buffer_handle));
+        }
+
     private:
         std::unique_ptr<menoh_model_data, decltype(&menoh_delete_model_data)>
           impl_;
@@ -131,8 +199,6 @@ namespace menoh {
 
     /** @addtogroup cpp_vpt Veriable profile table
      * @{ */
-    enum class dtype_t { float_ = menoh_dtype_float };
-
     struct variable_profile {
         dtype_t dtype;
         std::vector<int32_t> dims;
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index c1d0b31..69ac966 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -102,6 +102,92 @@ menoh_error_code menoh_make_model_data_from_onnx_data_on_memory(
         return menoh_error_code_success;
     });
 }
+menoh_error_code menoh_make_model_data(menoh_model_data_handle* dst_handle) {
+    return check_error([&]() {
+        *dst_handle = std::make_unique<menoh_model_data>().release();
+        return menoh_error_code_success;
+    });
+}
+menoh_error_code MENOH_API menoh_model_data_add_new_node(
+  menoh_model_data* model_data, const char* op_type) {
+    return check_error([&]() {
+        model_data->model_data.node_list.push_back({op_type, {}, {}, {}});
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_input_name_to_current_node(
+  menoh_model_data* model_data, const char* input_name) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().input_name_list.push_back(
+          input_name);
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_output_name_to_current_node(
+  menoh_model_data* model_data, const char* output_name) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().output_name_list.push_back(
+          output_name);
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_attribute_int_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name,
+  int32_t value) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().attribute_table.insert(
+          {std::string(attribute_name), value});
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, float value) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().attribute_table.insert(
+          {std::string(attribute_name), value});
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
+  const int* value) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().attribute_table.insert(
+          {std::string(attribute_name),
+           std::vector<int32_t>(value, value + size)});
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API
+menoh_model_data_add_attribute_floats_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
+  const float* value) {
+    return check_error([&]() {
+        model_data->model_data.node_list.back().attribute_table.insert(
+          {std::string(attribute_name),
+           std::vector<float>(value, value + size)});
+        return menoh_error_code_success;
+    });
+}
+
+menoh_error_code MENOH_API menoh_model_data_add_initializer(
+  menoh_model_data* model_data, const char* initializer_name, menoh_dtype dtype,
+  int32_t dims_size, const int32_t* dims, void* buffer_handle) {
+    return check_error([&]() {
+        model_data->model_data.parameter_name_and_array_list.push_back(
+          {std::string(initializer_name),
+           menoh_impl::array(static_cast<menoh_impl::dtype_t>(dtype),
+                             std::vector<int32_t>(dims, dims + dims_size),
+                             buffer_handle)});
+        return menoh_error_code_success;
+    });
+}
 void menoh_delete_model_data(menoh_model_data_handle model_data) {
     delete model_data;
 }

From 3fb4abebaa2d8f0186a69bd3c5368fe1c2678d84 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 7 Sep 2018 16:30:24 +0900
Subject: [PATCH 080/321] rename add_initializer -> add_parameter

---
 include/menoh/menoh.h   | 4 ++--
 include/menoh/menoh.hpp | 6 +++---
 menoh/menoh.cpp         | 6 +++---
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 8ece6d6..ce72328 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -142,8 +142,8 @@ menoh_model_data_add_attribute_floats_to_current_node(
 /*! \brief //TODO
  *
  */
-menoh_error_code MENOH_API menoh_model_data_add_initializer(
-  menoh_model_data_handle model_data, const char* initializer_name,
+menoh_error_code MENOH_API menoh_model_data_add_parameter(
+  menoh_model_data_handle model_data, const char* parameter_name,
   menoh_dtype dtype, int32_t dims_size, const int32_t* dims, void* buffer_handle);
 /*! \brief Model_data delete function
  *
diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index 4ec254a..96d557a 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -164,11 +164,11 @@ namespace menoh {
                 value.data()));
         }
 
-        void add_initializer(std::string const& initializer_name, dtype_t dtype,
+        void add_parameter(std::string const& parameter_name, dtype_t dtype,
                              std::vector<int> const& dims,
                              void* buffer_handle) {
-            MENOH_CPP_API_ERROR_CHECK(menoh_model_data_add_initializer(
-              impl_.get(), initializer_name.c_str(),
+            MENOH_CPP_API_ERROR_CHECK(menoh_model_data_add_parameter(
+              impl_.get(), parameter_name.c_str(),
               static_cast<menoh_dtype>(dtype), dims.size(), dims.data(),
               buffer_handle));
         }
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 69ac966..af63b7b 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -176,12 +176,12 @@ menoh_model_data_add_attribute_floats_to_current_node(
     });
 }
 
-menoh_error_code MENOH_API menoh_model_data_add_initializer(
-  menoh_model_data* model_data, const char* initializer_name, menoh_dtype dtype,
+menoh_error_code MENOH_API menoh_model_data_add_parameter(
+  menoh_model_data* model_data, const char* parameter_name, menoh_dtype dtype,
   int32_t dims_size, const int32_t* dims, void* buffer_handle) {
     return check_error([&]() {
         model_data->model_data.parameter_name_and_array_list.push_back(
-          {std::string(initializer_name),
+          {std::string(parameter_name),
            menoh_impl::array(static_cast<menoh_impl::dtype_t>(dtype),
                              std::vector<int32_t>(dims, dims + dims_size),
                              buffer_handle)});

From 4411612456aa7b3730d83b2d7647833918ae6e9d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 7 Sep 2018 17:11:16 +0900
Subject: [PATCH 081/321] add duplication check in
 menoh_model_data_add_parameter()

---
 include/menoh/menoh.h | 1 +
 menoh/menoh.cpp       | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index ce72328..828edc3 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -66,6 +66,7 @@ enum menoh_error_code_constant {
     menoh_error_code_backend_error,
     menoh_error_code_same_named_variable_already_exist,
     menoh_error_code_unsupported_input_dims,
+    menoh_error_code_same_named_parameter_already_exist,
 };
 typedef int32_t menoh_error_code;
 /*! \brief Users can get detailed message about last error.
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index af63b7b..89ef20e 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -180,6 +180,15 @@ menoh_error_code MENOH_API menoh_model_data_add_parameter(
   menoh_model_data* model_data, const char* parameter_name, menoh_dtype dtype,
   int32_t dims_size, const int32_t* dims, void* buffer_handle) {
     return check_error([&]() {
+        // check duplication
+        if(std::find_if(
+             model_data->model_data.parameter_name_and_array_list.begin(),
+             model_data->model_data.parameter_name_and_array_list.end(),
+             [parameter_name](auto const& e) {
+                 return parameter_name == e.first;
+             }) != model_data->model_data.parameter_name_and_array_list.end()) {
+            return menoh_error_code_same_named_parameter_already_exist;
+        }
         model_data->model_data.parameter_name_and_array_list.push_back(
           {std::string(parameter_name),
            menoh_impl::array(static_cast<menoh_impl::dtype_t>(dtype),

From 8476dcadc2ecd2c1bb150bd6331d2592df2b7d13 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 7 Sep 2018 17:12:41 +0900
Subject: [PATCH 082/321] fix code format

---
 include/menoh/menoh.h | 30 +++++++++++++++---------------
 menoh/menoh.cpp       | 10 +++++++---
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 828edc3..8c214a2 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -5,7 +5,7 @@
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
 
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
+#if(defined(_WIN32) || defined(__WIN32__)) && !defined(__GNUC__)
 #define MENOH_API __declspec(dllexport)
 #else
 #define MENOH_API
@@ -84,14 +84,23 @@ MENOH_API const char* menoh_get_last_error_message();
  */
 struct menoh_model_data;
 typedef struct menoh_model_data* menoh_model_data_handle;
-
+/*! \brief Model_data delete function
+ *
+ * Users must call to release memory resources allocated for
+ * model_data.
+ *
+ * \note This function can be called after menoh_build_model() function
+ * call.
+ */
+void MENOH_API menoh_delete_model_data(menoh_model_data_handle model_data);
 /*! \brief Load onnx file and make model_data
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx(
   const char* onnx_filename, menoh_model_data_handle* dst_handle);
 /*! \brief make model_data from onnx binary data on memory
  *
- * \note Users can free onnx_data buffer after calling menoh_make_model_data_from_onnx().
+ * \note Users can free onnx_data buffer after calling
+ * menoh_make_model_data_from_onnx().
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
   const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle);
@@ -129,8 +138,7 @@ menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
 /*! \brief //TODO
  *
  */
-menoh_error_code MENOH_API
-menoh_model_data_add_attribute_ints_to_current_node(
+menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
   const int* value);
 /*! \brief //TODO
@@ -145,16 +153,8 @@ menoh_model_data_add_attribute_floats_to_current_node(
  */
 menoh_error_code MENOH_API menoh_model_data_add_parameter(
   menoh_model_data_handle model_data, const char* parameter_name,
-  menoh_dtype dtype, int32_t dims_size, const int32_t* dims, void* buffer_handle);
-/*! \brief Model_data delete function
- *
- * Users must call to release memory resources allocated for
- * model_data.
- *
- * \note This function can be called after menoh_build_model() function
- * call.
- */
-void MENOH_API menoh_delete_model_data(menoh_model_data_handle model_data);
+  menoh_dtype dtype, int32_t dims_size, const int32_t* dims,
+  void* buffer_handle);
 /** @} */
 
 /*! @addtogroup vpt Variable profile table types and operations
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 89ef20e..214e2fb 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -79,6 +79,10 @@ struct menoh_model_data {
     menoh_impl::model_data model_data;
 };
 
+void menoh_delete_model_data(menoh_model_data_handle model_data) {
+    delete model_data;
+}
+
 menoh_error_code
 menoh_make_model_data_from_onnx(const char* onnx_filename,
                                 menoh_model_data_handle* dst_handle) {
@@ -91,6 +95,7 @@ menoh_make_model_data_from_onnx(const char* onnx_filename,
         return menoh_error_code_success;
     });
 }
+
 menoh_error_code menoh_make_model_data_from_onnx_data_on_memory(
   const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle) {
     return check_error([&]() {
@@ -102,12 +107,14 @@ menoh_error_code menoh_make_model_data_from_onnx_data_on_memory(
         return menoh_error_code_success;
     });
 }
+
 menoh_error_code menoh_make_model_data(menoh_model_data_handle* dst_handle) {
     return check_error([&]() {
         *dst_handle = std::make_unique<menoh_model_data>().release();
         return menoh_error_code_success;
     });
 }
+
 menoh_error_code MENOH_API menoh_model_data_add_new_node(
   menoh_model_data* model_data, const char* op_type) {
     return check_error([&]() {
@@ -197,9 +204,6 @@ menoh_error_code MENOH_API menoh_model_data_add_parameter(
         return menoh_error_code_success;
     });
 }
-void menoh_delete_model_data(menoh_model_data_handle model_data) {
-    delete model_data;
-}
 
 /*
  * variable_profile_table_builder

From fd52e51ce4d1f24ad56e718374906e5691386911 Mon Sep 17 00:00:00 2001
From: Toru Ogawa <Hakuyume@users.noreply.github.com>
Date: Fri, 7 Sep 2018 17:56:15 +0900
Subject: [PATCH 083/321] update README

---
 README.md | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/README.md b/README.md
index 21c73aa..3516f9c 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,14 @@ This codebase contains C API and C++ API.
 
 - For Windows users, prebuild libraries are available (see [release](https://github.com/pfnet-research/menoh/releases)) and [Nuget package](https://www.nuget.org/packages/Menoh/) is available.
 - For macOS user, [Homebrew tap repository](https://github.com/pfnet-research/homebrew-menoh) is available.
+- For Ubuntu user, binary packages are available.
+    ```
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_menoh_1.0.3-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_menoh-dev_1.0.3-1_amd64.deb
+    $ sudo apt install ./ubuntu1604_*_amd64.deb
+    ```
+    If you are using Ubuntu 18.04, please replace `1604` with `1804`.
 
 # Installation from source
 

From 34519771537daa7689809221f30609d914d2a564 Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Fri, 7 Sep 2018 20:22:53 +0900
Subject: [PATCH 084/321] Increase total bytes limit in
 make_model_data_from_onnx_data_on_memory

---
 menoh/onnx.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 174ff5d..e1813e6 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -232,8 +232,11 @@ namespace menoh_impl {
     model_data make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data, int32_t size) {
         namespace gpio = ::google::protobuf::io;
         gpio::ArrayInputStream ais(onnx_data, size);
+        gpio::CodedInputStream cis(&ais);
+        cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
+                               std::numeric_limits<int>::max());
         onnx::ModelProto onnx_model;
-        if(!onnx_model.ParseFromZeroCopyStream(&ais)) {
+        if(!onnx_model.ParseFromCodedStream(&cis) || !cis.ConsumedEntireMessage()) {
             throw onnx_parse_error("parse binary onnx data on memory");
         }
         return make_model_from_onnx(onnx_model);

From e26116667149191bce34aae2adc0c5c8914c2b1d Mon Sep 17 00:00:00 2001
From: Toru Ogawa <Hakuyume@users.noreply.github.com>
Date: Fri, 7 Sep 2018 23:49:27 +0900
Subject: [PATCH 085/321] use mkl-dnn deb

---
 .travis.yml               | 12 ++++++------
 .travis/install_mkldnn.sh | 13 -------------
 2 files changed, 6 insertions(+), 19 deletions(-)
 delete mode 100644 .travis/install_mkldnn.sh

diff --git a/.travis.yml b/.travis.yml
index 509d0ba..e471eb6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -43,20 +43,21 @@ matrix:
                       - libopencv-dev
 env:
     global:
-        - MKL_DNN_REV: v0.15
-        - MKL_DNN_INSTALL_SUFFIX: -0.15
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
         #   via the "travis encrypt" command using the project repo's public key
         - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
-cache:
-    directories:
-        - $HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}
 before_install:
     - |
       if [ "$TRAVIS_OS_NAME" = "linux" ]; then
         echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
       fi
 install:
+    - |
+      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+        curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1404_mkl-dnn_0.16-1_amd64.deb
+        curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1404_mkl-dnn-dev_0.16-1_amd64.deb
+        sudo dpkg -i *.deb
+      fi
     - |
       if [ "$TRAVIS_OS_NAME" = "osx" ]; then
         brew update
@@ -69,7 +70,6 @@ install:
         pyenv local 3.6
       fi
     - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
-    - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sh .travis/install_mkldnn.sh; fi
     - mkdir -p data
     - pip install --user chainer
     - python retrieve_data.py
diff --git a/.travis/install_mkldnn.sh b/.travis/install_mkldnn.sh
deleted file mode 100644
index 7750d5f..0000000
--- a/.travis/install_mkldnn.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-if [ ! -d "$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib" ]; then
-    git clone https://github.com/intel/mkl-dnn.git
-    cd mkl-dnn
-    git checkout $MKL_DNN_REV
-    cd scripts && bash ./prepare_mkl.sh && cd ..
-    sed -i 's/add_subdirectory(examples)//g' CMakeLists.txt
-    sed -i 's/add_subdirectory(tests)//g' CMakeLists.txt
-    mkdir -p build && cd build && cmake -DCMAKE_INSTALL_PREFIX=$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX} .. && make
-    make install
-    cd ..
-else
-    echo "Using cached directory."
-fi

From 2e39f9de5bb167ef864a049b9e954c5453b95cd4 Mon Sep 17 00:00:00 2001
From: Toru Ogawa <Hakuyume@users.noreply.github.com>
Date: Sat, 8 Sep 2018 00:00:31 +0900
Subject: [PATCH 086/321] remove print

---
 .travis.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index e471eb6..754d740 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -86,7 +86,6 @@ before_script:
       fi
       cmake --version
       make --version
-    - ls -R $HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}
 script:
     #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
     # CMakeCache.txt generated for coverity_scan build hinders out-of-source build

From f9c26e91740663bef4c20f1db9ca1790279dfe68 Mon Sep 17 00:00:00 2001
From: Toru Ogawa <Hakuyume@users.noreply.github.com>
Date: Sat, 8 Sep 2018 00:38:18 +0900
Subject: [PATCH 087/321] remove option

---
 .travis.yml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 754d740..af07e58 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -109,8 +109,6 @@ script:
         ..
       else
         cmake -DENABLE_TEST=ON \
-        -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/include" \
-        -DMKLDNN_LIBRARY="$HOME/mkl-dnn${MKL_DNN_INSTALL_SUFFIX}/lib/libmkldnn.so" \
         $STATIC_OPTION \
         ..
       fi

From 778906abe1f3636a22e6db2158b03f4c2f1c9695 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:24:39 +0900
Subject: [PATCH 088/321] add error handling

---
 include/menoh/menoh.h |  1 +
 menoh/menoh.cpp       | 53 ++++++++++++++++++++++++++++---------------
 2 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 8c214a2..1d2c6c7 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -67,6 +67,7 @@ enum menoh_error_code_constant {
     menoh_error_code_same_named_variable_already_exist,
     menoh_error_code_unsupported_input_dims,
     menoh_error_code_same_named_parameter_already_exist,
+    menoh_error_code_same_named_attribute_already_exist,
 };
 typedef int32_t menoh_error_code;
 /*! \brief Users can get detailed message about last error.
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 214e2fb..61188a7 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -141,21 +141,46 @@ menoh_error_code MENOH_API menoh_model_data_add_output_name_to_current_node(
     });
 }
 
-menoh_error_code MENOH_API menoh_model_data_add_attribute_int_to_current_node(
+template <typename T>
+menoh_error_code menoh_model_data_add_attribute_scalar_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name,
-  int32_t value) {
+  T const& value) {
     return check_error([&]() {
-        model_data->model_data.node_list.back().attribute_table.insert(
-          {std::string(attribute_name), value});
+        auto& attribute_table =
+          model_data->model_data.node_list.back().attribute_table;
+        if(attribute_table.find(attribute_name) != attribute_table.end()) {
+            return menoh_error_code_same_named_attribute_already_exist;
+        }
+        attribute_table.insert({std::string(attribute_name), value});
         return menoh_error_code_success;
     });
 }
 
+menoh_error_code MENOH_API menoh_model_data_add_attribute_int_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name,
+  int32_t value) {
+    return menoh_model_data_add_attribute_scalar_to_current_node(
+      model_data, attribute_name, value);
+}
+
 menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, float value) {
+    return menoh_model_data_add_attribute_scalar_to_current_node(
+      model_data, attribute_name, value);
+}
+
+template <typename T>
+menoh_error_code menoh_model_data_add_attribute_array_to_current_node(
+  menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
+  const T* value) {
     return check_error([&]() {
-        model_data->model_data.node_list.back().attribute_table.insert(
-          {std::string(attribute_name), value});
+        auto& attribute_table =
+          model_data->model_data.node_list.back().attribute_table;
+        if(attribute_table.find(attribute_name) != attribute_table.end()) {
+            return menoh_error_code_same_named_attribute_already_exist;
+        }
+        attribute_table.insert(
+          {std::string(attribute_name), std::vector<T>(value, value + size)});
         return menoh_error_code_success;
     });
 }
@@ -163,24 +188,16 @@ menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
 menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
   const int* value) {
-    return check_error([&]() {
-        model_data->model_data.node_list.back().attribute_table.insert(
-          {std::string(attribute_name),
-           std::vector<int32_t>(value, value + size)});
-        return menoh_error_code_success;
-    });
+    return menoh_model_data_add_attribute_array_to_current_node(
+      model_data, attribute_name, size, value);
 }
 
 menoh_error_code MENOH_API
 menoh_model_data_add_attribute_floats_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
   const float* value) {
-    return check_error([&]() {
-        model_data->model_data.node_list.back().attribute_table.insert(
-          {std::string(attribute_name),
-           std::vector<float>(value, value + size)});
-        return menoh_error_code_success;
-    });
+    return menoh_model_data_add_attribute_array_to_current_node(
+      model_data, attribute_name, size, value);
 }
 
 menoh_error_code MENOH_API menoh_model_data_add_parameter(

From 9b6446af018aa44f3be3e437d00a1af9e9ae9238 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:25:32 +0900
Subject: [PATCH 089/321] add tests

---
 test/CMakeLists.txt |  1 +
 test/model_data.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 88 insertions(+)
 create mode 100644 test/model_data.cpp

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d27878b..aa5b4f4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,6 +8,7 @@ add_executable(menoh_test
 
     operator.cpp
     model.cpp
+    model_data.cpp
     #vgg16.cpp
 
 )
diff --git a/test/model_data.cpp b/test/model_data.cpp
new file mode 100644
index 0000000..191f812
--- /dev/null
+++ b/test/model_data.cpp
@@ -0,0 +1,87 @@
+#include <gtest/gtest.h>
+
+#include <iostream>
+#include <unordered_set>
+
+#include <menoh/menoh.cpp>
+#include <menoh/menoh.hpp>
+
+#include "common.hpp"
+
+namespace {
+    class ModelDataTest : public ::testing::Test {};
+
+    TEST_F(ModelDataTest, make_model_data_with_default_constructor) {
+        menoh::model_data model_data;
+        EXPECT_EQ(model_data.get()->model_data.node_list.size(), 0);
+    }
+
+    TEST_F(ModelDataTest, add_new_node) {
+        menoh::model_data model_data;
+        model_data.add_new_node("op1");
+        EXPECT_EQ(model_data.get()->model_data.node_list.size(), 1);
+        EXPECT_EQ(model_data.get()->model_data.node_list.at(0).op_type, "op1");
+        model_data.add_new_node("op2");
+        EXPECT_EQ(model_data.get()->model_data.node_list.size(), 2);
+        EXPECT_EQ(model_data.get()->model_data.node_list.at(1).op_type, "op2");
+    }
+
+    TEST_F(ModelDataTest, add_attribute) {
+        menoh::model_data model_data;
+        model_data.add_new_node("");
+        auto const& attribute_table =
+          model_data.get()->model_data.node_list.front().attribute_table;
+
+        model_data.add_attribute_int_to_current_node("attr1", 42);
+        EXPECT_EQ(menoh_impl::get<int>(attribute_table.at("attr1")), 42);
+
+        model_data.add_attribute_int_to_current_node("attr2", 53);
+        EXPECT_EQ(menoh_impl::get<int>(attribute_table.at("attr1")), 42);
+        EXPECT_EQ(menoh_impl::get<int>(attribute_table.at("attr2")), 53);
+
+        // attribute duplication is not allowed
+        EXPECT_THROW(model_data.add_attribute_int_to_current_node("attr1", 123),
+                     menoh::error);
+    }
+
+    TEST_F(ModelDataTest, add_parameter) {
+        menoh::model_data model_data;
+        auto const& parameter_name_and_array_list =
+          model_data.get()->model_data.parameter_name_and_array_list;
+        std::vector<float> param1_buffer({1, 2, 3, 4});
+        model_data.add_parameter("param1", menoh::dtype_t::float_, {2, 2},
+                                 param1_buffer.data());
+        EXPECT_EQ(parameter_name_and_array_list.front().first, "param1");
+        EXPECT_EQ(parameter_name_and_array_list.front().second.data(),
+                  param1_buffer.data());
+        menoh_impl::array param1_clone_arr(
+          menoh_impl::dtype_t::float_, std::vector<int>({2, 2}),
+          static_cast<void*>(param1_buffer.data()));
+        EXPECT_TRUE(is_near_array(parameter_name_and_array_list.front().second,
+                                  param1_clone_arr));
+
+        std::vector<float> param2_buffer({11, 12, 13, 14});
+        model_data.add_parameter("param2", menoh::dtype_t::float_, {2, 2},
+                                 param2_buffer.data());
+
+        EXPECT_EQ(parameter_name_and_array_list.front().first, "param1");
+        EXPECT_EQ(parameter_name_and_array_list.front().second.data(),
+                  param1_buffer.data());
+        EXPECT_TRUE(is_near_array(parameter_name_and_array_list.front().second,
+                                  param1_clone_arr));
+
+        EXPECT_EQ(parameter_name_and_array_list.at(1).first, "param2");
+        EXPECT_EQ(parameter_name_and_array_list.at(1).second.data(),
+                  param2_buffer.data());
+        menoh_impl::array param2_clone_arr(
+          menoh_impl::dtype_t::float_, std::vector<int>({2, 2}),
+          static_cast<void*>(param2_buffer.data()));
+        EXPECT_TRUE(is_near_array(parameter_name_and_array_list.at(1).second,
+                                  param2_clone_arr));
+
+        // named parameter duplication is not allowed
+        EXPECT_THROW(model_data.add_parameter("param1", menoh::dtype_t::float_,
+                                              {2, 2}, param1_buffer.data()),
+                     menoh::error);
+    }
+} // namespace

From 8e626bb7ededf05baab1e4117b8593646d2640cf Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:36:49 +0900
Subject: [PATCH 090/321] add documents

---
 include/menoh/menoh.h | 37 +++++++++++++++++++------------------
 1 file changed, 19 insertions(+), 18 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 1d2c6c7..8c47bc1 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -105,57 +105,58 @@ menoh_error_code MENOH_API menoh_make_model_data_from_onnx(
  */
 menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
   const uint8_t* onnx_data, int32_t size, menoh_model_data_handle* dst_handle);
-/*! \brief //TODO
- *
+/*! \brief Make empty model_data
  */
 menoh_error_code MENOH_API
 menoh_make_model_data(menoh_model_data_handle* dst_handle);
-/*! \brief //TODO
+/*! \brief Add a new parameter in model_data
  *
+ * \note Duplication of parameter_name is not allowed and it throws error.
+ */
+menoh_error_code MENOH_API menoh_model_data_add_parameter(
+  menoh_model_data_handle model_data, const char* parameter_name,
+  menoh_dtype dtype, int32_t dims_size, const int32_t* dims,
+  void* buffer_handle);
+/*! \brief Add a new node to model_data
  */
 menoh_error_code MENOH_API menoh_model_data_add_new_node(
   menoh_model_data_handle model_data, const char* op_type);
-/*! \brief //TODO
- *
+/*! \brief Add a new input name to latest added node in model_data
  */
 menoh_error_code MENOH_API menoh_model_data_add_input_name_to_current_node(
   menoh_model_data_handle model_data, const char* input_name);
-/*! \brief //TODO
- *
+/*! \brief Add a new output name to latest added node in model_data
  */
 menoh_error_code MENOH_API menoh_model_data_add_output_name_to_current_node(
   menoh_model_data_handle model_data, const char* output_name);
-/*! \brief //TODO
+/*! \brief Add a new int attribute to latest added node in model_data
  *
+ * \note Duplication of attribute_name is not allowed and it throws error.
  */
 menoh_error_code MENOH_API menoh_model_data_add_attribute_int_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name,
   int32_t value);
-/*! \brief //TODO
+/*! \brief Add a new float attribute to latest added node in model_data
  *
+ * \note Duplication of attribute_name is not allowed and it throws error.
  */
 menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, float value);
-/*! \brief //TODO
+/*! \brief Add a new int array attribute to latest added node in model_data
  *
+ * \note Duplication of attribute_name is not allowed and it throws error.
  */
 menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
   const int* value);
-/*! \brief //TODO
+/*! \brief Add a new float array attribute to latest added node in model_data
  *
+ * \note Duplication of attribute_name is not allowed and it throws error.
  */
 menoh_error_code MENOH_API
 menoh_model_data_add_attribute_floats_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
   const float* value);
-/*! \brief //TODO
- *
- */
-menoh_error_code MENOH_API menoh_model_data_add_parameter(
-  menoh_model_data_handle model_data, const char* parameter_name,
-  menoh_dtype dtype, int32_t dims_size, const int32_t* dims,
-  void* buffer_handle);
 /** @} */
 
 /*! @addtogroup vpt Variable profile table types and operations

From 946099f3a4a38fc4c0ebc032d72deb9396f13200 Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Mon, 10 Sep 2018 16:10:07 +0900
Subject: [PATCH 091/321] Use RPATH instead of RUNPATH for test

---
 CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a3d3a32..beb906b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.1)
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
+set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags")
+
 set(MENOH_MAJOR_VERSION 1)
 set(MENOH_MINOR_VERSION 1)
 set(MENOH_PATCH_VERSION 0)

From cba92378cc2202c7e065a4eea26830cb2f095e52 Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Mon, 10 Sep 2018 17:21:09 +0900
Subject: [PATCH 092/321] Fix indent in a cmake file

---
 cmake/ConfigureMenoh.cmake | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/cmake/ConfigureMenoh.cmake b/cmake/ConfigureMenoh.cmake
index 772c439..a2f956a 100644
--- a/cmake/ConfigureMenoh.cmake
+++ b/cmake/ConfigureMenoh.cmake
@@ -9,12 +9,12 @@ macro(menoh_link_libraries TARGET_NAME SCOPE)
     endif()
 
     if(NOT ${SCOPE})
-	    # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
-	    # Note: change it to PRIVATE after building mkldnn itself
-	    target_link_libraries(${TARGET_NAME} PUBLIC ${MKLDNN_LIBRARIES})
-	else()
-	    target_link_libraries(${TARGET_NAME} ${MKLDNN_LIBRARIES})
-	endif()
+        # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
+        # Note: change it to PRIVATE after building mkldnn itself
+        target_link_libraries(${TARGET_NAME} PUBLIC ${MKLDNN_LIBRARIES})
+    else()
+        target_link_libraries(${TARGET_NAME} ${MKLDNN_LIBRARIES})
+    endif()
 
     target_link_libraries(${TARGET_NAME} ${SCOPE} ${PROTOBUF_LIBRARIES})
 endmacro()

From 6ed093b30a37bb673ff4faa5e3c782f701713a5c Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Mon, 10 Sep 2018 17:39:13 +0900
Subject: [PATCH 093/321] Remove -march=native for compatibility

---
 CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a3d3a32..b51806e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -29,11 +29,11 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
 if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # check Clang and AppleClang
     # using Clang
     set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg -Wall -Wextra")
-    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG -march=native")
+    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
 elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
     # using GCC
     set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg -Wall -Wextra")
-    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG -march=native")
+    set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG")
 endif()
 
 # Configure to use the new `libstdc++` ABI

From 174916aa1251ac64bd9727225e27de9636cee56e Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Tue, 11 Sep 2018 08:54:15 +0900
Subject: [PATCH 094/321] Fix compilation error on GCC 5.4

---
 test/mkldnn.cpp | 14 ++++++++------
 test/model.cpp  |  7 ++++---
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/test/mkldnn.cpp b/test/mkldnn.cpp
index 8faf743..8799591 100644
--- a/test/mkldnn.cpp
+++ b/test/mkldnn.cpp
@@ -88,13 +88,15 @@ namespace menoh_impl {
             // Construct computation primitive list and memories
             ASSERT_THROW(
               menoh_impl::model(
-                {{conv1_1_in_name, menoh_impl::dtype_t::float_, input_dims,
-                  nullptr}}, // table of input_name, dtype, input_dims and
+                {std::make_tuple(
+                  conv1_1_in_name, menoh_impl::dtype_t::float_, input_dims,
+                  nullptr)}, // table of input_name, dtype, input_dims and
                              // data_handle
-                {{softmax_out_name, menoh_impl::dtype_t::float_,
-                  nullptr}}, // list of output names, dtypes and data_handles
-                model_data, "mkldnn",
-                "{\"cpu_id\":" + std::to_string(cpu_count + 2) + "}"),
+                {std::make_tuple(
+                  softmax_out_name, menoh_impl::dtype_t::float_,
+                  nullptr)}, // list of output names, dtypes and data_handles
+                model_data,
+                "mkldnn", "{\"cpu_id\":" + std::to_string(cpu_count + 2) + "}"),
               menoh_impl::backend_error);
         }
 
diff --git a/test/model.cpp b/test/model.cpp
index e610c91..8509662 100644
--- a/test/model.cpp
+++ b/test/model.cpp
@@ -32,9 +32,10 @@ namespace menoh_impl {
 
             // Construct computation primitive list and memories
             auto model = menoh_impl::model(
-              {{conv1_1_in_name, dtype_t::float_, input_dims, nullptr}},
-              {{softmax_out_name, dtype_t::float_, nullptr}}, *model_data,
-              "mkldnn");
+              {std::make_tuple(conv1_1_in_name, dtype_t::float_, input_dims,
+                               nullptr)},
+              {std::make_tuple(softmax_out_name, dtype_t::float_, nullptr)},
+              *model_data, "mkldnn");
             model_data.reset(); // delete model_data
 
             model.run();

From f1d348801fa92182ad2241acb791a1dc71610fce Mon Sep 17 00:00:00 2001
From: Gentaro Watanabe <g.wtnb@preferred.jp>
Date: Tue, 11 Sep 2018 13:09:23 +0900
Subject: [PATCH 095/321] Fix cmake files for environments other than Linux

---
 CMakeLists.txt      | 2 --
 test/CMakeLists.txt | 5 +++++
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index beb906b..a3d3a32 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.1)
 
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
-set(CMAKE_EXE_LINKER_FLAGS "-Wl,--disable-new-dtags")
-
 set(MENOH_MAJOR_VERSION 1)
 set(MENOH_MINOR_VERSION 1)
 set(MENOH_PATCH_VERSION 0)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d27878b..4348424 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -12,5 +12,10 @@ add_executable(menoh_test
 
 )
 target_link_libraries(menoh_test gtest_main menoh_test_target)
+if(UNIX AND NOT APPLE)
+    set_property(
+        TARGET menoh_test APPEND_STRING PROPERTY
+            LINK_FLAGS "-Wl,--disable-new-dtags")
+endif()
 
 add_test(NAME menoh_test COMMAND menoh_test)

From bda2c748447951623cd617181ce9cdb2e186c0b7 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 11 Sep 2018 20:56:58 +0900
Subject: [PATCH 096/321] add CC/CPP/CXX/CXXCPP options to configure for
 protobuf

---
 cmake/SetupProtobuf.cmake |  4 ++--
 cmake/configure-helper.sh | 14 ++++++++++++++
 2 files changed, 16 insertions(+), 2 deletions(-)
 create mode 100644 cmake/configure-helper.sh

diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 5ddaf6e..327edf4 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -24,8 +24,8 @@ if(LINK_STATIC_LIBPROTOBUF)
             URL_HASH ${PROTOBUF_HASH}
             DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
             BUILD_IN_SOURCE 1
-            CONFIGURE_COMMAND ./configure --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
-            BUILD_COMMAND make
+            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER} ${PROTOBUF_DIR} ${PROTOBUF_CFLAGS} ${PROTOBUF_CXXFLAGS}
+            BUILD_COMMAND make -j4
             INSTALL_COMMAND make install
         )
 
diff --git a/cmake/configure-helper.sh b/cmake/configure-helper.sh
new file mode 100644
index 0000000..515fa34
--- /dev/null
+++ b/cmake/configure-helper.sh
@@ -0,0 +1,14 @@
+#!/bin/bash -ex
+
+c_compiler=$1
+cxx_compiler=$2
+prefix=$3
+cflags=$4
+cxxflags=$5
+
+export CC=${c_compiler}
+export CPP="${c_compiler} -E"
+export CXX=${cxx_compiler}
+export CXXCPP="${cxx_compiler} -E"
+
+./configure --prefix=${prefix} CFLAGS=${cflags} CXXFLAGS=${cxxflags}

From ddcef8c6bc3d0f1c92f64d0d3c191271696abcfa Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 16:10:12 +0900
Subject: [PATCH 097/321] dockernize Travis build for Linux

---
 .travis.yml                 | 144 +++++++++---------------------------
 .travis/README.md           |  50 +++++++++++++
 .travis/init-build-linux.sh |  79 ++++++++++++++++++++
 .travis/init-build-osx.sh   |  36 +++++++++
 .travis/install-mkldnn.sh   |  96 ++++++++++++++++++++++++
 .travis/install-protobuf.sh |  83 +++++++++++++++++++++
 .travis/run-build.sh        |  56 ++++++++++++++
 7 files changed, 435 insertions(+), 109 deletions(-)
 create mode 100644 .travis/README.md
 create mode 100644 .travis/init-build-linux.sh
 create mode 100644 .travis/init-build-osx.sh
 create mode 100644 .travis/install-mkldnn.sh
 create mode 100644 .travis/install-protobuf.sh
 create mode 100644 .travis/run-build.sh

diff --git a/.travis.yml b/.travis.yml
index 0bda972..3ac1923 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,124 +1,50 @@
 dist: trusty
 sudo: required
 language: cpp
+services:
+  - docker
 addons:
 matrix:
     include:
         - os: osx
+          env: PLATFORM=macosx-x86_64
         - os: osx
-          env: STATIC=1
+          env: PLATFORM=macosx-x86_64 LINK_STATIC=true
         - os: linux
-          addons:
-              apt:
-                  sources:
-                      - ubuntu-toolchain-r-test
-                      - sourceline: 'ppa:maarten-fonville/protobuf'
-                  packages:
-                      - gcc-7
-                      - g++-7
-                      - cmake-data
-                      - cmake
-                      - libopencv-dev
-                      - libprotobuf-dev
-                      - protobuf-compiler
-              coverity_scan:
-                  project:
-                      name: "pfnet-research/menoh"
-                      description: "Menoh: DNN inference library"
-                  notification_email: menoh-oss@preferred.jp
-                  build_command_prepend: >-
-                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
-                      cmake .
-                  build_command: make
-                  branch_pattern: coverity_scan
+          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
+#          addons:
+#              coverity_scan:
+#                  project:
+#                      name: "pfnet-research/menoh"
+#                      description: "Menoh: DNN inference library"
+#                  notification_email: menoh-oss@preferred.jp
+#                  build_command_prepend: >-
+#                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
+#                      cmake .
+#                  build_command: make
+#                  branch_pattern: coverity_scan
         - os: linux
-          env: STATIC=1
-          addons:
-              apt:
-                  sources:
-                      - ubuntu-toolchain-r-test
-                  packages:
-                      - gcc-7
-                      - g++-7
-                      - cmake-data
-                      - cmake
-                      - libopencv-dev
+          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
+
 env:
     global:
+        - PROTOBUF_VERSION: 3.6.1
+        - MKLDNN_VERSION: 0.16
+        - MAKE_JOBS: 2
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
         #   via the "travis encrypt" command using the project repo's public key
-        - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
-before_install:
-    - |
-      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
-        echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
-      fi
-install:
-    - |
-      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
-        curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1404_mkl-dnn_0.16-1_amd64.deb
-        curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1404_mkl-dnn-dev_0.16-1_amd64.deb
-        sudo dpkg -i *.deb
-      fi
-    - |
-      if [ "$TRAVIS_OS_NAME" = "osx" ]; then
-        brew update
-        brew upgrade python
-        export PATH=/usr/local/opt/python/libexec/bin:$PATH
-        brew install numpy || true
-        brew install opencv mkl-dnn
-        if [ -z "$STATIC" ]; then brew install protobuf; fi
-      else
-        pyenv local 3.6
-      fi
-    - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
-    - mkdir -p data
-    - pip install --user chainer
-    - python retrieve_data.py
-    - python gen_test_data.py
-before_script:
-    - |
-      echo 'Checking tools and libraries version:'
-      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
-        apt list --installed
-        ldconfig -p
-      fi
-      if [ "$TRAVIS_OS_NAME" = "osx" ]; then
-        brew list --versions
-      fi
-      cmake --version
-      make --version
+#        - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
+
+cache:
+  directories:
+    - ${HOME}/downloads
+    - ${HOME}/build/protobuf-${PROTOBUF_VERSION}
+    - ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}
+
+#before_install:
+#    - |
+#      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
+#        echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+#      fi
 script:
-    #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
-    # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
-    - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
-    - |
-      if [ -n "$STATIC" ]; then
-        if [ "$TRAVIS_OS_NAME" = "osx" ]; then
-          STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON"
-        else
-          STATIC_OPTION="-DLINK_STATIC_LIBPROTOBUF=ON -DLINK_STATIC_LIBSTDCXX=ON -DLINK_STATIC_LIBGCC=ON"
-        fi
-      else
-        STATIC_OPTION=""
-      fi
-    - mkdir build
-    - cd build
-    - |
-      if [ "$TRAVIS_OS_NAME" == "osx" ]; then
-        cmake -DENABLE_TEST=ON \
-        $STATIC_OPTION \
-        ..
-      else
-        cmake -DENABLE_TEST=ON \
-        $STATIC_OPTION \
-        ..
-      fi
-    - make
-    - ./test/menoh_test
-    - |
-      if [ "$TRAVIS_OS_NAME" == "osx" ]; then
-        otool -L menoh/libmenoh.dylib
-      else
-        ldd menoh/libmenoh.so
-      fi
+    - bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh
diff --git a/.travis/README.md b/.travis/README.md
new file mode 100644
index 0000000..95992cd
--- /dev/null
+++ b/.travis/README.md
@@ -0,0 +1,50 @@
+# Build scripts for Travis
+
+## Prerequisites
+It requires a container image with the following softwares:
+
+- GCC 5.2 or later
+- CMake 3.1 or later
+- Python 3.6
+- pip
+- OpenCV 2.4 or later
+
+Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/) image for linux-x86_64 platform.
+
+## Architecture
+`.travis.yml` -> `run-build.sh` -> `build.sh` -> `install-*.sh` & `build-menoh.sh`
+
+1. `run-build.sh` starts a Docker container for building the project
+    - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
+2. `build.sh` runs a build workflow *in the container*
+    - (All commands are run by `docker_exec` and `docker_exec_cmd` functions)
+    - Install the prerequisites
+    - Run a build
+    - Run a test
+3. Release and clean up
+
+## Directory
+- `/home/travis` (= `${HOME}`)
+    - `/downloads` (cache)
+    - `/build`
+        - `/protobuf-<ver>` (cache)
+        - `/mkl-dnn-<ver>` (cache)
+        - `/<user>/<repo>` (= `${TRAVIS_BUILD_DIR}`)
+            - `/menoh`
+            - `/test`
+            - `/cmake`
+            - `CMakeLists.txt`
+            - ...
+            - `/build`
+                - `/menoh`
+                - `/test`
+                - ...
+
+## Cache
+```yaml
+cache:
+  directories:
+    - ${HOME}/downloads
+    - ${HOME}/build/protobuf-${PROTOBUF_VERSION}
+    - ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}
+```
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
new file mode 100644
index 0000000..36e6351
--- /dev/null
+++ b/.travis/init-build-linux.sh
@@ -0,0 +1,79 @@
+# check if variables are set
+test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID does not exist"; exit 1; }
+test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION does not exist"; exit 1; }
+test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION does not exist"; exit 1; }
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist"; exit 1; }
+
+test -n "${LINK_STATIC}" || LINK_STATIC=false
+
+# TODO: make them configurable for outside Travis
+export WORK_DIR=${HOME}
+export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
+
+export PROTOBUF_INSTALL_DIR=/usr/local
+export MKLDNN_INSTALL_DIR=/usr/local
+
+# define shared functions for Linux-based platforms
+function docker_exec() {
+    docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xec "$1"
+}
+
+function docker_exec_cmd() {
+    docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xe $@
+}
+
+function install_protobuf() {
+    docker_exec_cmd \
+        ${PROJ_DIR}/.travis/install-protobuf.sh \
+            --version ${PROTOBUF_VERSION} \
+            --download-dir ${WORK_DIR}/downloads \
+            --build-dir ${WORK_DIR}/build \
+            --install-dir ${PROTOBUF_INSTALL_DIR} \
+            --parallel ${MAKE_JOBS}
+}
+
+function install_mkldnn() {
+    docker_exec_cmd \
+        ${PROJ_DIR}/.travis/install-mkldnn.sh \
+            --version ${MKLDNN_VERSION} \
+            --download-dir ${WORK_DIR}/downloads \
+            --build-dir ${WORK_DIR}/build \
+            --install-dir ${MKLDNN_INSTALL_DIR} \
+            --parallel ${MAKE_JOBS}
+}
+
+function prepare_menoh_data() {
+    echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
+    docker_exec "$(cat << EOS
+        cd ${PROJ_DIR}/menoh && \
+        ([ -d "data" ] || mkdir -p data) && \
+        python3 retrieve_data.py && \
+        python3 gen_test_data.py
+EOS
+)"
+}
+
+function build_menoh() {
+    # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
+    docker_exec "if [ -f \"CMakeCache.txt\" ]; then cd ${PROJ_DIR} && rm CMakeCache.txt; fi"
+    if [ "${LINK_STATIC}" != "true" ]; then
+        docker_exec_cmd \
+            ${PROJ_DIR}/.travis/build-menoh.sh \
+                --source-dir ${PROJ_DIR}
+    else
+        docker_exec_cmd \
+            ${PROJ_DIR}/.travis/build-menoh.sh \
+                --source-dir ${PROJ_DIR} \
+                --link-static-libgcc ON \
+                --link-static-libstdcxx ON \
+                --link-static-libprotobuf ON
+    fi
+}
+
+function test_menoh() {
+    docker_exec "cd ${PROJ_DIR}/menoh/build && ./test/menoh_test"
+}
+
+function check_menoh_artifact() {
+    ldd ${PROJ_DIR}/menoh/build/menoh/libmenoh.so
+}
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
new file mode 100644
index 0000000..9545360
--- /dev/null
+++ b/.travis/init-build-osx.sh
@@ -0,0 +1,36 @@
+# check if variables are set
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist"; exit 1; }
+
+# TODO: make them configurable for outside Travis
+export WORK_DIR=${HOME}
+export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
+
+function prepare_menoh_data() {
+    echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
+
+    cd ${PROJ_DIR}/menoh
+    [ -d "data" ] || mkdir -p data
+
+    python retrieve_data.py
+    python gen_test_data.py
+}
+
+function build_menoh() {
+    if [ "${LINK_STATIC}" != "true" ]; then
+        ${PROJ_DIR}/.travis/build-menoh.sh \
+            --source-dir ${PROJ_DIR}
+    else
+    	# Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
+        ${PROJ_DIR}/.travis/build-menoh.sh \
+            --source-dir ${PROJ_DIR} \
+            --link-static-libprotobuf ON
+    fi
+}
+
+function test_menoh() {
+    cd ${PROJ_DIR}/menoh/build && ./test/menoh_test
+}
+
+function check_menoh_artifact() {
+    otool -L ${PROJ_DIR}/menoh/build/menoh/libmenoh.dylib
+}
diff --git a/.travis/install-mkldnn.sh b/.travis/install-mkldnn.sh
new file mode 100644
index 0000000..a1ad2be
--- /dev/null
+++ b/.travis/install-mkldnn.sh
@@ -0,0 +1,96 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --version)
+            ARG_VERSION="$2"
+            shift 2
+            ;;
+        --download-dir)
+            ARG_DOWNLOAD_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            ARG_BUILD_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --parallel)
+            ARG_PARALLEL="$2"
+            shift 2
+            ;;
+        -*)
+            err Unknown option \"$1\"
+            exit
+            ;;
+        *)
+            break
+            ;;
+
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_VERSION}" || { echo "--version is not specified"; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified"; exit 1; }
+test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified"; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified"; exit 1; }
+test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
+
+# download (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/LICENSE" ]; then
+    echo -e "\e[33;1mDownloading libmkldnn\e[0m"
+
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+
+    cd ${ARG_DOWNLOAD_DIR}
+    if [ ! -e "mkl-dnn-${ARG_VERSION}.tar.gz" ]; then
+        download_url="https://github.com/intel/mkl-dnn/archive/v${ARG_VERSION}.tar.gz"
+        wget -O mkl-dnn-${ARG_VERSION}.tar.gz ${download_url}
+    fi
+    tar -zxf mkl-dnn-${ARG_VERSION}.tar.gz -C ${ARG_BUILD_DIR}
+
+    echo -e "\e[32;1mlibmkldnn was successfully downloaded.\e[0m"
+else
+    echo -e "\e[32;1mlibmkldnn has been downloaded.\e[0m"
+fi
+
+# build (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/build/src/libmkldnn.so" ]; then
+    echo -e "\e[33;1mBuilding libmkldnn\e[0m"
+
+    cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/scripts
+    ./prepare_mkl.sh
+
+    cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}
+    [ -d "build" ] || mkdir -p build
+
+    cd build
+    cmake \
+        -DCMAKE_BUILD_TYPE=Release \
+        -DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR} \
+        -DWITH_TEST=OFF \
+        -DWITH_EXAMPLE=OFF \
+        -DARCH_OPT_FLAGS='' \
+        -Wno-error=unused-result \
+        ..
+    make -j${ARG_PARALLEL}
+
+    echo -e "\e[32;1mlibmkldnn was successfully built.\e[0m"
+else
+    echo -e "\e[32;1mlibmkldnn has been built.\e[0m"
+fi
+
+# install (always)
+echo -e "\e[33;1mInstalling libmkldnn\e[0m"
+
+cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/build
+make install/strip
diff --git a/.travis/install-protobuf.sh b/.travis/install-protobuf.sh
new file mode 100644
index 0000000..7ea2d84
--- /dev/null
+++ b/.travis/install-protobuf.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --version)
+            ARG_VERSION="$2"
+            shift 2
+            ;;
+        --download-dir)
+            ARG_DOWNLOAD_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            ARG_BUILD_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --parallel)
+            ARG_PARALLEL="$2"
+            shift 2
+            ;;
+        -*)
+            err Unknown option \"$1\"
+            exit
+            ;;
+        *)
+            break
+            ;;
+
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_VERSION}" || { echo "--version is not specified"; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified"; exit 1; }
+test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified"; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified"; exit 1; }
+test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
+
+# download (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}/LICENSE" ]; then
+    echo -e "\e[33;1mDownloading libprotobuf\e[0m"
+
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+
+    cd ${ARG_DOWNLOAD_DIR}
+    if [ ! -e "protobuf-cpp-${ARG_VERSION}.tar.gz" ]; then
+        download_dir="https://github.com/protocolbuffers/protobuf/releases/download/v${ARG_VERSION}/protobuf-cpp-${ARG_VERSION}.tar.gz"
+        wget ${download_dir}
+    fi
+    tar -zxf protobuf-cpp-${ARG_VERSION}.tar.gz -C ${ARG_BUILD_DIR}
+
+    echo -e "\e[32;1mlibprotobuf was successfully downloaded.\e[0m"
+else
+    echo -e "\e[32;1mlibprotobuf has been downloaded.\e[0m"
+fi
+
+# build (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}/src/libprotobuf.la" ]; then
+    echo -e "\e[33;1mBuilding libprotobuf\e[0m"
+
+    cd ${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}
+    ./configure --prefix=${ARG_INSTALL_DIR} CFLAGS=-fPIC CXXFLAGS=-fPIC
+    make -j${ARG_PARALLEL}
+
+    echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
+else
+    echo -e "\e[32;1mlibprotobuf has been built.\e[0m"
+fi
+
+# install (always)
+echo -e "\e[33;1mInstalling libprotobuf\e[0m"
+
+cd ${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}
+make install
diff --git a/.travis/run-build.sh b/.travis/run-build.sh
new file mode 100644
index 0000000..d7518b3
--- /dev/null
+++ b/.travis/run-build.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+
+echo "travis_fold:start:run-build.sh"
+echo -e "\e[33;1mRunning .travis/${PLATFORM}/run-build.sh in ${TRAVIS_REPO_SLUG}\e[0m"
+
+# check if variables have values
+test -n "${PLATFORM}" || { echo "PLATFORM does not exist"; exit 1; }
+
+export PLATFORM_DIR=${TRAVIS_BUILD_DIR}/.travis/${PLATFORM}
+
+# "$TRAVIS_OS_NAME" == "linux"
+if [[ "$PLATFORM" == "linux-x86" ]] || [[ "$PLATFORM" == "linux-x86_64" ]] || [[ "$PLATFORM" =~ android ]]; then
+    test -n "${BUILDENV_IMAGE}" || { echo "BUILDENV_IMAGE does not exist"; exit 1; }
+
+    docker pull ${BUILDENV_IMAGE} || true
+
+    # Run a docker container and map Travis's $HOME to the container's $HOME
+    # $HOME:$HOME = /home/travis                     : /home/travis
+    #               /home/travis/build               : /home/travis/build
+    #               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
+    # TODO: the ownership of files and directories mounted on the container
+    export DOCKER_CONTAINER_ID=$(docker run -d -it -v $HOME:$HOME -v /sys/fs/cgroup:/sys/fs/cgroup:ro ${BUILDENV_IMAGE} /bin/bash)
+
+    # Note: You shouldn't do `docker run` with `--privileged /sbin/init`.
+    # See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
+
+    if [ -z "${DOCKER_CONTAINER_ID}" ]; then
+        echo 'Failed to run a Docker container: '${BUILDENV_IMAGE}
+        exit 1
+    fi
+
+    # Stop the container when run-build.sh exits
+    trap '[[ "$DOCKER_CONTAINER_ID" ]] && docker stop ${DOCKER_CONTAINER_ID} && docker rm -v ${DOCKER_CONTAINER_ID}' 0 1 2 3 15
+
+    docker logs ${DOCKER_CONTAINER_ID}
+
+    if [ -e "${PLATFORM_DIR}/build.sh" ]; then
+        # Dispatch to the platform specific script
+        /bin/bash -ex ${PLATFORM_DIR}/build.sh
+    else
+        echo 'The specified platform not found: '${PLATFORM} 1>&2
+        exit 1
+    fi
+fi
+
+if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+    if [ -e "${PLATFORM_DIR}/build.sh" ]; then
+        # Dispatch to the platform specific script
+        /bin/bash -ex ${PLATFORM_DIR}/build.sh
+    else
+        echo 'The specified platform not found: '${PLATFORM} 1>&2
+        exit 1
+    fi
+fi
+
+echo "travis_fold:end:run-build.sh"

From 60f69e22e2ed4b2985770f74837e87090b2d7943 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 16:20:53 +0900
Subject: [PATCH 098/321] fix .gitignore to allow build*.sh

---
 .gitignore                     |  2 +-
 .travis/build-menoh.sh         | 66 ++++++++++++++++++++++++++++++++++
 .travis/linux-x86_64/build.sh  | 33 +++++++++++++++++
 .travis/macosx-x86_64/build.sh | 40 +++++++++++++++++++++
 4 files changed, 140 insertions(+), 1 deletion(-)
 create mode 100644 .travis/build-menoh.sh
 create mode 100644 .travis/linux-x86_64/build.sh
 create mode 100644 .travis/macosx-x86_64/build.sh

diff --git a/.gitignore b/.gitignore
index 6425fde..69d2099 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-build*
+build*/
 data/*
 external/protobuf/
 runx/onnx/onnx.pb.cc
diff --git a/.travis/build-menoh.sh b/.travis/build-menoh.sh
new file mode 100644
index 0000000..cf48239
--- /dev/null
+++ b/.travis/build-menoh.sh
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --source-dir)
+            ARG_SOURCE_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --link-static-libgcc)
+            ARG_LINK_STATIC_LIBGCC="$2"
+            shift 2
+            ;;
+        --link-static-libstdcxx)
+            ARG_LINK_STATIC_LIBSTDCXX="$2"
+            shift 2
+            ;;
+        --link-static-libprotobuf)
+            ARG_LINK_STATIC_LIBPROTOBUF="$2"
+            shift 2
+            ;;
+        -*)
+            err Unknown option \"$1\"
+            exit
+            ;;
+        *)
+            break
+            ;;
+
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified"; exit 1; }
+
+test -n "${ARG_LINK_STATIC_LIBGCC}" || ARG_LINK_STATIC_LIBGCC='OFF'
+test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || ARG_LINK_STATIC_LIBSTDCXX='OFF'
+test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || ARG_LINK_STATIC_LIBPROTOBUF='OFF'
+
+echo -e "\e[33;1mBuilding Menoh\e[0m"
+
+cd ${ARG_SOURCE_DIR}/menoh
+[ -d "build" ] || mkdir -p build
+
+cd build
+if [ -n "${ARG_INSTALL_DIR}" ]; then
+    CMAKE_INSTALL_PREFIX="-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}"
+fi
+cmake \
+    -DCMAKE_BUILD_TYPE=Release \
+    ${CMAKE_INSTALL_PREFIX} \
+    -DLINK_STATIC_LIBGCC=${ARG_LINK_STATIC_LIBGCC} \
+    -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
+    -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \
+    -DENABLE_TEST=ON \
+    ..
+
+make
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
new file mode 100644
index 0000000..0fa77a5
--- /dev/null
+++ b/.travis/linux-x86_64/build.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -ex
+
+BASE_DIR=$(cd $(dirname $0) && pwd)
+
+# initialize this script
+source ${BASE_DIR}/../init-build-linux.sh
+
+# check the environment
+docker_exec "ls -l ${WORK_DIR}"
+docker_exec "ls -l ${WORK_DIR}/build"
+docker_exec "ls -l ${WORK_DIR}/build/${TRAVIS_REPO_SLUG}"
+
+docker_exec "(printenv | grep PATH) && make --version && cmake --version && g++ --version && ldd --version"
+
+# build and install prerequisites
+install_protobuf
+install_mkldnn
+
+docker_exec "pip3 install --user chainer" # for generating test data
+
+docker_exec "yum list installed"
+docker_exec "pip list"
+
+# build and test menoh
+prepare_menoh_data
+build_menoh
+test_menoh
+
+# check the artifact and release
+check_menoh_artifact
+
+# release the artifact
+# TODO
diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
new file mode 100644
index 0000000..8f840ea
--- /dev/null
+++ b/.travis/macosx-x86_64/build.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+
+BASE_DIR=$(cd $(dirname $0) && pwd)
+
+# initialize this script
+source ${BASE_DIR}/../init-build-osx.sh
+
+# check the environment
+ls -l ${WORK_DIR}
+ls -l ${WORK_DIR}/build
+ls -l ${WORK_DIR}/build/${TRAVIS_REPO_SLUG}
+
+printenv | grep PATH
+make --version
+cmake --version
+g++ --version
+
+# install prerequisites
+brew update
+brew upgrade python
+
+export PATH=/usr/local/opt/python/libexec/bin:$PATH
+
+brew install numpy || true
+brew install opencv mkl-dnn
+
+if [ "$LINK_STATIC" != "true" ]; then brew install protobuf; fi
+
+pip install --user chainer # for generating test data
+
+brew list --versions
+pip list
+
+# build and test menoh
+prepare_menoh_data
+build_menoh
+test_menoh
+
+# check the artifact and release
+check_menoh_artifact

From f0d256ef3de81a2d4b058306e87f77e3e9f547b4 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 16:31:05 +0900
Subject: [PATCH 099/321] fix source directory

---
 .travis/build-menoh.sh        |  2 +-
 .travis/init-build-linux.sh   |  6 +++---
 .travis/init-build-osx.sh     | 10 +++++-----
 .travis/linux-x86_64/build.sh |  2 +-
 4 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/.travis/build-menoh.sh b/.travis/build-menoh.sh
index cf48239..c426789 100644
--- a/.travis/build-menoh.sh
+++ b/.travis/build-menoh.sh
@@ -47,7 +47,7 @@ test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || ARG_LINK_STATIC_LIBPROTOBUF='OFF'
 
 echo -e "\e[33;1mBuilding Menoh\e[0m"
 
-cd ${ARG_SOURCE_DIR}/menoh
+cd ${ARG_SOURCE_DIR}
 [ -d "build" ] || mkdir -p build
 
 cd build
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index 36e6351..bc1706e 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -45,7 +45,7 @@ function install_mkldnn() {
 function prepare_menoh_data() {
     echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
     docker_exec "$(cat << EOS
-        cd ${PROJ_DIR}/menoh && \
+        cd ${PROJ_DIR} && \
         ([ -d "data" ] || mkdir -p data) && \
         python3 retrieve_data.py && \
         python3 gen_test_data.py
@@ -71,9 +71,9 @@ function build_menoh() {
 }
 
 function test_menoh() {
-    docker_exec "cd ${PROJ_DIR}/menoh/build && ./test/menoh_test"
+    docker_exec "cd ${PROJ_DIR}/build/menoh && ./test/menoh_test"
 }
 
 function check_menoh_artifact() {
-    ldd ${PROJ_DIR}/menoh/build/menoh/libmenoh.so
+    ldd ${PROJ_DIR}/build/menoh/libmenoh.so
 }
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 9545360..07acf3c 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -8,7 +8,7 @@ export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 function prepare_menoh_data() {
     echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
 
-    cd ${PROJ_DIR}/menoh
+    cd ${PROJ_DIR}
     [ -d "data" ] || mkdir -p data
 
     python retrieve_data.py
@@ -17,20 +17,20 @@ function prepare_menoh_data() {
 
 function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
-        ${PROJ_DIR}/.travis/build-menoh.sh \
+        bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
             --source-dir ${PROJ_DIR}
     else
     	# Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
-        ${PROJ_DIR}/.travis/build-menoh.sh \
+        bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
             --source-dir ${PROJ_DIR} \
             --link-static-libprotobuf ON
     fi
 }
 
 function test_menoh() {
-    cd ${PROJ_DIR}/menoh/build && ./test/menoh_test
+    cd ${PROJ_DIR}/build/menoh && ./test/menoh_test
 }
 
 function check_menoh_artifact() {
-    otool -L ${PROJ_DIR}/menoh/build/menoh/libmenoh.dylib
+    otool -L ${PROJ_DIR}/build/menoh/libmenoh.dylib
 }
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index 0fa77a5..a9cce3c 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -19,7 +19,7 @@ install_mkldnn
 docker_exec "pip3 install --user chainer" # for generating test data
 
 docker_exec "yum list installed"
-docker_exec "pip list"
+docker_exec "pip3 list"
 
 # build and test menoh
 prepare_menoh_data

From 246117e82d0f4efce730f734ba6bdd3825e08f62 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 17:02:00 +0900
Subject: [PATCH 100/321] run build before preparing data

---
 .travis/init-build-linux.sh    | 2 +-
 .travis/init-build-osx.sh      | 2 +-
 .travis/linux-x86_64/build.sh  | 2 +-
 .travis/macosx-x86_64/build.sh | 2 +-
 4 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index bc1706e..f80e2ea 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -71,7 +71,7 @@ function build_menoh() {
 }
 
 function test_menoh() {
-    docker_exec "cd ${PROJ_DIR}/build/menoh && ./test/menoh_test"
+    docker_exec "cd ${PROJ_DIR}/build && ./test/menoh_test"
 }
 
 function check_menoh_artifact() {
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 07acf3c..e0bdf23 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -28,7 +28,7 @@ function build_menoh() {
 }
 
 function test_menoh() {
-    cd ${PROJ_DIR}/build/menoh && ./test/menoh_test
+    cd ${PROJ_DIR}/build && ./test/menoh_test
 }
 
 function check_menoh_artifact() {
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index a9cce3c..d08f8f7 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -22,8 +22,8 @@ docker_exec "yum list installed"
 docker_exec "pip3 list"
 
 # build and test menoh
-prepare_menoh_data
 build_menoh
+prepare_menoh_data
 test_menoh
 
 # check the artifact and release
diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index 8f840ea..e63e625 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -32,8 +32,8 @@ brew list --versions
 pip list
 
 # build and test menoh
-prepare_menoh_data
 build_menoh
+prepare_menoh_data
 test_menoh
 
 # check the artifact and release

From ac36ae50d85349e61c4fd5953fb8afb125cec004 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 17:19:44 +0900
Subject: [PATCH 101/321] tweek messages

---
 .travis.yml          | 8 +++++++-
 .travis/run-build.sh | 5 -----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 3ac1923..499a5d9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -47,4 +47,10 @@ cache:
 #        echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
 #      fi
 script:
-    - bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh
+    - |
+      echo "travis_fold:start:run-build.sh"
+      echo -e "\e[33;1mRunning .travis/run-build.sh\e[0m"
+
+      bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh
+
+      echo "travis_fold:end:run-build.sh"
diff --git a/.travis/run-build.sh b/.travis/run-build.sh
index d7518b3..4355659 100644
--- a/.travis/run-build.sh
+++ b/.travis/run-build.sh
@@ -1,8 +1,5 @@
 #!/bin/bash
 
-echo "travis_fold:start:run-build.sh"
-echo -e "\e[33;1mRunning .travis/${PLATFORM}/run-build.sh in ${TRAVIS_REPO_SLUG}\e[0m"
-
 # check if variables have values
 test -n "${PLATFORM}" || { echo "PLATFORM does not exist"; exit 1; }
 
@@ -52,5 +49,3 @@ if [ "$TRAVIS_OS_NAME" == "osx" ]; then
         exit 1
     fi
 fi
-
-echo "travis_fold:end:run-build.sh"

From 9fa8f83177c390eead4c0dfff707e8fbc2d19c60 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 18:30:28 +0900
Subject: [PATCH 102/321] enable coverity

---
 .travis.yml                   | 98 ++++++++++++++++++++++++-----------
 .travis/README.md             |  9 ++--
 .travis/build-menoh.sh        |  2 +-
 .travis/init-build-linux.sh   | 22 +++-----
 .travis/init-build-osx.sh     | 12 ++---
 .travis/install-mkldnn.sh     |  8 +--
 .travis/install-protobuf.sh   |  8 +--
 .travis/prepare-menoh-data.sh | 39 ++++++++++++++
 .travis/run-build.sh          |  6 +--
 9 files changed, 135 insertions(+), 69 deletions(-)
 create mode 100644 .travis/prepare-menoh-data.sh

diff --git a/.travis.yml b/.travis.yml
index 499a5d9..a013fd5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,27 +4,6 @@ language: cpp
 services:
   - docker
 addons:
-matrix:
-    include:
-        - os: osx
-          env: PLATFORM=macosx-x86_64
-        - os: osx
-          env: PLATFORM=macosx-x86_64 LINK_STATIC=true
-        - os: linux
-          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
-#          addons:
-#              coverity_scan:
-#                  project:
-#                      name: "pfnet-research/menoh"
-#                      description: "Menoh: DNN inference library"
-#                  notification_email: menoh-oss@preferred.jp
-#                  build_command_prepend: >-
-#                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
-#                      cmake .
-#                  build_command: make
-#                  branch_pattern: coverity_scan
-        - os: linux
-          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
 
 env:
     global:
@@ -33,19 +12,76 @@ env:
         - MAKE_JOBS: 2
         # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
         #   via the "travis encrypt" command using the project repo's public key
-#        - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
+        - secure: "q1I4YsB5VcNaF9Unmm6T92ht9/KwOGbxZVCpXIp5XUVulpaZq7sTd3rL1v3r1mUCYaabkcy9N4UPQjJZsuOlU4jc8zPzPxPir7hOER5umlkfSMuc1RhmShT8cK9naznqv7FLSTIjTZIao85Lrgxgw0B6xzcWc0kSeJPJVAmS5kwmC/FCQS2MPQpyhfE5JjpUrePOT+lRTB6Psm5bWyEww8bPsatO2k5b8DDdmUJIxmuJ1UTCx5rj/ZcTJLWAsj8D7u9aUfCmOhV5+hqHBvJd/06FLt254SNmvzmVLW9CVU/aZvuTtRECgBYCVndR7NxWpRHo1SBKqgLu+cNOFoFyt++1V+FAbpxj9JMktZNyxWp22c/FvBBdHynOsxBxVFdGIzhcwhQMiHFLOK3pnyiByabtINhERqrszkbpztOepBE3o8PGpjOz8iIx1TtLgmWwAw5D6WXx8FeP5FMkJwpXckCMI5tX5wPoU8cpZIwPjCxG3Z+ojHw+80pQWCrMZnEDfcf9zskJNsmv/GbiWGEvI8xVG0gst5VmjaAXK7JhC0cKvPOEmCFRGY+BWdjD3dkYIIElUmBRfTRDpcDJV6j5r1xMv7QKRFDfAjnC33KLJo2aALZTrkRPveIP2h2jU13ZbemN8GKWwEWNzidmwtCbH4rpe80rFqASWkyfii7HrEI="
 
 cache:
-  directories:
-    - ${HOME}/downloads
-    - ${HOME}/build/protobuf-${PROTOBUF_VERSION}
-    - ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}
+    directories:
+        - ${HOME}/downloads
+        - ${HOME}/build/protobuf-${PROTOBUF_VERSION}
+        - ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}
+
+matrix:
+    include:
+        - os: osx
+          env: PLATFORM=macosx-x86_64
+        - os: osx
+          env: PLATFORM=macosx-x86_64 LINK_STATIC=true
+        - os: linux
+          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
+        - os: linux
+          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
+        - os: linux
+          env: RUN_COVERITY=true
+          addons:
+              apt:
+                  sources:
+                      - ubuntu-toolchain-r-test
+                      - sourceline: 'ppa:maarten-fonville/protobuf'
+                  packages:
+                      - gcc-7
+                      - g++-7
+                      - cmake-data
+                      - cmake
+                      - libopencv-dev
+                      - libprotobuf-dev
+                      - protobuf-compiler
+              coverity_scan:
+                  project:
+                      name: "pfnet-research/menoh"
+                      description: "Menoh: DNN inference library"
+                  notification_email: menoh-oss@preferred.jp
+                  build_command_prepend: >-
+                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
+                      cmake .
+                  build_command: make
+                  branch_pattern: coverity_scan
+          before_install:
+              - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+          install:
+              - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
+              - |
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/install-mkldnn.sh \
+                    --version ${MKLDNN_VERSION} \
+                    --download-dir ${HOME}/downloads \
+                    --build-dir ${HOME}/build \
+                    --install-dir /usr/local \
+                    --parallel ${MAKE_JOBS}
+              - pip install --user chainer
+              - |
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/prepare-menoh-data.sh \
+                    --source-dir ${TRAVIS_BUILD_DIR} \
+                    --python-executable python
+          script:
+              #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
+              # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
+              - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
+              - if [ -d "build" ]; then mkdir -p build; fi
+              - cd build
+              - cmake -DENABLE_TEST=ON ..
+              - make
+              - ./test/menoh_test
+              - ldd menoh/libmenoh.so
 
-#before_install:
-#    - |
-#      if [ "$TRAVIS_OS_NAME" = "linux" ]; then
-#        echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
-#      fi
 script:
     - |
       echo "travis_fold:start:run-build.sh"
diff --git a/.travis/README.md b/.travis/README.md
index 95992cd..5f0d845 100644
--- a/.travis/README.md
+++ b/.travis/README.md
@@ -1,7 +1,7 @@
 # Build scripts for Travis
 
 ## Prerequisites
-It requires a container image with the following softwares:
+Linux-based platforms requires a container image with the following softwares:
 
 - GCC 5.2 or later
 - CMake 3.1 or later
@@ -14,10 +14,11 @@ Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/)
 ## Architecture
 `.travis.yml` -> `run-build.sh` -> `build.sh` -> `install-*.sh` & `build-menoh.sh`
 
-1. `run-build.sh` starts a Docker container for building the project
+1. `run-build.sh` calls `build.sh` at once for running the actual build workflow
+    - It runs a Docker container before calling `build.sh` if it is in the Linux-based platforms
     - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
-2. `build.sh` runs a build workflow *in the container*
-    - (All commands are run by `docker_exec` and `docker_exec_cmd` functions)
+2. `build.sh`
+    - In Linux, the build workflow is run *in the container*. All commands are run by `docker_exec` and `docker_exec_cmd` functions
     - Install the prerequisites
     - Run a build
     - Run a test
diff --git a/.travis/build-menoh.sh b/.travis/build-menoh.sh
index c426789..35fcf1c 100644
--- a/.travis/build-menoh.sh
+++ b/.travis/build-menoh.sh
@@ -39,7 +39,7 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified"; exit 1; }
+test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified" 1>&2; exit 1; }
 
 test -n "${ARG_LINK_STATIC_LIBGCC}" || ARG_LINK_STATIC_LIBGCC='OFF'
 test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || ARG_LINK_STATIC_LIBSTDCXX='OFF'
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index f80e2ea..b2fe7c1 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -1,8 +1,8 @@
 # check if variables are set
-test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID does not exist"; exit 1; }
-test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION does not exist"; exit 1; }
-test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION does not exist"; exit 1; }
-test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist"; exit 1; }
+test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID does not exist" 1>&2; exit 1; }
+test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION does not exist" 1>&2; exit 1; }
+test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION does not exist" 1>&2; exit 1; }
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist" 1>&2; exit 1; }
 
 test -n "${LINK_STATIC}" || LINK_STATIC=false
 
@@ -43,19 +43,13 @@ function install_mkldnn() {
 }
 
 function prepare_menoh_data() {
-    echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
-    docker_exec "$(cat << EOS
-        cd ${PROJ_DIR} && \
-        ([ -d "data" ] || mkdir -p data) && \
-        python3 retrieve_data.py && \
-        python3 gen_test_data.py
-EOS
-)"
+    docker_exec_cmd \
+        ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
+            --source-dir ${PROJ_DIR} \
+            --python-executable python3
 }
 
 function build_menoh() {
-    # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
-    docker_exec "if [ -f \"CMakeCache.txt\" ]; then cd ${PROJ_DIR} && rm CMakeCache.txt; fi"
     if [ "${LINK_STATIC}" != "true" ]; then
         docker_exec_cmd \
             ${PROJ_DIR}/.travis/build-menoh.sh \
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index e0bdf23..619f119 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -1,18 +1,14 @@
 # check if variables are set
-test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist"; exit 1; }
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist" 1>&2; exit 1; }
 
 # TODO: make them configurable for outside Travis
 export WORK_DIR=${HOME}
 export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 
 function prepare_menoh_data() {
-    echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
-
-    cd ${PROJ_DIR}
-    [ -d "data" ] || mkdir -p data
-
-    python retrieve_data.py
-    python gen_test_data.py
+    bash -ex ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
+        --source-dir ${PROJ_DIR} \
+        --python-executable python
 }
 
 function build_menoh() {
diff --git a/.travis/install-mkldnn.sh b/.travis/install-mkldnn.sh
index a1ad2be..cb797e8 100644
--- a/.travis/install-mkldnn.sh
+++ b/.travis/install-mkldnn.sh
@@ -39,10 +39,10 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified"; exit 1; }
-test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified"; exit 1; }
-test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified"; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified"; exit 1; }
+test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
 
 # download (if it isn't cached)
diff --git a/.travis/install-protobuf.sh b/.travis/install-protobuf.sh
index 7ea2d84..f3b4fd5 100644
--- a/.travis/install-protobuf.sh
+++ b/.travis/install-protobuf.sh
@@ -39,10 +39,10 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified"; exit 1; }
-test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified"; exit 1; }
-test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified"; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified"; exit 1; }
+test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
 
 # download (if it isn't cached)
diff --git a/.travis/prepare-menoh-data.sh b/.travis/prepare-menoh-data.sh
new file mode 100644
index 0000000..fa19dba
--- /dev/null
+++ b/.travis/prepare-menoh-data.sh
@@ -0,0 +1,39 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --source-dir)
+            ARG_SOURCE_DIR="$2"
+            shift 2
+            ;;
+        --python-executable)
+            ARG_PYTHON_EXECUTABLE="$2"
+            shift 2
+            ;;
+        -*)
+            err Unknown option \"$1\"
+            exit
+            ;;
+        *)
+            break
+            ;;
+
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_SOURCE_DIR}" || { echo "ARG_SOURCE_DIR does not exist" 1>&2; exit 1; }
+test -n "${ARG_PYTHON_EXECUTABLE}" || ARG_PYTHON_EXECUTABLE=python
+
+echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
+
+cd ${ARG_SOURCE_DIR}
+[ -d "data" ] || mkdir -p data
+
+${ARG_PYTHON_EXECUTABLE} retrieve_data.py
+${ARG_PYTHON_EXECUTABLE} gen_test_data.py
diff --git a/.travis/run-build.sh b/.travis/run-build.sh
index 4355659..84b5d21 100644
--- a/.travis/run-build.sh
+++ b/.travis/run-build.sh
@@ -1,13 +1,13 @@
 #!/bin/bash
 
 # check if variables have values
-test -n "${PLATFORM}" || { echo "PLATFORM does not exist"; exit 1; }
+test -n "${PLATFORM}" || { echo "PLATFORM does not exist" 1>&2; exit 1; }
 
 export PLATFORM_DIR=${TRAVIS_BUILD_DIR}/.travis/${PLATFORM}
 
 # "$TRAVIS_OS_NAME" == "linux"
 if [[ "$PLATFORM" == "linux-x86" ]] || [[ "$PLATFORM" == "linux-x86_64" ]] || [[ "$PLATFORM" =~ android ]]; then
-    test -n "${BUILDENV_IMAGE}" || { echo "BUILDENV_IMAGE does not exist"; exit 1; }
+    test -n "${BUILDENV_IMAGE}" || { echo "BUILDENV_IMAGE does not exist" 1>&2; exit 1; }
 
     docker pull ${BUILDENV_IMAGE} || true
 
@@ -22,7 +22,7 @@ if [[ "$PLATFORM" == "linux-x86" ]] || [[ "$PLATFORM" == "linux-x86_64" ]] || [[
     # See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
 
     if [ -z "${DOCKER_CONTAINER_ID}" ]; then
-        echo 'Failed to run a Docker container: '${BUILDENV_IMAGE}
+        echo 'Failed to run a Docker container: '${BUILDENV_IMAGE} 1>&2
         exit 1
     fi
 

From 23e805111d83097d53a8428a1f27e3f68632466e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:49:15 +0900
Subject: [PATCH 103/321] add mkldnn_with_generic_fallback_backend

---
 menoh/mkldnn/utility.cpp                      |  16 +++
 menoh/mkldnn/utility.hpp                      |   4 +
 .../computation_node_factory.hpp              |  27 +++++
 .../mkldnn_with_generic_fallback/context.hpp  |  67 +++++++++++
 .../model_core.cpp                            | 104 ++++++++++++++++++
 .../model_core.hpp                            |  42 +++++++
 .../procedure.hpp                             |  12 ++
 menoh/optional.hpp                            |   1 +
 8 files changed, 273 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/context.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/model_core.cpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/model_core.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/procedure.hpp

diff --git a/menoh/mkldnn/utility.cpp b/menoh/mkldnn/utility.cpp
index 50fb55d..7393996 100644
--- a/menoh/mkldnn/utility.cpp
+++ b/menoh/mkldnn/utility.cpp
@@ -22,6 +22,15 @@ namespace menoh_impl {
             throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
         }
 
+        dtype_t mkldnn_memory_data_type_to_dtype(
+          mkldnn::memory::data_type mem_data_type) {
+            if(mem_data_type == mkldnn::memory::data_type::f32) {
+                return dtype_t::float_;
+            }
+            throw invalid_dtype(
+              std::to_string(static_cast<int>(mem_data_type)));
+        }
+
         mkldnn::memory array_to_memory(array const& arr,
                                        std::vector<int> const& dims,
                                        mkldnn::memory::format format,
@@ -38,5 +47,12 @@ namespace menoh_impl {
             return array_to_memory(arr, arr.dims(), format, engine);
         }
 
+        array memory_to_array(mkldnn::memory const& mem) {
+            return array(mkldnn_memory_data_type_to_dtype(
+                           static_cast<mkldnn::memory::data_type>(
+                             mem.get_primitive_desc().desc().data.data_type)),
+                         extract_dims(mem), mem.get_data_handle());
+        }
+
     } // namespace mkldnn_backend
 } // namespace menoh_impl
diff --git a/menoh/mkldnn/utility.hpp b/menoh/mkldnn/utility.hpp
index e2d91bc..8cb057f 100644
--- a/menoh/mkldnn/utility.hpp
+++ b/menoh/mkldnn/utility.hpp
@@ -21,6 +21,8 @@ namespace menoh_impl {
 
         mkldnn::memory::data_type
         dtype_to_mkldnn_memory_data_type(dtype_t dtype);
+        dtype_t mkldnn_memory_data_type_to_dtype(
+          mkldnn::memory::data_type mem_data_type);
 
         mkldnn::memory array_to_memory(array const& arr,
                                        std::vector<int> const& dims,
@@ -31,6 +33,8 @@ namespace menoh_impl {
                                        mkldnn::memory::format format,
                                        mkldnn::engine const& engine);
 
+        array memory_to_array(mkldnn::memory const& mem);
+
     } // namespace mkldnn_backend
 } // namespace menoh_impl
 
diff --git a/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp b/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp
new file mode 100644
index 0000000..3cf8bae
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp
@@ -0,0 +1,27 @@
+#ifndef MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
+#define MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
+
+#include <functional>
+#include <memory>
+#include <tuple>
+#include <unordered_map>
+#include <vector>
+
+#include <menoh/array.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback {
+
+        using computation_node_factory_return_type =
+          std::tuple<std::function<void()>,
+                     std::vector<std::pair<std::string, array>>>;
+
+        using computation_node_factory =
+          std::function<computation_node_factory_return_type(
+            int32_t, std::vector<node> const&,
+            std::unordered_map<std::string, array> const&)>;
+
+    } // namespace mkldnn_with_generic_fallback
+} // namespace menoh_impl
+
+#endif // MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/context.hpp b/menoh/mkldnn_with_generic_fallback/context.hpp
new file mode 100644
index 0000000..76997e8
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/context.hpp
@@ -0,0 +1,67 @@
+#ifndef MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
+#define MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
+
+#include <menoh/any.hpp>
+#include <menoh/array.hpp>
+#include <menoh/node.hpp>
+#include <menoh/optional.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+
+        class context {
+        public:
+            optional<std::tuple<procedure, array>>
+            try_to_get_variable(std::string const& name) {
+                return do_try_to_get_variable(name);
+            }
+
+            optional<std::tuple<std::vector<procedure>, int>> process_node_list(
+              std::string const& context_name, int current_index,
+              std::vector<node> const& node_list,
+              std::unordered_map<std::string, array> const&
+                common_parameter_table,
+              std::unordered_map<std::string, array> const& common_input_table,
+              std::unordered_map<std::string, array> const&
+                required_output_table,
+              std::vector<
+                std::pair<std::string, std::unique_ptr<context>>> const&
+                context_list) {
+                return do_process_node_list(
+                  context_name, current_index, node_list,
+                  common_parameter_table, common_input_table,
+                  required_output_table, context_list);
+            }
+
+            // for specialized optimization across backends
+            any take_variable_handle(std::string const& name) {
+                return do_take_variable_handle(name);
+            }
+
+        private:
+            virtual optional<std::tuple<procedure, array>>
+            do_try_to_get_variable(std::string const& name) = 0;
+
+            virtual optional<std::tuple<std::vector<procedure>, int>>
+            do_process_node_list(
+              std::string const& context_name, int current_index,
+              std::vector<node> const& node_list,
+              std::unordered_map<std::string, array> const&
+                common_parameter_table,
+              std::unordered_map<std::string, array> const& common_input_table,
+              std::unordered_map<std::string, array> const&
+                required_output_table,
+              std::vector<
+                std::pair<std::string, std::unique_ptr<context>>> const&
+                context_list) = 0;
+
+            // for specialized optimization across backends
+            virtual any do_take_variable_handle(std::string const& name) = 0;
+        };
+
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
new file mode 100644
index 0000000..e773cd7
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -0,0 +1,104 @@
+#include <menoh/mkldnn_with_generic_fallback/model_core.hpp>
+
+#include <algorithm>
+#include <cassert>
+#include <memory>
+
+#include <menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp>
+#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+
+#include <menoh/mkldnn/utility.hpp>
+
+#include <menoh/optional.hpp>
+#include <menoh/utility.hpp>
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+
+        model_core::model_core(
+          std::vector<std::pair<std::string, std::unique_ptr<context>>>
+            context_list,
+          std::unordered_map<std::string, array> const& input_table,
+          std::unordered_map<std::string, array> const& output_table,
+          menoh_impl::model_data const& model_data)
+          : menoh_impl::model_core(),
+            common_parameter_table_(
+              model_data.parameter_name_and_array_list.begin(),
+              model_data.parameter_name_and_array_list.end()),
+            common_input_table_(input_table.begin(), input_table.end()),
+            required_output_table_(output_table.begin(), output_table.end()),
+            context_list_(std::move(context_list)) {
+
+            auto graph = make_graph(model_data.node_list);
+
+            for(decltype(graph.node_list().size()) current_index = 0;
+                current_index < graph.node_list().size();) {
+                auto const& node = graph.node_list().at(current_index);
+                std::cout << "node: " << node.op_type << std::endl;
+                std::cout << context_list_.size() << std::endl;
+
+                // for each backend
+                bool is_found = false;
+                for(auto const& context_pair : context_list_) {
+                    std::cout << "context: " << context_pair.first << std::endl;
+                    auto const& context_name = context_pair.first;
+                    auto context = context_pair.second.get();
+
+                    // try to process nodes
+                    optional<std::tuple<std::vector<procedure>, int>> result =
+                      context->process_node_list(
+                        context_name, current_index, graph.node_list(),
+                        common_parameter_table_, common_input_table_,
+                        required_output_table_, context_list_);
+
+                    // if succeeded processing, add procedures into
+                    // procedure_list
+                    if(result) {
+                        std::cout << "consumed "
+                                  << std::get<1>(*result) - current_index
+                                  << " nodes" << std::endl;
+                        /*
+                        std::cout << "find op "
+                                  << graph.node_list().at(current_index).op_type
+                                  << " in " << context_pair.first << std::endl;
+                        */
+                        std::vector<procedure> additional_procedure_list;
+                        std::tie(additional_procedure_list, current_index) =
+                          *result;
+                        procedure_list_.insert(
+                          procedure_list_.end(),
+                          std::make_move_iterator(
+                            additional_procedure_list.begin()),
+                          std::make_move_iterator(
+                            additional_procedure_list.end()));
+                        is_found = true;
+                        break;
+                    } else {
+                        std::cout << "failed to find op "
+                                  << graph.node_list().at(current_index).op_type
+                                  << " in " << context_pair.first << std::endl;
+                    }
+                }
+                // if any context can not process the node
+                if(!is_found) {
+                    throw unsupported_operator(node.op_type);
+                }
+            }
+
+            // erase useless procedures
+            auto end_iter = std::remove_if(
+              procedure_list_.begin(), procedure_list_.end(),
+              [](auto const& e) { return !static_cast<bool>(e); });
+            procedure_list_.erase(end_iter, procedure_list_.end());
+        }
+
+        void model_core::do_run() {
+            for(auto const& procedure : procedure_list_) {
+                procedure.operator()();
+            }
+        }
+
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.hpp b/menoh/mkldnn_with_generic_fallback/model_core.hpp
new file mode 100644
index 0000000..43d4b61
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/model_core.hpp
@@ -0,0 +1,42 @@
+#ifndef MENOH_MKLDNN_WITH_FALLBACK_MODEL_CORE_HPP
+#define MENOH_MKLDNN_WITH_FALLBACK_MODEL_CORE_HPP
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include <menoh/array.hpp>
+#include <menoh/model_core.hpp>
+#include <menoh/model_data.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+
+        class model_core final : public menoh_impl::model_core {
+        public:
+            model_core(
+              std::vector<std::pair<std::string, std::unique_ptr<context>>>
+                context_list,
+              std::unordered_map<std::string, array> const& input_table,
+              std::unordered_map<std::string, array> const& output_table,
+              menoh_impl::model_data const& model_data);
+
+        private:
+            virtual void do_run() override;
+
+            std::unordered_map<std::string, array> common_parameter_table_;
+            std::unordered_map<std::string, array> common_input_table_;
+            std::unordered_map<std::string, array> required_output_table_;
+            std::vector<std::pair<std::string, std::unique_ptr<context>>>
+              context_list_;
+
+            std::vector<procedure> procedure_list_;
+        };
+
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_MKLDNN_WITH_FALLBACK_MODEL_CORE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/procedure.hpp b/menoh/mkldnn_with_generic_fallback/procedure.hpp
new file mode 100644
index 0000000..ae6c94d
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/procedure.hpp
@@ -0,0 +1,12 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
+#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
+
+#include <functional>
+
+namespace menoh_impl {
+namespace mkldnn_with_generic_fallback_backend {
+    using procedure = std::function<void()>;
+} // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
diff --git a/menoh/optional.hpp b/menoh/optional.hpp
index 44171f4..2f71a86 100644
--- a/menoh/optional.hpp
+++ b/menoh/optional.hpp
@@ -5,6 +5,7 @@
 
 namespace menoh_impl {
     using nonstd::optional;
+    using nonstd::nullopt;
 } // namespace menoh_impl
 
 #endif // MENOH_OPTIONAL_HPP

From a98a4e1309b936e52d9eac41134eea94485d7172 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:50:29 +0900
Subject: [PATCH 104/321] add test

---
 test/CMakeLists.txt                           |   1 +
 test/mkldnn_with_generic_fallback_backend.cpp | 122 ++++++++++++++++++
 2 files changed, 123 insertions(+)
 create mode 100644 test/mkldnn_with_generic_fallback_backend.cpp

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index aa5b4f4..d920bce 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,6 +8,7 @@ add_executable(menoh_test
 
     operator.cpp
     model.cpp
+    mkldnn_with_generic_fallback_backend.cpp
     model_data.cpp
     #vgg16.cpp
 
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
new file mode 100644
index 0000000..1cb5edc
--- /dev/null
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -0,0 +1,122 @@
+#include <gtest/gtest.h>
+
+#include "backend.hpp"
+
+namespace menoh {
+    class MultiContextBackendTest : public ::testing::Test {
+    protected:
+        MultiContextBackendTest() = default;
+        virtual void SetUp() {}
+    };
+    /*
+    TEST_F(MultiContextBackendTest, gemm_1d_test) {
+        gemm_test("mkldnn_with_fallback", "", "../data/random_input_3_4096.txt",
+                  "../data/random_weight_256_4096.txt",
+                  "../data/random_bias_256.txt",
+                  "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
+    }
+    TEST_F(MultiContextBackendTest, gemm_2d_test) {
+        gemm_test(
+          "mkldnn_with_fallback", "", "../data/random_input_3_4_32_32.txt",
+          "../data/random_weight_256_4096.txt", "../data/random_bias_256.txt",
+          "../data/linear_2d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
+    }
+    */
+
+    TEST_F(MultiContextBackendTest, gemm_1d_relu_test) {
+        std::string backend_name = "mkldnn_with_fallback";
+        std::string backend_config = "";
+        menoh::model_data model_data;
+        menoh::variable_profile_table_builder vpt_builder;
+        std::pair<std::string, std::string> gemm_true_output_filename = {
+          "gemm_out", "../data/linear_2d_w256_4096_b_256.txt"};
+        std::pair<std::string, std::string> relu_true_output_filename = {
+          "relu_out", "../data/linear_2d_w256_4096_b_256.txt"};
+        float eps = 10.e-4;
+        std::unordered_map<std::string, std::vector<float>> input_table;
+
+        {
+            model_data.add_new_node("Gemm");
+            model_data.add_attribute_int_to_current_node("transB", 1);
+
+            std::vector<std::pair<std::string, std::string>>
+              input_filename_table = {
+                {"input", "../data/random_input_3_4_32_32.txt"},
+                {"weight", "../data/random_weight_256_4096.txt"},
+                {"bias", "../data/random_bias_256.txt"}};
+
+            for(auto const& p : input_filename_table) {
+                std::string input_name;
+                std::string input_filename;
+                std::tie(input_name, input_filename) = p;
+                model_data.add_input_name_to_current_node(input_name);
+                std::vector<int32_t> input_dims;
+                std::vector<float> input_data;
+                std::tie(std::ignore, input_dims, input_data) =
+                  menoh_impl::load_np_array(input_filename);
+                input_table.emplace(input_name, input_data);
+                dtype_t dtype = dtype_t::float_; // TODO other dtype
+                model_data.add_initializer(input_name, dtype, input_dims,
+                                           input_table.at(input_name).data());
+            }
+
+            std::string output_name;
+            std::string output_filename;
+            std::tie(output_name, output_filename) = gemm_true_output_filename;
+            model_data.add_output_name_to_current_node(output_name);
+            dtype_t dtype = dtype_t::float_; // TODO other dtype
+            vpt_builder.add_output_profile(output_name, dtype);
+        }
+
+        {
+            model_data.add_new_node("Relu");
+            model_data.add_input_name_to_current_node("gemm_out");
+            model_data.add_output_name_to_current_node("relu_out");
+            vpt_builder.add_output_profile("relu_out", dtype_t::float_);
+        }
+
+        auto vpt = vpt_builder.build_variable_profile_table(model_data);
+        model_builder model_builder(vpt);
+        auto model =
+          model_builder.build_model(model_data, backend_name, backend_config);
+        model.run();
+
+        {
+            auto output_var = model.get_variable("gemm_out");
+            std::cout << "gemm out " << *static_cast<float*>(output_var.buffer_handle) << std::endl;
+        }
+        {
+            auto output_var = model.get_variable("relu_out");
+            std::cout << "relu out " << *static_cast<float*>(output_var.buffer_handle) << std::endl;
+        }
+
+        std::unordered_map<std::string, std::string> true_output_filename_table{
+          {gemm_true_output_filename, relu_true_output_filename}};
+        for(auto const& p : true_output_filename_table) {
+            auto const& output_name = p.first;
+            std::cout << output_name << std::endl;
+
+            auto const& true_output_filename = p.second;
+            std::vector<int32_t> output_dims;
+            std::vector<float> true_output_data;
+            std::tie(std::ignore, output_dims, true_output_data) =
+              menoh_impl::load_np_array(true_output_filename);
+            dtype_t dtype = dtype_t::float_; // TODO other dtype
+
+            auto output_var = model.get_variable(output_name);
+            menoh_impl::assert_near_list(
+              static_cast<float*>(output_var.buffer_handle),
+              static_cast<float*>(output_var.buffer_handle) +
+                std::accumulate(output_var.dims.begin(), output_var.dims.end(),
+                                1, std::multiplies<>()),
+              true_output_data.begin(), true_output_data.end(), eps);
+        }
+    }
+    /*
+    TEST_F(MultiContextBackendTest, relu_1d_test) {
+        relu_test("mkldnn_with_fallback", "",
+    "../data/random_input_3_4096.txt",
+                  "../data/relu_1d.txt");
+    }
+    */
+} // namespace menoh

From ca3acd046bca8d70cccd73f93fadfe021161accf Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 10:52:06 +0900
Subject: [PATCH 105/321] fix style

---
 menoh/mkldnn/utility.hpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/menoh/mkldnn/utility.hpp b/menoh/mkldnn/utility.hpp
index 8cb057f..2f80350 100644
--- a/menoh/mkldnn/utility.hpp
+++ b/menoh/mkldnn/utility.hpp
@@ -4,9 +4,10 @@
 #include <vector>
 
 // mkldnn.hpp requires including <string>
-// c.f. https://stackoverflow.com/questions/19456626/compile-cln-with-clang-and-libc
-#include <string>
+// c.f.
+// https://stackoverflow.com/questions/19456626/compile-cln-with-clang-and-libc
 #include <mkldnn.hpp>
+#include <string>
 
 #include <menoh/dtype.hpp>
 

From c29501916f63b5df8d6da32696d72631d3f2050d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:31:39 +0900
Subject: [PATCH 106/321] add logger

---
 include/menoh/menoh.h                         |  1 +
 menoh/exception.hpp                           |  7 +++
 .../mkldnn_with_generic_fallback/context.hpp  | 11 +++-
 .../model_core.cpp                            | 58 +++++++++++++------
 .../model_core.hpp                            |  5 +-
 test/mkldnn_with_generic_fallback_backend.cpp | 53 +++++++++--------
 6 files changed, 90 insertions(+), 45 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index be224a2..d561a1b 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -78,6 +78,7 @@ enum menoh_error_code_constant {
     menoh_error_code_unsupported_input_dims,
     menoh_error_code_same_named_parameter_already_exist,
     menoh_error_code_same_named_attribute_already_exist,
+    menoh_error_code_invalid_backend_config_error,
 };
 typedef int32_t menoh_error_code;
 /*! \brief Users can get detailed message about last error.
diff --git a/menoh/exception.hpp b/menoh/exception.hpp
index bddf2cc..65633bd 100644
--- a/menoh/exception.hpp
+++ b/menoh/exception.hpp
@@ -33,6 +33,13 @@ namespace menoh_impl {
                       "menoh json parse error: " + message) {}
     };
 
+    class invalid_backend_config_error : public exception {
+    public:
+        explicit invalid_backend_config_error(std::string const& message)
+          : exception(menoh_error_code_invalid_backend_config_error,
+                      "menoh invalid backend config error: " + message) {}
+    };
+
 } // namespace menoh_impl
 
 #endif // MENOH_EXCEPTION
diff --git a/menoh/mkldnn_with_generic_fallback/context.hpp b/menoh/mkldnn_with_generic_fallback/context.hpp
index 76997e8..f8aafbc 100644
--- a/menoh/mkldnn_with_generic_fallback/context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/context.hpp
@@ -1,11 +1,14 @@
 #ifndef MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
 #define MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
 
+#include <iosfwd>
+
 #include <menoh/any.hpp>
 #include <menoh/array.hpp>
 #include <menoh/node.hpp>
 #include <menoh/optional.hpp>
 
+#include <menoh/mkldnn_with_generic_fallback/logger.hpp>
 #include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
 
 namespace menoh_impl {
@@ -28,11 +31,12 @@ namespace menoh_impl {
                 required_output_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
-                context_list) {
+                context_list,
+              logger_handle logger) {
                 return do_process_node_list(
                   context_name, current_index, node_list,
                   common_parameter_table, common_input_table,
-                  required_output_table, context_list);
+                  required_output_table, context_list, logger);
             }
 
             // for specialized optimization across backends
@@ -55,7 +59,8 @@ namespace menoh_impl {
                 required_output_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
-                context_list) = 0;
+                context_list,
+              logger_handle logger) = 0;
 
             // for specialized optimization across backends
             virtual any do_take_variable_handle(std::string const& name) = 0;
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index e773cd7..e22e9e8 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -9,9 +9,12 @@
 
 #include <menoh/mkldnn/utility.hpp>
 
+#include <menoh/exception.hpp>
+#include <menoh/json.hpp>
 #include <menoh/optional.hpp>
 #include <menoh/utility.hpp>
 
+#include <fstream>
 #include <iostream>
 
 namespace menoh_impl {
@@ -22,27 +25,45 @@ namespace menoh_impl {
             context_list,
           std::unordered_map<std::string, array> const& input_table,
           std::unordered_map<std::string, array> const& output_table,
-          menoh_impl::model_data const& model_data)
+          menoh_impl::model_data const& model_data,
+          backend_config const& config)
           : menoh_impl::model_core(),
             common_parameter_table_(
               model_data.parameter_name_and_array_list.begin(),
               model_data.parameter_name_and_array_list.end()),
             common_input_table_(input_table.begin(), input_table.end()),
             required_output_table_(output_table.begin(), output_table.end()),
-            context_list_(std::move(context_list)) {
+            context_list_(std::move(context_list)),
+            logger_(std::make_unique<std::ostream>(nullptr)) {
+            if(!config.empty()) {
+                auto c = nlohmann::json::parse(config);
+                if(c.find("log_output") != c.end()) {
+                    auto log_output = c["log_output"].get<std::string>();
+                    if(log_output == "stdout") {
+                        logger_->rdbuf(std::cout.rdbuf());
+                    } else if(log_output == "file") {
+                        logger_.reset(new std::ofstream(
+                          "mkldnn_with_generic_fallback_backend_log.txt"));
+                    } else {
+                        throw invalid_backend_config_error(
+                          "invalid value of \"log_output\": " + log_output);
+                    }
+                    *logger_ << "mkldnn_with_generic_fallback_backend log"
+                             << std::endl;
+                }
+            }
 
             auto graph = make_graph(model_data.node_list);
 
             for(decltype(graph.node_list().size()) current_index = 0;
                 current_index < graph.node_list().size();) {
                 auto const& node = graph.node_list().at(current_index);
-                std::cout << "node: " << node.op_type << std::endl;
-                std::cout << context_list_.size() << std::endl;
+                *logger_ << "node: " << node.op_type << std::endl;
 
                 // for each backend
                 bool is_found = false;
                 for(auto const& context_pair : context_list_) {
-                    std::cout << "context: " << context_pair.first << std::endl;
+                    *logger_ << "context: " << context_pair.first << std::endl;
                     auto const& context_name = context_pair.first;
                     auto context = context_pair.second.get();
 
@@ -51,19 +72,17 @@ namespace menoh_impl {
                       context->process_node_list(
                         context_name, current_index, graph.node_list(),
                         common_parameter_table_, common_input_table_,
-                        required_output_table_, context_list_);
+                        required_output_table_, context_list_, logger_.get());
 
                     // if succeeded processing, add procedures into
                     // procedure_list
                     if(result) {
-                        std::cout << "consumed "
-                                  << std::get<1>(*result) - current_index
-                                  << " nodes" << std::endl;
-                        /*
-                        std::cout << "find op "
-                                  << graph.node_list().at(current_index).op_type
-                                  << " in " << context_pair.first << std::endl;
-                        */
+                        *logger_ << "succeeded to interpret ";
+                        for(int i = current_index; i < std::get<1>(*result);
+                            ++i) {
+                            *logger_ << graph.node_list().at(i).op_type << " ";
+                        }
+                        *logger_ << std::endl;
                         std::vector<procedure> additional_procedure_list;
                         std::tie(additional_procedure_list, current_index) =
                           *result;
@@ -76,18 +95,21 @@ namespace menoh_impl {
                         is_found = true;
                         break;
                     } else {
-                        std::cout << "failed to find op "
-                                  << graph.node_list().at(current_index).op_type
-                                  << " in " << context_pair.first << std::endl;
+                        *logger_ << "failed to interpret "
+                                 << graph.node_list().at(current_index).op_type
+                                 << std::endl;
                     }
                 }
                 // if any context can not process the node
                 if(!is_found) {
+                    *logger_ << "failed to interpret"
+                             << graph.node_list().at(current_index).op_type
+                             << "with all context";
                     throw unsupported_operator(node.op_type);
                 }
             }
 
-            // erase useless procedures
+            // delete useless procedures
             auto end_iter = std::remove_if(
               procedure_list_.begin(), procedure_list_.end(),
               [](auto const& e) { return !static_cast<bool>(e); });
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.hpp b/menoh/mkldnn_with_generic_fallback/model_core.hpp
index 43d4b61..e4cc405 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.hpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.hpp
@@ -9,8 +9,10 @@
 #include <menoh/array.hpp>
 #include <menoh/model_core.hpp>
 #include <menoh/model_data.hpp>
+#include <menoh/backend_config.hpp>
 
 #include <menoh/mkldnn_with_generic_fallback/context.hpp>
+#include <menoh/mkldnn_with_generic_fallback/logger.hpp>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
@@ -22,7 +24,7 @@ namespace menoh_impl {
                 context_list,
               std::unordered_map<std::string, array> const& input_table,
               std::unordered_map<std::string, array> const& output_table,
-              menoh_impl::model_data const& model_data);
+              menoh_impl::model_data const& model_data, backend_config const& config);
 
         private:
             virtual void do_run() override;
@@ -32,6 +34,7 @@ namespace menoh_impl {
             std::unordered_map<std::string, array> required_output_table_;
             std::vector<std::pair<std::string, std::unique_ptr<context>>>
               context_list_;
+            logger logger_;
 
             std::vector<procedure> procedure_list_;
         };
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index 1cb5edc..7a2e3ca 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -8,24 +8,25 @@ namespace menoh {
         MultiContextBackendTest() = default;
         virtual void SetUp() {}
     };
-    /*
+
     TEST_F(MultiContextBackendTest, gemm_1d_test) {
-        gemm_test("mkldnn_with_fallback", "", "../data/random_input_3_4096.txt",
-                  "../data/random_weight_256_4096.txt",
-                  "../data/random_bias_256.txt",
-                  "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
-    }
-    TEST_F(MultiContextBackendTest, gemm_2d_test) {
         gemm_test(
-          "mkldnn_with_fallback", "", "../data/random_input_3_4_32_32.txt",
+          "mkldnn_with_generic_fallback", R"({"log_output": "file"})",
+          "../data/random_input_3_4096.txt",
           "../data/random_weight_256_4096.txt", "../data/random_bias_256.txt",
-          "../data/linear_2d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
+          "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
+    }
+    TEST_F(MultiContextBackendTest, gemm_2d_test) {
+        gemm_test("mkldnn_with_generic_fallback", "",
+                  "../data/random_input_3_4_32_32.txt",
+                  "../data/random_weight_256_4096.txt",
+                  "../data/random_bias_256.txt",
+                  "../data/linear_2d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
     }
-    */
 
     TEST_F(MultiContextBackendTest, gemm_1d_relu_test) {
-        std::string backend_name = "mkldnn_with_fallback";
-        std::string backend_config = "";
+        std::string backend_name = "mkldnn_with_generic_fallback";
+        std::string backend_config = R"({"log_output": "file"})";
         menoh::model_data model_data;
         menoh::variable_profile_table_builder vpt_builder;
         std::pair<std::string, std::string> gemm_true_output_filename = {
@@ -56,13 +57,17 @@ namespace menoh {
                   menoh_impl::load_np_array(input_filename);
                 input_table.emplace(input_name, input_data);
                 dtype_t dtype = dtype_t::float_; // TODO other dtype
-                model_data.add_initializer(input_name, dtype, input_dims,
-                                           input_table.at(input_name).data());
+                model_data.add_parameter(input_name, dtype, input_dims,
+                                         input_table.at(input_name).data());
+                if(input_name !=
+                   "bias") { // FIXME bias is 1d so vpt_builder can't take it.
+                    vpt_builder.add_input_profile(input_name, dtype,
+                                                  input_dims);
+                }
             }
 
             std::string output_name;
-            std::string output_filename;
-            std::tie(output_name, output_filename) = gemm_true_output_filename;
+            std::tie(output_name, std::ignore) = gemm_true_output_filename;
             model_data.add_output_name_to_current_node(output_name);
             dtype_t dtype = dtype_t::float_; // TODO other dtype
             vpt_builder.add_output_profile(output_name, dtype);
@@ -83,11 +88,15 @@ namespace menoh {
 
         {
             auto output_var = model.get_variable("gemm_out");
-            std::cout << "gemm out " << *static_cast<float*>(output_var.buffer_handle) << std::endl;
+            std::cout << "gemm out "
+                      << *static_cast<float*>(output_var.buffer_handle)
+                      << std::endl;
         }
         {
             auto output_var = model.get_variable("relu_out");
-            std::cout << "relu out " << *static_cast<float*>(output_var.buffer_handle) << std::endl;
+            std::cout << "relu out "
+                      << *static_cast<float*>(output_var.buffer_handle)
+                      << std::endl;
         }
 
         std::unordered_map<std::string, std::string> true_output_filename_table{
@@ -112,11 +121,9 @@ namespace menoh {
               true_output_data.begin(), true_output_data.end(), eps);
         }
     }
-    /*
+
     TEST_F(MultiContextBackendTest, relu_1d_test) {
-        relu_test("mkldnn_with_fallback", "",
-    "../data/random_input_3_4096.txt",
-                  "../data/relu_1d.txt");
+        relu_test("mkldnn_with_generic_fallback", "",
+                  "../data/random_input_3_4096.txt", "../data/relu_1d.txt");
     }
-    */
 } // namespace menoh

From ebf038997505db21c81ae3bed9f3e92e5c7fb3d1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:31:48 +0900
Subject: [PATCH 107/321] fix to run test

---
 menoh/model_core_factory.cpp | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index 242f790..fd18980 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -2,6 +2,10 @@
 #include <menoh/model_core_factory.hpp>
 
 #include <menoh/mkldnn/model_core.hpp>
+#include <menoh/mkldnn_with_generic_fallback/model_core.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
 
 namespace menoh_impl {
 
@@ -15,7 +19,19 @@ namespace menoh_impl {
             return std::make_unique<mkldnn_backend::model_core>(
               mkldnn_backend::make_model_core(input_table, output_table,
                                               model_data, config));
+        } else if(backend_name == "mkldnn_with_generic_fallback") {
+            using namespace mkldnn_with_generic_fallback_backend;
+            std::vector<std::pair<std::string, std::unique_ptr<context>>>
+              context_list;
+            context_list.emplace_back("mkldnn",
+                                      std::make_unique<mkldnn_context>());
+            context_list.emplace_back("generic",
+                                      std::make_unique<generic_context>());
+            return std::make_unique<
+              mkldnn_with_generic_fallback_backend::model_core>(
+              std::move(context_list), input_table, output_table, model_data, config);
         }
+
         throw invalid_backend_name(backend_name);
     }
 

From aa7a75657879593292130f68943fb49074a279d2 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:32:17 +0900
Subject: [PATCH 108/321] add logger.h

---
 menoh/mkldnn_with_generic_fallback/logger.hpp | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/logger.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/logger.hpp b/menoh/mkldnn_with_generic_fallback/logger.hpp
new file mode 100644
index 0000000..84c642d
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/logger.hpp
@@ -0,0 +1,13 @@
+#ifndef MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
+#define MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        using logger = std::unique_ptr<std::ostream>;
+        using logger_handle = std::ostream*;
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP

From 2dd77a98194e8f10a0da3c50629a973d28580999 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:58:21 +0900
Subject: [PATCH 109/321] add context and operator

---
 .../backend/generic/generic_context.cpp       | 133 +++++++++++++
 .../backend/generic/generic_context.hpp       |  64 +++++++
 .../backend/generic/operator/relu.hpp         |  50 +++++
 .../backend/mkldnn/mkldnn_context.cpp         | 163 ++++++++++++++++
 .../backend/mkldnn/mkldnn_context.hpp         |  75 ++++++++
 .../backend/mkldnn/operator/gemm.hpp          | 181 ++++++++++++++++++
 menoh/model_core_factory.cpp                  |  11 +-
 7 files changed, 673 insertions(+), 4 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
new file mode 100644
index 0000000..daaa539
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -0,0 +1,133 @@
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+
+            generic_context::generic_context() : context() {
+                procedure_factory_table_.emplace("Relu", make_relu);
+            }
+
+            optional<std::function<void()>>
+            generic_context::try_to_get_input_from_common_table(
+              std::string const& input_name,
+              std::unordered_map<std::string, array> const& common_table) {
+                auto found = common_table.find(input_name);
+                if(found != common_table.end()) {
+                    variable_table_.emplace(input_name, found->second);
+                    return std::function<void()>([this, &input_name]() {
+                        variable_table_.erase(input_name);
+                    });
+                }
+                return nullopt;
+            }
+
+            optional<std::tuple<std::vector<procedure>, int>>
+            generic_context::do_process_node_list(
+              std::string const& context_name, int current_index,
+              std::vector<node> const& node_list,
+              std::unordered_map<std::string, array> const&
+                common_parameter_table,
+              std::unordered_map<std::string, array> const& common_input_table,
+              std::unordered_map<std::string, array> const&
+                required_output_table,
+              std::vector<
+                std::pair<std::string, std::unique_ptr<context>>> const&
+                context_list,
+              logger_handle logger) {
+                auto const& node = node_list.at(current_index);
+                std::vector<procedure> procedure_list;
+                std::vector<array> input_list;
+                std::vector<std::function<void()>> rollback_list;
+                for(auto const& input_name : node.input_name_list) {
+                    if(variable_table_.find(input_name) !=
+                       variable_table_.end()) {
+                        *logger << input_name
+                                << " is found in self variable table"
+                                << std::endl;
+                        continue; // when found
+                    }
+                    do {
+                        {
+                            // normally, copy once array here, because
+                            // parameter is statically fixed
+                            auto rollback = try_to_get_input_from_common_table(
+                              input_name, common_parameter_table);
+                            if(rollback) {
+                                *logger << input_name
+                                        << " is found in common parameter table"
+                                        << std::endl;
+                                rollback_list.emplace_back(*rollback);
+                                break;
+                            }
+                        }
+                        {
+                            // normally, allocate buffer for variable and
+                            // issue copy procedure
+                            auto rollback = try_to_get_input_from_common_table(
+                              input_name, common_input_table);
+                            if(rollback) {
+                                *logger << input_name
+                                        << " is found in common input table"
+                                        << std::endl;
+                                rollback_list.emplace_back(*rollback);
+                                break;
+                            }
+                        }
+
+                        // take from other context
+                        bool is_found_from_other_context = false;
+                        for(auto const& context_pair : context_list) {
+                            std::string name = context_pair.first;
+                            context* con = context_pair.second.get();
+                            if(name == context_name) {
+                                continue; // skip self
+                            }
+                            auto found = con->try_to_get_variable(input_name);
+                            if(found) {
+                                *logger << input_name
+                                        << " is found in other context's "
+                                           "varibale table: "
+                                        << context_pair.first << std::endl;
+                                procedure proc;
+                                array arr;
+                                std::tie(proc, arr) = *found;
+                                procedure_list.push_back(proc);
+                                variable_table_.emplace(input_name, arr);
+                                rollback_list.push_back([this, &input_name]() {
+                                    variable_table_.erase(input_name);
+                                });
+                                is_found_from_other_context = true;
+                                break;
+                            }
+                        }
+                        assert(is_found_from_other_context);
+                    } while(false);
+                    assert(variable_table_.find(input_name) !=
+                           variable_table_.end());
+                    input_list.push_back(variable_table_.at(input_name));
+                }
+                procedure proc;
+                std::vector<std::pair<std::string, array>> new_variables;
+                try {
+                    auto factory = procedure_factory_table_.at(node.op_type);
+                    std::tie(proc, new_variables) =
+                      factory.operator()(current_index, node_list, input_list,
+                                         required_output_table);
+                } catch(...) {
+                    for(auto const& rollback : rollback_list) {
+                        rollback(); // remove new inputs
+                    }
+                    return nullopt;
+                }
+                procedure_list.push_back(std::move(proc));
+                variable_table_.insert(
+                  std::make_move_iterator(new_variables.begin()),
+                  std::make_move_iterator(new_variables.end()));
+                return std::make_tuple(procedure_list, current_index + 1);
+            }
+        } // namespace generic_backend
+
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
new file mode 100644
index 0000000..7a1bb2b
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
@@ -0,0 +1,64 @@
+#ifndef MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
+#define MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+
+            class generic_context final : public context {
+            public:
+                generic_context();
+
+            private:
+                virtual optional<std::tuple<procedure, array>>
+                do_try_to_get_variable(std::string const& name) override {
+                    auto varriable_iter = variable_table_.find(name);
+                    if(varriable_iter == variable_table_.end()) {
+                        return nullopt;
+                    }
+                    return std::make_tuple(procedure(nullptr),
+                                           variable_table_.at(name));
+                }
+
+                virtual optional<std::tuple<std::vector<procedure>, int>>
+                do_process_node_list(
+                  std::string const& context_name, int current_index,
+                  std::vector<node> const& node_list,
+                  std::unordered_map<std::string, array> const&
+                    common_parameter_table,
+                  std::unordered_map<std::string, array> const&
+                    common_input_table,
+                  std::unordered_map<std::string, array> const&
+                    required_output_table,
+                  std::vector<
+                    std::pair<std::string, std::unique_ptr<context>>> const&
+                    context_list,
+                  logger_handle logger) override;
+
+                // for specialized optimization across backends
+                virtual any
+                do_take_variable_handle(std::string const& name) override {
+                    return variable_table_.at(name);
+                }
+
+                using procedure_factory = std::function<std::tuple<
+                  procedure, std::vector<std::pair<std::string, array>>>(
+                  int, std::vector<node> const&, std::vector<array> const&,
+                  std::unordered_map<std::string, array> const&)>;
+                optional<std::function<void()>>
+                try_to_get_input_from_common_table(
+                  std::string const& input_name,
+                  std::unordered_map<std::string, array> const& common_table);
+
+                std::unordered_map<std::string, array> variable_table_;
+                std::unordered_map<std::string, procedure_factory>
+                  procedure_factory_table_;
+            };
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
new file mode 100644
index 0000000..092f59e
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
@@ -0,0 +1,50 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+            inline std::tuple<procedure,
+                              std::vector<std::pair<std::string, array>>>
+            make_relu(int node_index, std::vector<node> const& node_list,
+                      std::vector<array> const& input_list,
+                      std::unordered_map<std::string, array> const&
+                        required_output_table) {
+                assert(input_list.size() == 1);
+                auto const& node = node_list.at(node_index);
+
+                auto const& x_arr = input_list.at(0);
+
+                auto found =
+                  required_output_table.find(node.output_name_list.at(0));
+                optional<array> output_opt;
+                if(found == required_output_table.end()) {
+                    output_opt = array(dtype_t::float_,
+                                       x_arr.dims()); // TODO check inplace-able
+                } else {
+                    output_opt =
+                      found->second; // output is required so not inplace-able
+                }
+
+                auto procedure = [x_arr, output = *output_opt]() {
+                    for(decltype(total_size(x_arr)) i = 0;
+                        i < total_size(x_arr); ++i) {
+                        fat(output, i) = std::max(fat(x_arr, i), 0.f);
+                    }
+                };
+
+                std::vector<std::pair<std::string, array>> outputs;
+                if(found == required_output_table.end()) {
+                    outputs.push_back(std::pair<std::string, array>(
+                      node.output_name_list.at(0), *output_opt));
+                }
+                return std::make_tuple(procedure, outputs);
+            }
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
new file mode 100644
index 0000000..f40d0d4
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -0,0 +1,163 @@
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+
+#include <menoh/mkldnn/utility.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            mkldnn_context::mkldnn_context() : context() {
+                procedure_factory_table_.emplace(
+                  "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_gemm);
+            }
+
+            optional<std::tuple<std::vector<procedure>, int>>
+            mkldnn_context::do_process_node_list(
+              std::string const& context_name, int current_index,
+              std::vector<node> const& node_list,
+              std::unordered_map<std::string, array> const&
+                common_parameter_table,
+              std::unordered_map<std::string, array> const& common_input_table,
+              std::unordered_map<std::string, array> const&
+                required_output_table,
+              std::vector<
+                std::pair<std::string, std::unique_ptr<context>>> const&
+                context_list,
+              logger_handle logger) {
+                auto first_node_index = current_index;
+                std::vector<procedure> procedure_list;
+                std::vector<mkldnn::primitive> primitive_list;
+
+                for(; current_index < node_list.size(); ++current_index) {
+                    auto const& node = node_list.at(current_index);
+                    std::vector<array> input_list;
+                    std::vector<procedure> new_copy_procedure_list;
+
+                    for(auto const& input_name : node.input_name_list) {
+                        do {
+                            // search in self variable table
+                            auto found_from_variable_memory_table =
+                              variable_memory_table_.find(input_name);
+                            if(found_from_variable_memory_table !=
+                               variable_memory_table_.end()) {
+                                *logger << input_name
+                                        << " is found in self variable table"
+                                        << std::endl;
+                                input_list.push_back(
+                                  menoh_impl::mkldnn_backend::memory_to_array(
+                                    found_from_variable_memory_table->second));
+                                break;
+                            }
+
+                            // search in common parameter and input table
+                            auto found_from_common_table =
+                              [&](auto const& table) {
+                                  auto found = table.find(input_name);
+                                  if(found != table.end()) {
+                                      assert(found->second.dims().size() == 2 ||
+                                             found->second.dims().size() == 4);
+                                      input_list.push_back(found->second);
+                                      return true;
+                                  }
+                                  return false;
+                              };
+                            if(found_from_common_table(
+                                 common_parameter_table)) {
+                                *logger << input_name
+                                        << " is found in common parameter table"
+                                        << std::endl;
+                                break;
+                            }
+                            if(found_from_common_table(common_input_table)) {
+                                *logger << input_name
+                                        << " is found in common input table"
+                                        << std::endl;
+                                break;
+                            }
+
+                            // search in other contexts' variable table
+                            bool is_found_from_other_context = false;
+                            for(auto const& context_pair : context_list) {
+                                if(context_pair.first == context_name) {
+                                    continue; // skip self
+                                }
+                                auto found =
+                                  context_pair.second->try_to_get_variable(
+                                    input_name);
+                                if(found) {
+                                    *logger << input_name
+                                            << " is found in other context's "
+                                               "varibale table: "
+                                            << context_pair.first << std::endl;
+                                    procedure copy_proc; // copy from other
+                                                         // context to array
+                                    array arr;
+                                    std::tie(copy_proc, arr) = *found;
+                                    assert(arr.dims().size() == 2 ||
+                                           arr.dims().size() == 4);
+                                    new_copy_procedure_list.push_back(
+                                      copy_proc);
+                                    input_list.push_back(arr);
+                                    auto format =
+                                      arr.dims().size() == 2
+                                        ? mkldnn::memory::format::nc
+                                        : mkldnn::memory::format::nchw;
+                                    is_found_from_other_context = true;
+                                    break;
+                                }
+                            }
+                            assert(is_found_from_other_context);
+                        } while(false);
+                    }
+
+                    // make primitives and
+                    std::vector<mkldnn::primitive> new_primitive_list;
+                    std::vector<std::pair<std::string, mkldnn::memory>>
+                      new_output_memory_list;
+                    std::vector<mkldnn::memory> new_temp_memory_list;
+                    try {
+                        auto factory =
+                          procedure_factory_table_.at(node.op_type);
+                        std::tie(new_primitive_list, new_output_memory_list,
+                                 new_temp_memory_list) =
+                          factory.operator()(current_index, node_list,
+                                             input_list, required_output_table,
+                                             engine_);
+                    } catch(...) { break; }
+                    primitive_list.insert(primitive_list.end(),
+                                          new_primitive_list.begin(),
+                                          new_primitive_list.end());
+                    // add copy procedures
+                    procedure_list.insert(
+                      procedure_list.end(),
+                      std::make_move_iterator(new_copy_procedure_list.begin()),
+                      std::make_move_iterator(new_copy_procedure_list.end()));
+
+                    // update context
+                    variable_memory_table_.insert(
+                      std::make_move_iterator(new_output_memory_list.begin()),
+                      std::make_move_iterator(new_output_memory_list.end()));
+                    temp_memory_list_.insert(
+                      temp_memory_list_.end(),
+                      std::make_move_iterator(new_temp_memory_list.begin()),
+                      std::make_move_iterator(new_temp_memory_list.end()));
+                }
+
+                // when any nodes are not processed
+                if(current_index == first_node_index) {
+                    return nullopt;
+                }
+                procedure_list.emplace_back([this, primitive_list]() {
+                    mkldnn::stream(mkldnn::stream::kind::eager)
+                      .submit(primitive_list)
+                      .wait();
+                });
+
+                return std::make_tuple(procedure_list, current_index);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
new file mode 100644
index 0000000..35a44e4
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -0,0 +1,75 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+
+#include <menoh/array.hpp>
+#include <menoh/mkldnn/utility.hpp>
+#include <menoh/model_core.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            class mkldnn_context final : public context {
+            public:
+                mkldnn_context();
+
+            private:
+                virtual optional<std::tuple<procedure, array>>
+                do_try_to_get_variable(std::string const& name) override {
+                    auto found = variable_memory_table_.find(name);
+                    if(found == variable_memory_table_.end()) {
+                        return nullopt;
+                    }
+                    auto dims =
+                      ::menoh_impl::mkldnn_backend::extract_dims(found->second);
+                    return std::make_tuple(
+                      procedure(), array(dtype_t::float_, dims,
+                                         found->second.get_data_handle()));
+                }
+
+                virtual optional<std::tuple<std::vector<procedure>, int>>
+                do_process_node_list(
+                  std::string const& context_name, int current_index,
+                  std::vector<node> const& node_list,
+                  std::unordered_map<std::string, array> const&
+                    common_parameter_table,
+                  std::unordered_map<std::string, array> const&
+                    common_input_table,
+                  std::unordered_map<std::string, array> const&
+                    required_output_table,
+                  std::vector<
+                    std::pair<std::string, std::unique_ptr<context>>> const&
+                    context_list,
+                  logger_handle logger) override;
+
+                // for specialized optimization across backends
+                virtual any
+                do_take_variable_handle(std::string const& name) override {
+                    return variable_memory_table_.at(name);
+                }
+
+                using procedure_factory = std::function<std::tuple<
+                  std::vector<mkldnn::primitive>,
+                  std::vector<std::pair<std::string, mkldnn::memory>>,
+                  std::vector<mkldnn::memory>>(
+                  int, std::vector<node> const&, std::vector<array> const&,
+                  std::unordered_map<std::string, array> const&,
+                  mkldnn::engine const&)>;
+
+                mkldnn::engine engine_{mkldnn::engine::kind::cpu, 0}; // TODO
+                std::unordered_map<std::string, mkldnn::memory>
+                  variable_memory_table_;
+                std::vector<mkldnn::memory> temp_memory_list_;
+                std::unordered_map<std::string, procedure_factory>
+                  procedure_factory_table_;
+            };
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
new file mode 100644
index 0000000..a006d92
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -0,0 +1,181 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<
+              std::vector<mkldnn::primitive>,
+              std::vector<std::pair<std::string, mkldnn::memory>>,
+              std::vector<mkldnn::memory>>
+            make_gemm(int node_index, std::vector<node> const& node_list,
+                      std::vector<array> const& input_list,
+                      std::unordered_map<std::string, array> const&
+                        required_output_table,
+                      mkldnn::engine const& engine) {
+
+                using namespace menoh_impl::mkldnn_backend;
+                std::vector<mkldnn::primitive> primitives;
+                std::unordered_map<std::string, array> output_table;
+                std::vector<mkldnn::memory> temp_memory_list;
+                std::vector<array> owned_array_list;
+
+                auto node = node_list.at(node_index);
+
+                auto alpha = optional_attribute_float(node, "alpha", 1.f);
+                if(alpha != 1) {
+                    throw failed_to_configure_operator(
+                      node.op_type, node.output_name_list.at(0),
+                      "alpha of Gemm must be 1 but given: " +
+                        std::to_string(alpha));
+                }
+                auto beta = optional_attribute_float(node, "beta", 1.f);
+                if(beta != 1) {
+                    throw failed_to_configure_operator(
+                      node.op_type, node.output_name_list.at(0),
+                      "beta of Gemm must be 1 but given: " +
+                        std::to_string(alpha));
+                }
+
+                auto trans_a = optional_attribute_int(node, "transA", 0);
+                if(trans_a) {
+                    throw failed_to_configure_operator(
+                      node.op_type, node.output_name_list.at(0),
+                      "transA of Gemm must be 0 but given: " +
+                        std::to_string(alpha));
+                }
+                auto trans_b = optional_attribute_int(node, "transB", 0);
+                if(!trans_b) {
+                    throw failed_to_configure_operator(
+                      node.op_type, node.output_name_list.at(0),
+                      "transB of Gemm must be 0 but given: " +
+                        std::to_string(alpha));
+                }
+
+                auto input_dims = input_list.at(0).dims();
+                auto input_format =
+                  (input_dims.size() == 2 ? mkldnn::memory::format::nc
+                                          : mkldnn::memory::format::nchw);
+                auto input_memory =
+                  array_to_memory(input_list.at(0), input_format, engine);
+                temp_memory_list.push_back(input_memory);
+
+                auto const& weight_arr = input_list.at(1);
+                auto weight_dims = weight_arr.dims();
+                auto weight_format =
+                  (input_dims.size() == 2 ? mkldnn::memory::format::oi
+                                          : mkldnn::memory::format::oihw);
+                if(weight_format == mkldnn::memory::format::oihw) {
+                    weight_dims = std::vector<int>{weight_dims.front()};
+                    weight_dims.insert(weight_dims.end(),
+                                       input_dims.begin() + 1,
+                                       input_dims.end());
+                }
+                auto weight_memory = array_to_memory(weight_arr, weight_dims,
+                                                     weight_format, engine);
+                temp_memory_list.push_back(weight_memory);
+
+                auto bias_arr = input_list.at(2);
+                auto bias_memory =
+                  array_to_memory(bias_arr, mkldnn::memory::format::x, engine);
+                temp_memory_list.push_back(bias_memory);
+
+                auto bias_dims = input_list.at(2).dims();
+                int output_size = weight_arr.dims()[0];
+                if(output_size != bias_dims[0]) {
+                    throw failed_to_configure_operator(
+                      node.op_type, node.output_name_list.at(0),
+                      "dims[0] of input C must be equal to dims[0] of "
+                      "input B: "
+                      "broadcast is not supported yet");
+                }
+                mkldnn::memory::dims output_dims{input_dims[0], output_size};
+
+                auto const& output_name = node.output_name_list.at(0);
+
+                auto gemm_input_md = mkldnn::memory::desc(
+                  {input_dims}, mkldnn::memory::data_type::f32,
+                  mkldnn::memory::format::any);
+                auto gemm_weight_md = mkldnn::memory::desc(
+                  {weight_dims}, mkldnn::memory::data_type::f32,
+                  mkldnn::memory::format::any);
+                auto gemm_output_md = mkldnn::memory::desc(
+                  {output_dims}, mkldnn::memory::data_type::f32,
+                  mkldnn::memory::format::any);
+
+                mkldnn::inner_product_forward::desc gemm_desc(
+                  mkldnn::prop_kind::forward_inference, gemm_input_md,
+                  gemm_weight_md, bias_memory.get_primitive_desc().desc(),
+                  gemm_output_md);
+                auto gemm_pd = mkldnn::inner_product_forward::primitive_desc(
+                  gemm_desc, engine);
+
+                auto gemm_input_memory = input_memory;
+                if(mkldnn::memory::primitive_desc(
+                     gemm_pd.src_primitive_desc()) !=
+                   input_memory.get_primitive_desc()) {
+                    gemm_input_memory =
+                      mkldnn::memory(gemm_pd.src_primitive_desc());
+                    temp_memory_list.push_back(gemm_input_memory);
+                    primitives.push_back(
+                      mkldnn::reorder(input_memory, gemm_input_memory));
+                }
+
+                auto gemm_weight_memory = weight_memory;
+                if(mkldnn::memory::primitive_desc(
+                     gemm_pd.weights_primitive_desc()) !=
+                   weight_memory.get_primitive_desc()) {
+                    gemm_weight_memory =
+                      mkldnn::memory(gemm_pd.weights_primitive_desc());
+                    temp_memory_list.push_back(gemm_weight_memory);
+                    primitives.push_back(
+                      mkldnn::reorder(weight_memory, gemm_weight_memory));
+                }
+
+                auto output_format = mkldnn::memory::format::nc;
+                std::vector<std::pair<std::string, array>>
+                  output_name_and_arr_list;
+                menoh_impl::optional<mkldnn::memory> output_memory_opt;
+                auto found = required_output_table.find(output_name);
+                if(found != required_output_table.end()) {
+                    std::string name;
+                    array output_array;
+                    std::tie(name, output_array) = *found;
+                    output_memory_opt =
+                      array_to_memory(output_array, output_format, engine);
+                }
+
+                auto output_pd = gemm_pd.dst_primitive_desc();
+                auto op_output_memory =
+                  output_memory_opt.value_or(mkldnn::memory(output_pd));
+                if(output_memory_opt &&
+                   mkldnn::memory::primitive_desc(output_pd) !=
+                     output_memory_opt->get_primitive_desc()) {
+                    op_output_memory = mkldnn::memory(output_pd);
+                    temp_memory_list.push_back(*output_memory_opt);
+                }
+
+                primitives.push_back(mkldnn::inner_product_forward(
+                  gemm_pd, gemm_input_memory, gemm_weight_memory, bias_memory,
+                  op_output_memory));
+
+                if(output_memory_opt &&
+                   op_output_memory != *output_memory_opt) {
+                    primitives.push_back(
+                      mkldnn::reorder(op_output_memory, *output_memory_opt));
+                }
+
+                std::vector<std::pair<std::string, mkldnn::memory>>
+                  output_memory_list;
+                output_memory_list.emplace_back(output_name, op_output_memory);
+
+                return std::make_tuple(primitives, output_memory_list,
+                                       temp_memory_list);
+            }
+
+        } // namespace mkldnn_backend
+    } // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index fd18980..84c08a8 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -23,10 +23,13 @@ namespace menoh_impl {
             using namespace mkldnn_with_generic_fallback_backend;
             std::vector<std::pair<std::string, std::unique_ptr<context>>>
               context_list;
-            context_list.emplace_back("mkldnn",
-                                      std::make_unique<mkldnn_context>());
-            context_list.emplace_back("generic",
-                                      std::make_unique<generic_context>());
+            context_list.emplace_back(
+              "mkldnn", std::make_unique<mkldnn_with_generic_fallback_backend::
+                                           mkldnn_backend::mkldnn_context>());
+            context_list.emplace_back(
+              "generic",
+              std::make_unique<mkldnn_with_generic_fallback_backend::
+                                 generic_backend::generic_context>());
             return std::make_unique<
               mkldnn_with_generic_fallback_backend::model_core>(
               std::move(context_list), input_table, output_table, model_data, config);

From 09cb8903c13a6e3f13bca7ad9ccb00f40556341a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:59:06 +0900
Subject: [PATCH 110/321] fix style

---
 menoh/model_core_factory.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index 84c08a8..9d1a582 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -32,7 +32,8 @@ namespace menoh_impl {
                                  generic_backend::generic_context>());
             return std::make_unique<
               mkldnn_with_generic_fallback_backend::model_core>(
-              std::move(context_list), input_table, output_table, model_data, config);
+              std::move(context_list), input_table, output_table, model_data,
+              config);
         }
 
         throw invalid_backend_name(backend_name);

From 1bbe470c7f1956b6579cee50f4d59a794f32ad64 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 22:59:25 +0900
Subject: [PATCH 111/321] add any

---
 menoh/any.hpp        |  10 +
 menoh/nonstd/any.hpp | 606 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 616 insertions(+)
 create mode 100644 menoh/any.hpp
 create mode 100644 menoh/nonstd/any.hpp

diff --git a/menoh/any.hpp b/menoh/any.hpp
new file mode 100644
index 0000000..f5153c7
--- /dev/null
+++ b/menoh/any.hpp
@@ -0,0 +1,10 @@
+#ifndef MENOH_ANY_HPP
+#define MENOH_ANY_HPP
+
+#include <menoh/nonstd/any.hpp>
+
+namespace menoh_impl {
+    using nonstd::any;
+} // namespace menoh_impl
+
+#endif // MENOH_ANY_HPP
diff --git a/menoh/nonstd/any.hpp b/menoh/nonstd/any.hpp
new file mode 100644
index 0000000..356e42c
--- /dev/null
+++ b/menoh/nonstd/any.hpp
@@ -0,0 +1,606 @@
+//
+// Copyright (c) 2016-2018 Martin Moene
+//
+// https://github.com/martinmoene/any-lite
+//
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#pragma once
+
+#ifndef NONSTD_ANY_LITE_HPP
+#define NONSTD_ANY_LITE_HPP
+
+#define any_lite_MAJOR  0
+#define any_lite_MINOR  1
+#define any_lite_PATCH  0
+
+#define any_lite_VERSION  any_STRINGIFY(any_lite_MAJOR) "." any_STRINGIFY(any_lite_MINOR) "." any_STRINGIFY(any_lite_PATCH)
+
+#define any_STRINGIFY(  x )  any_STRINGIFY_( x )
+#define any_STRINGIFY_( x )  #x
+
+// any-lite configuration:
+
+#define any_ANY_DEFAULT  0
+#define any_ANY_LITE     1
+#define any_ANY_STD      2
+
+#if !defined( any_CONFIG_SELECT_ANY )
+# define any_CONFIG_SELECT_ANY  ( any_HAVE_STD_ANY ? any_ANY_STD : any_ANY_LITE )
+#endif
+
+// C++ language version detection (C++20 is speculative):
+// Note: VC14.0/1900 (VS2015) lacks too much from C++14.
+
+#ifndef   any_CPLUSPLUS
+# ifdef  _MSVC_LANG
+#  define any_CPLUSPLUS  (_MSC_VER == 1900 ? 201103L : _MSVC_LANG )
+# else
+#  define any_CPLUSPLUS  __cplusplus
+# endif
+#endif
+
+#define any_CPP98_OR_GREATER  ( any_CPLUSPLUS >= 199711L )
+#define any_CPP11_OR_GREATER  ( any_CPLUSPLUS >= 201103L )
+#define any_CPP14_OR_GREATER  ( any_CPLUSPLUS >= 201402L )
+#define any_CPP17_OR_GREATER  ( any_CPLUSPLUS >= 201703L )
+#define any_CPP20_OR_GREATER  ( any_CPLUSPLUS >= 202000L )
+
+// use C++17 std::any if available and requested:
+
+#if any_CPP17_OR_GREATER && defined(__has_include ) && __has_include( <any> )
+# define any_HAVE_STD_ANY  1
+#else
+# define any_HAVE_STD_ANY  0
+#endif
+
+#define any_USES_STD_ANY  ( (any_CONFIG_SELECT_ANY == any_ANY_STD) || ((any_CONFIG_SELECT_ANY == any_ANY_DEFAULT) && any_HAVE_STD_ANY) )
+
+// Using std::any:
+
+#if any_USES_STD_ANY
+
+#include <any>
+
+namespace nonstd {
+
+    using std::any;
+    using std::any_cast;
+    using std::make_any;
+    using std::swap;
+    using std::bad_any_cast;
+
+    using std::in_place;
+    using std::in_place_type;
+    using std::in_place_t;
+    using std::in_place_type_t;
+}
+
+#else // C++17 std::any
+
+#include <typeinfo>
+#include <utility>
+
+// Compiler versions:
+//
+// MSVC++ 6.0  _MSC_VER == 1200 (Visual Studio 6.0)
+// MSVC++ 7.0  _MSC_VER == 1300 (Visual Studio .NET 2002)
+// MSVC++ 7.1  _MSC_VER == 1310 (Visual Studio .NET 2003)
+// MSVC++ 8.0  _MSC_VER == 1400 (Visual Studio 2005)
+// MSVC++ 9.0  _MSC_VER == 1500 (Visual Studio 2008)
+// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
+// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
+// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
+// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
+// MSVC++ 14.1 _MSC_VER >= 1910 (Visual Studio 2017)
+
+#if defined( _MSC_VER ) && !defined( __clang__ )
+# define any_COMPILER_MSVC_VERSION  (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) )
+#else
+# define any_COMPILER_MSVC_VERSION  0
+#endif
+
+#define any_COMPILER_VERSION( major, minor, patch )  ( 10 * ( 10 * (major) + (minor) ) + (patch) )
+
+#if defined __clang__
+# define any_COMPILER_CLANG_VERSION  any_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
+#else
+# define any_COMPILER_CLANG_VERSION  0
+#endif
+
+#if defined __GNUC__
+# define any_COMPILER_GNUC_VERSION  any_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
+#else
+# define any_COMPILER_GNUC_VERSION  0
+#endif
+
+// half-open range [lo..hi):
+//#define any_BETWEEN( v, lo, hi ) ( lo <= v && v < hi )
+
+// Presence of language and library features:
+
+#define any_HAVE( feature )  ( any_HAVE_##feature )
+
+#ifdef _HAS_CPP0X
+# define any_HAS_CPP0X  _HAS_CPP0X
+#else
+# define any_HAS_CPP0X  0
+#endif
+
+#define any_CPP11_90   (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 90)
+#define any_CPP11_100  (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 100)
+#define any_CPP11_120  (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 120)
+#define any_CPP11_140  (any_CPP11_OR_GREATER || any_COMPILER_MSVC_VERSION >= 140)
+
+#define any_CPP14_000  (any_CPP14_OR_GREATER)
+#define any_CPP17_000  (any_CPP17_OR_GREATER)
+
+// Presence of C++11 language features:
+
+#define any_HAVE_CONSTEXPR_11           any_CPP11_140
+#define any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG \
+                                        any_CPP11_120
+#define any_HAVE_INITIALIZER_LIST       any_CPP11_120
+#define any_HAVE_NOEXCEPT               any_CPP11_140
+#define any_HAVE_NULLPTR                any_CPP11_100
+#define any_HAVE_TYPE_TRAITS            any_CPP11_90
+#define any_HAVE_STATIC_ASSERT          any_CPP11_100
+#define any_HAVE_ADD_CONST              any_CPP11_90
+#define any_HAVE_REMOVE_REFERENCE       any_CPP11_90
+
+#define any_HAVE_TR1_ADD_CONST          (!! any_COMPILER_GNUC_VERSION )
+#define any_HAVE_TR1_REMOVE_REFERENCE   (!! any_COMPILER_GNUC_VERSION )
+#define any_HAVE_TR1_TYPE_TRAITS        (!! any_COMPILER_GNUC_VERSION )
+
+// Presence of C++14 language features:
+
+#define any_HAVE_CONSTEXPR_14           any_CPP14_000
+
+// Presence of C++17 language features:
+
+#define any_HAVE_NODISCARD              any_CPP17_000
+
+// Presence of C++ library features:
+
+#if any_HAVE_CONSTEXPR_11
+# define any_constexpr constexpr
+#else
+# define any_constexpr /*constexpr*/
+#endif
+
+#if any_HAVE_CONSTEXPR_14
+# define any_constexpr14 constexpr
+#else
+# define any_constexpr14 /*constexpr*/
+#endif
+
+#if any_HAVE_NOEXCEPT
+# define any_noexcept noexcept
+#else
+# define any_noexcept /*noexcept*/
+#endif
+
+#if any_HAVE_NULLPTR
+# define any_nullptr nullptr
+#else
+# define any_nullptr NULL
+#endif
+
+#if any_HAVE_NODISCARD
+# define any_nodiscard [[nodiscard]]
+#else
+# define any_nodiscard /*[[nodiscard]]*/
+#endif
+
+// additional includes:
+
+#if ! any_HAVE_NULLPTR
+# include <cstddef>
+#endif
+
+#if any_HAVE_INITIALIZER_LIST
+# include <initializer_list>
+#endif
+
+#if any_HAVE_TYPE_TRAITS
+# include <type_traits>
+#elif any_HAVE_TR1_TYPE_TRAITS
+# include <tr1/type_traits>
+#endif
+
+//
+// in_place: code duplicated in any-lite, optional-lite, variant-lite:
+//
+
+#if ! defined nonstd_lite_HAVE_IN_PLACE_TYPES
+
+namespace nonstd {
+
+namespace detail {
+
+template< class T >
+struct in_place_type_tag {};
+
+template< std::size_t I >
+struct in_place_index_tag {};
+
+} // namespace detail
+
+struct in_place_t {};
+
+template< class T >
+inline in_place_t in_place( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
+{
+    return in_place_t();
+}
+
+template< std::size_t I >
+inline in_place_t in_place( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() )
+{
+    return in_place_t();
+}
+
+template< class T >
+inline in_place_t in_place_type( detail::in_place_type_tag<T> = detail::in_place_type_tag<T>() )
+{
+    return in_place_t();
+}
+
+template< std::size_t I >
+inline in_place_t in_place_index( detail::in_place_index_tag<I> = detail::in_place_index_tag<I>() )
+{
+    return in_place_t();
+}
+
+// mimic templated typedef:
+
+#define nonstd_lite_in_place_type_t( T)  nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag<T>  )
+#define nonstd_lite_in_place_index_t(T)  nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag<I> )
+
+#define nonstd_lite_HAVE_IN_PLACE_TYPES  1
+
+} // namespace nonstd
+
+#endif // nonstd_lite_HAVE_IN_PLACE_TYPES
+
+//
+// any:
+//
+
+namespace nonstd {  namespace any_lite {
+
+namespace detail {
+
+// C++11 emulation:
+
+#if any_HAVE_ADD_CONST
+
+using std::add_const;
+
+#elif any_HAVE_TR1_ADD_CONST
+
+using std::tr1::add_const;
+
+#else
+
+template< class T > struct add_const { typedef const T type; };
+
+#endif // any_HAVE_ADD_CONST
+
+#if any_HAVE_REMOVE_REFERENCE
+
+using std::remove_reference;
+
+#elif any_HAVE_TR1_REMOVE_REFERENCE
+
+using std::tr1::remove_reference;
+
+#else
+
+template< class T > struct remove_reference     { typedef T type; };
+template< class T > struct remove_reference<T&> { typedef T type; };
+
+#endif // any_HAVE_REMOVE_REFERENCE
+
+} // namespace detail
+
+class bad_any_cast : public std::bad_cast
+{
+public:
+#if any_CPP11_OR_GREATER
+    virtual const char* what() const any_noexcept
+#else
+    virtual const char* what() const throw()
+#endif
+   {
+      return "any-lite: bad any_cast";
+   }
+};
+
+class any
+{
+public:
+    any_constexpr any() any_noexcept
+    : content( any_nullptr )
+    {}
+
+    any( any const & rhs )
+    : content( rhs.content ? rhs.content->clone() : any_nullptr )
+    {}
+
+#if any_CPP11_OR_GREATER
+
+    any( any && rhs ) any_noexcept
+    : content( std::move( rhs.content ) )
+    {
+        rhs.content = any_nullptr;
+    }
+
+    template<
+        class ValueType, class T = typename std::decay<ValueType>::type
+        , typename = typename std::enable_if< ! std::is_same<T, any>::value >::type
+    >
+    any( ValueType && value ) any_noexcept
+    : content( new holder<T>( std::move( value ) ) )
+    {}
+
+    template<
+        class T, class... Args
+        , typename = typename std::enable_if< std::is_constructible<T, Args...>::value >::type
+    >
+    explicit any( nonstd_lite_in_place_type_t(T), Args&&... args )
+    : content( new holder<T>( T( std::forward<Args>(args)... ) ) )
+    {}
+
+    template<
+        class T, class U, class... Args
+        , typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type
+    >
+    explicit any( nonstd_lite_in_place_type_t(T), std::initializer_list<U> il, Args&&... args )
+    : content( new holder<T>( T( il, std::forward<Args>(args)... ) ) )
+    {}
+
+#else
+
+    template< class ValueType >
+    any( ValueType const & value )
+    : content( new holder<ValueType>( value ) )
+    {}
+
+#endif // any_CPP11_OR_GREATER
+
+    ~any()
+    {
+        reset();
+    }
+
+    any & operator=( any const & rhs )
+    {
+        any( rhs ).swap( *this );
+        return *this;
+    }
+
+#if any_CPP11_OR_GREATER
+
+    any & operator=( any && rhs ) any_noexcept
+    {
+        any( std::move( rhs ) ).swap( *this );
+        return *this;
+    }
+
+    template<
+        class ValueType, class T = typename std::decay<ValueType>::type
+        , typename = typename std::enable_if< ! std::is_same<T, any>::value >::type
+    >
+    any & operator=( ValueType && rhs )
+    {
+        any( std::move( rhs ) ).swap( *this );
+        return *this;
+    }
+
+    template< class T, class... Args >
+    void emplace( Args && ... args )
+    {
+        any( T( std::forward<Args>(args)... ) ).swap( *this );
+    }
+
+    template<
+        class T, class U, class... Args
+        , typename = typename std::enable_if< std::is_constructible<T, std::initializer_list<U>&, Args...>::value >::type
+    >
+    void emplace( std::initializer_list<U> il, Args&&... args )
+    {
+        any( T( il, std::forward<Args>(args)... ) ).swap( *this );
+    }
+
+#else
+
+    template< class ValueType >
+    any & operator=( ValueType const & rhs )
+    {
+        any( rhs ).swap( *this );
+        return *this;
+    }
+
+#endif // any_CPP11_OR_GREATER
+
+    void reset() any_noexcept
+    {
+        delete content; content = any_nullptr;
+    }
+
+    void swap( any & rhs ) any_noexcept
+    {
+        std::swap( content, rhs.content );
+    }
+
+    bool has_value() const any_noexcept
+    {
+        return content != any_nullptr;
+    }
+
+    const std::type_info & type() const any_noexcept
+    {
+        return has_value() ? content->type() : typeid( void );
+    }
+
+    //
+    // non-standard:
+    //
+
+    template< class ValueType >
+    const ValueType * to_ptr() const
+    {
+        return &( static_cast<holder<ValueType> *>( content )->held );
+    }
+
+    template< class ValueType >
+    ValueType * to_ptr()
+    {
+        return &( static_cast<holder<ValueType> *>( content )->held );
+    }
+
+private:
+    class placeholder
+    {
+    public:
+        virtual ~placeholder()
+        {
+        }
+
+        virtual std::type_info const & type() const = 0;
+
+        virtual placeholder * clone() const = 0;
+    };
+
+    template< typename ValueType >
+    class holder : public placeholder
+    {
+    public:
+        holder( ValueType const & value )
+        : held( value )
+        {}
+
+#if any_CPP11_OR_GREATER
+        holder( ValueType && value )
+        : held( std::move( value ) )
+        {}
+#endif
+
+        virtual std::type_info const & type() const
+        {
+            return typeid( ValueType );
+        }
+
+        virtual placeholder * clone() const
+        {
+            return new holder( held );
+        }
+
+        ValueType held;
+    };
+
+    placeholder * content;
+};
+
+inline void swap( any & x, any & y ) any_noexcept
+{
+    x.swap( y );
+}
+
+#if any_CPP11_OR_GREATER
+
+template< class T, class ...Args >
+inline any make_any( Args&& ...args )
+{
+    return any( in_place<T>, std::forward<Args>(args)...);
+}
+
+template< class T, class U, class ...Args >
+inline any make_any( std::initializer_list<U> il, Args&& ...args )
+{
+    return any( in_place<T>, il, std::forward<Args>(args)...);
+}
+
+#endif // any_CPP11_OR_GREATER
+
+template<
+    class ValueType
+#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
+    , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+#endif
+>
+any_nodiscard inline ValueType any_cast( any const & operand )
+{
+   const ValueType * result = any_cast< typename detail::add_const< typename detail::remove_reference<ValueType>::type >::type >( &operand );
+
+   if ( ! result )
+   {
+      throw bad_any_cast();
+   }
+
+   return *result;
+}
+
+template<
+    class ValueType
+#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
+    , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+#endif
+>
+any_nodiscard inline ValueType any_cast( any & operand )
+{
+   const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
+
+   if ( ! result )
+   {
+      throw bad_any_cast();
+   }
+
+   return *result;
+}
+
+#if any_CPP11_OR_GREATER
+
+template<
+    class ValueType
+#if any_HAVE_DEFAULT_FUNCTION_TEMPLATE_ARG
+    , typename = typename std::enable_if< std::is_reference<ValueType>::value || std::is_copy_constructible<ValueType>::value >::type
+#endif
+>
+any_nodiscard inline ValueType any_cast( any && operand )
+{
+   const ValueType * result = any_cast< typename detail::remove_reference<ValueType>::type >( &operand );
+
+   if ( ! result )
+   {
+      throw bad_any_cast();
+   }
+
+   return *result;
+}
+
+#endif // any_CPP11_OR_GREATER
+
+template< class ValueType >
+any_nodiscard inline ValueType const * any_cast( any const * operand ) any_noexcept
+{
+    return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
+}
+
+template<class ValueType >
+any_nodiscard inline ValueType * any_cast( any * operand ) any_noexcept
+{
+    return operand != any_nullptr && operand->type() == typeid(ValueType) ? operand->to_ptr<ValueType>() : any_nullptr;
+}
+
+} // namespace any_lite
+
+using namespace any_lite;
+
+} // namespace nonstd
+
+#endif // have C++17 std::any
+
+#endif // NONSTD_ANY_LITE_HPP

From d3f4b09dc6d44b1cd227a418b6ed4fa7f5706029 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 23:03:39 +0900
Subject: [PATCH 112/321] add operator.hpp

---
 .../backend/generic/generic_context.cpp                     | 2 +-
 .../backend/generic/operator.hpp                            | 6 ++++++
 .../backend/mkldnn/mkldnn_context.cpp                       | 2 +-
 .../backend/mkldnn/operator.hpp                             | 6 ++++++
 4 files changed, 14 insertions(+), 2 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index daaa539..13e17d7 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -1,5 +1,5 @@
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
new file mode 100644
index 0000000..56a8e40
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
@@ -0,0 +1,6 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f40d0d4..60b665d 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -1,5 +1,5 @@
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp>
 
 #include <menoh/mkldnn/utility.hpp>
 
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
new file mode 100644
index 0000000..db71fad
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -0,0 +1,6 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP

From 882e191ff15c482a1c632aee9089ba058df048b4 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 23:28:07 +0900
Subject: [PATCH 113/321] rename test

---
 test/mkldnn_with_generic_fallback_backend.cpp | 20 +++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index 7a2e3ca..cad6d86 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -3,30 +3,30 @@
 #include "backend.hpp"
 
 namespace menoh {
-    class MultiContextBackendTest : public ::testing::Test {
+    class MkldnnWithGenericFallbackBackendTest : public ::testing::Test {
     protected:
-        MultiContextBackendTest() = default;
+        MkldnnWithGenericFallbackBackendTest() = default;
         virtual void SetUp() {}
     };
 
-    TEST_F(MultiContextBackendTest, gemm_1d_test) {
+    TEST_F(MkldnnWithGenericFallbackBackendTest, gemm_1d_test) {
         gemm_test(
-          "mkldnn_with_generic_fallback", R"({"log_output": "file"})",
+          "mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
           "../data/random_input_3_4096.txt",
           "../data/random_weight_256_4096.txt", "../data/random_bias_256.txt",
           "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
     }
-    TEST_F(MultiContextBackendTest, gemm_2d_test) {
-        gemm_test("mkldnn_with_generic_fallback", "",
+    TEST_F(MkldnnWithGenericFallbackBackendTest, gemm_2d_test) {
+        gemm_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
                   "../data/random_input_3_4_32_32.txt",
                   "../data/random_weight_256_4096.txt",
                   "../data/random_bias_256.txt",
                   "../data/linear_2d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
     }
 
-    TEST_F(MultiContextBackendTest, gemm_1d_relu_test) {
+    TEST_F(MkldnnWithGenericFallbackBackendTest, gemm_1d_relu_test) {
         std::string backend_name = "mkldnn_with_generic_fallback";
-        std::string backend_config = R"({"log_output": "file"})";
+        std::string backend_config = R"({"log_output": "stdout"})";
         menoh::model_data model_data;
         menoh::variable_profile_table_builder vpt_builder;
         std::pair<std::string, std::string> gemm_true_output_filename = {
@@ -122,8 +122,8 @@ namespace menoh {
         }
     }
 
-    TEST_F(MultiContextBackendTest, relu_1d_test) {
-        relu_test("mkldnn_with_generic_fallback", "",
+    TEST_F(MkldnnWithGenericFallbackBackendTest, relu_1d_test) {
+        relu_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
                   "../data/random_input_3_4096.txt", "../data/relu_1d.txt");
     }
 } // namespace menoh

From 1a3fd7a4f49df73cfed35a6dd6c932e26425de80 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 9 Sep 2018 23:29:12 +0900
Subject: [PATCH 114/321] add test/backend.hpp

---
 test/backend.hpp | 252 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 252 insertions(+)
 create mode 100644 test/backend.hpp

diff --git a/test/backend.hpp b/test/backend.hpp
new file mode 100644
index 0000000..0f42985
--- /dev/null
+++ b/test/backend.hpp
@@ -0,0 +1,252 @@
+#ifndef MENOH_TEST_BACKEND_HPP
+#define MENOH_TEST_BACKEND_HPP
+
+#include <unordered_map>
+
+#include <menoh/menoh.hpp>
+
+#include "common.hpp"
+#include "np_io.hpp"
+
+namespace menoh {
+    inline auto
+    operator_test(std::string const& backend_name,
+                  std::string const& backend_config,
+                  menoh::model_data& model_data,
+                  std::vector<std::pair<std::string, std::string>> const&
+                    input_filename_table,
+                  std::unordered_map<std::string, std::string> const&
+                    true_output_filename_table,
+                  float eps = 10.e-4) {
+
+        menoh::variable_profile_table_builder vpt_builder;
+
+        std::unordered_map<std::string,
+                           std::tuple<std::vector<int>, std::vector<float>>>
+          input_table;
+        for(auto const& p : input_filename_table) {
+            auto const& input_name = p.first;
+            auto const& input_filename = p.second;
+
+            model_data.add_input_name_to_current_node(input_name);
+
+            std::vector<int32_t> input_dims;
+            std::vector<float> data;
+            std::tie(std::ignore, input_dims, data) =
+              menoh_impl::load_np_array(input_filename);
+            dtype_t dtype = dtype_t::float_; // TODO other dtype
+            input_table.insert({input_name, {input_dims, data}});
+            if(input_dims.size() == 2 ||
+               input_dims.size() == 4) { // FIXME dirty hack
+                vpt_builder.add_input_profile(input_name, dtype, input_dims);
+            }
+        }
+
+        for(auto const& p : input_filename_table) {
+            auto const& input_name = p.first;
+            // auto const& input_filename = p.second;
+            dtype_t dtype = dtype_t::float_; // TODO other dtype
+            model_data.add_parameter(
+              input_name, dtype, std::get<0>(input_table.at(input_name)),
+              std::get<1>(input_table.at(input_name)).data());
+        }
+
+        std::unordered_map<std::string, std::vector<float>> true_output_table;
+        for(auto const& p : true_output_filename_table) {
+            auto const& output_name = p.first;
+            auto const& output_filename = p.second;
+            model_data.add_output_name_to_current_node(output_name);
+
+            std::vector<int32_t> output_dims;
+            std::vector<float> data;
+            std::tie(std::ignore, output_dims, data) =
+              menoh_impl::load_np_array(output_filename);
+            dtype_t dtype = dtype_t::float_; // TODO other dtype
+            true_output_table.insert({output_name, data});
+            vpt_builder.add_output_profile(output_name, dtype);
+        }
+
+        auto vpt = vpt_builder.build_variable_profile_table(model_data);
+        model_builder model_builder(vpt);
+        auto model =
+          model_builder.build_model(model_data, backend_name, backend_config);
+        model.run();
+
+        for(auto const& p : true_output_table) {
+            auto const& output_name = p.first;
+            auto const& true_output = p.second;
+            auto output_var = model.get_variable(output_name);
+            menoh_impl::assert_near_list(
+              static_cast<float*>(output_var.buffer_handle),
+              static_cast<float*>(output_var.buffer_handle) +
+                std::accumulate(output_var.dims.begin(), output_var.dims.end(),
+                                1, std::multiplies<>()),
+              true_output.begin(), true_output.end(), eps);
+        }
+    }
+
+    inline auto add_test(std::string const& backend_name,
+                         std::string const& config,
+                         std::vector<std::string> const& input_filename_list,
+                         std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Add");
+        std::vector<std::pair<std::string, std::string>> inputs;
+        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+            auto const& filename = input_filename_list.at(i);
+            inputs.push_back({"input" + std::to_string(i), filename});
+        }
+        operator_test(backend_name, config, model_data, inputs,
+                      {{"output", true_output_filename}});
+    }
+    inline auto average_pool_test(std::string const& backend_name,
+                                  std::string const& config,
+                                  std::vector<int32_t> const& kernel_shape,
+                                  std::vector<int32_t> const& pads,
+                                  std::vector<int32_t> const& strides,
+                                  std::string const& input_filename,
+                                  std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("AveragePool");
+        model_data.add_attribute_ints_to_current_node("kernel_shape",
+                                                      kernel_shape);
+        model_data.add_attribute_ints_to_current_node("pads", pads);
+        model_data.add_attribute_ints_to_current_node("strides", strides);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto concat_test(std::string const& backend_name,
+                            std::string const& config, float axis,
+                            std::vector<std::string> const& input_filename_list,
+                            std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Concat");
+        model_data.add_attribute_int_to_current_node("axis", axis);
+        std::vector<std::pair<std::string, std::string>> inputs;
+        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+            auto const& filename = input_filename_list.at(i);
+            inputs.push_back({"input" + std::to_string(i), filename});
+        }
+        operator_test(backend_name, config, model_data, inputs,
+                      {{"output", true_output_filename}});
+    }
+    inline auto elu_test(std::string const& backend_name,
+                         std::string const& config, float alpha,
+                         std::string const& input_filename,
+                         std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Elu");
+        model_data.add_attribute_float_to_current_node("alpha", alpha);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto gemm_test(std::string const& backend_name,
+                          std::string const& config,
+                          std::string const& input_filename,
+                          std::string const& weight_filename,
+                          std::string const& bias_filename,
+                          std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Gemm");
+        model_data.add_attribute_int_to_current_node("transB", 1);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename},
+                       {"weight", weight_filename},
+                       {"bias", bias_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto gemm_relu_test(std::string const& backend_name,
+                               std::string const& config,
+                               std::string const& input_filename,
+                               std::string const& weight_filename,
+                               std::string const& bias_filename,
+                               std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Gemm");
+        model_data.add_attribute_int_to_current_node("transB", 1);
+        model_data.add_new_node("Relu");
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename},
+                       {"weight", weight_filename},
+                       {"bias", bias_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto leaky_relu_test(std::string const& backend_name,
+                                std::string const& config, float alpha,
+                                std::string const& input_filename,
+                                std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("LeakyRelu");
+        model_data.add_attribute_float_to_current_node("alpha", alpha);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto max_pool_test(std::string const& backend_name,
+                              std::string const& config,
+                              std::vector<int32_t> const& kernel_shape,
+                              std::vector<int32_t> const& pads,
+                              std::vector<int32_t> const& strides,
+                              std::string const& input_filename,
+                              std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("MaxPool");
+        model_data.add_attribute_ints_to_current_node("kernel_shape",
+                                                      kernel_shape);
+        model_data.add_attribute_ints_to_current_node("pads", pads);
+        model_data.add_attribute_ints_to_current_node("strides", strides);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto relu_test(std::string const& backend_name,
+                          std::string const& config,
+                          std::string const& input_filename,
+                          std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Relu");
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto softmax_test(std::string const& backend_name,
+                             std::string const& config, int32_t axis,
+                             std::string const& input_filename,
+                             std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Softmax");
+        model_data.add_attribute_int_to_current_node("axis", axis);
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+    inline auto sum_test(std::string const& backend_name,
+                         std::string const& config,
+                         std::vector<std::string> const& input_filename_list,
+                         std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Sum");
+        std::vector<std::pair<std::string, std::string>> inputs;
+        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+            auto const& filename = input_filename_list.at(i);
+            inputs.push_back({"input" + std::to_string(i), filename});
+        }
+        operator_test(backend_name, config, model_data, inputs,
+                      {{"output", true_output_filename}});
+    }
+    inline auto tanh_test(std::string const& backend_name,
+                          std::string const& config,
+                          std::string const& input_filename,
+                          std::string const& true_output_filename) {
+        menoh::model_data model_data;
+        model_data.add_new_node("Tanh");
+        operator_test(backend_name, config, model_data,
+                      {{"input", input_filename}},
+                      {{"output", true_output_filename}});
+    }
+
+} // namespace menoh
+
+#endif // MENOH_TEST_BACKEND_HPP

From bb0521a14040c26e50dce6a5a181570a14854ae2 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 11 Sep 2018 19:33:52 +0900
Subject: [PATCH 115/321] fix test with dirty hack

---
 menoh/graph.cpp                               | 2 +-
 test/mkldnn_with_generic_fallback_backend.cpp | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 40a0509..99b705e 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -245,7 +245,7 @@ namespace menoh_impl {
                                                           "LRN",
                                                           "MaxPool",
                                                           "Softmax",
-                                                          "Sum"}};
+                                                          "Sum",
 
         std::unordered_map<std::string, std::vector<int>> variable_dims_table(
           input_name_and_dims_pair_list.begin(),
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index cad6d86..dec14ad 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -111,6 +111,11 @@ namespace menoh {
             std::tie(std::ignore, output_dims, true_output_data) =
               menoh_impl::load_np_array(true_output_filename);
             dtype_t dtype = dtype_t::float_; // TODO other dtype
+            if(output_name == "relu_out") {
+                std::transform(true_output_data.begin(), true_output_data.end(),
+                               true_output_data.begin(),
+                               [](auto e) { return std::max(e, 0.f); });
+            }
 
             auto output_var = model.get_variable(output_name);
             menoh_impl::assert_near_list(

From b9e8cfbfb421f0178a9ba72b6373ec1d4bf43b99 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 12 Sep 2018 11:59:27 +0900
Subject: [PATCH 116/321] remove iostream include

---
 menoh/graph.cpp                                   | 2 --
 menoh/mkldnn_with_generic_fallback/model_core.cpp | 2 +-
 2 files changed, 1 insertion(+), 3 deletions(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 99b705e..804a05b 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -12,8 +12,6 @@
 #include <menoh/optional.hpp>
 #include <menoh/utility.hpp>
 
-#include <iostream>
-
 namespace menoh_impl {
 
     std::vector<node> extract_needed_node_list(
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index e22e9e8..a39c678 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -15,7 +15,7 @@
 #include <menoh/utility.hpp>
 
 #include <fstream>
-#include <iostream>
+#include <iosfwd>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {

From 8a9f734bd61e60ab93ad4c82eabc97c4cbbad7c9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 12 Sep 2018 12:00:41 +0900
Subject: [PATCH 117/321] fix style

---
 menoh/graph.cpp                               | 11 ++++++-----
 test/mkldnn_with_generic_fallback_backend.cpp | 10 +++++-----
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 804a05b..22ff5be 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -34,7 +34,9 @@ namespace menoh_impl {
                             return output_name == required_output_name;
                         });
                   });
-                if(needed_node_iter == node_list.end()) { continue; }
+                if(needed_node_iter == node_list.end()) {
+                    continue;
+                }
                 auto is_already_added =
                   std::find(needed_node_list.begin(), needed_node_list.end(),
                             *needed_node_iter) != needed_node_list.end();
@@ -282,8 +284,8 @@ namespace menoh_impl {
                 auto output_channel_num =
                   get_output_channel_num_from_parameter_dims(
                     find_value(parameter_table, weight_name).dims());
-                auto output_dims = calc_2d_output_dims_for_conv_transpose(node,
-                          output_channel_num, variable_dims_table);
+                auto output_dims = calc_2d_output_dims_for_conv_transpose(
+                  node, output_channel_num, variable_dims_table);
                 auto dilations =
                   optional_attribute_ints(node, "dilations", {1, 1});
                 if(dilations != std::vector<int>({1, 1})) {
@@ -391,8 +393,7 @@ namespace menoh_impl {
                 auto output_dims = find_value(variable_dims_table, input_name);
                 variable_dims_table.insert(
                   {node.output_name_list.at(0), output_dims});
-            }
-            else {
+            } else {
                 throw unsupported_operator(node.op_type);
             }
         }
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index dec14ad..cfe8c45 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -10,11 +10,11 @@ namespace menoh {
     };
 
     TEST_F(MkldnnWithGenericFallbackBackendTest, gemm_1d_test) {
-        gemm_test(
-          "mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
-          "../data/random_input_3_4096.txt",
-          "../data/random_weight_256_4096.txt", "../data/random_bias_256.txt",
-          "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
+        gemm_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
+                  "../data/random_input_3_4096.txt",
+                  "../data/random_weight_256_4096.txt",
+                  "../data/random_bias_256.txt",
+                  "../data/linear_1d_w256_4096_b_256.txt"); //, 1, 1, 0, 1);
     }
     TEST_F(MkldnnWithGenericFallbackBackendTest, gemm_2d_test) {
         gemm_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",

From b5ae596ab20beb80f47cfd31dba5087eb552a5b1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 15 Sep 2018 22:57:48 +0900
Subject: [PATCH 118/321] fix comment

---
 .../backend/mkldnn/mkldnn_context.cpp                           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 60b665d..9d09f25 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -145,7 +145,7 @@ namespace menoh_impl {
                       std::make_move_iterator(new_temp_memory_list.end()));
                 }
 
-                // when any nodes are not processed
+                // when no nodes are processed
                 if(current_index == first_node_index) {
                     return nullopt;
                 }

From b919e4cbf746152cccd17e0c4c65f4553b716f28 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 15 Sep 2018 23:13:30 +0900
Subject: [PATCH 119/321] remove unused code

---
 .../backend/mkldnn/mkldnn_context.cpp                         | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 9d09f25..7b2d57b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -100,10 +100,6 @@ namespace menoh_impl {
                                     new_copy_procedure_list.push_back(
                                       copy_proc);
                                     input_list.push_back(arr);
-                                    auto format =
-                                      arr.dims().size() == 2
-                                        ? mkldnn::memory::format::nc
-                                        : mkldnn::memory::format::nchw;
                                     is_found_from_other_context = true;
                                     break;
                                 }

From dbdcc4179a05aae9b4be730d001dcc33416bb456 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 15 Sep 2018 23:13:50 +0900
Subject: [PATCH 120/321] fix compile error

---
 menoh/graph.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 22ff5be..1d4466e 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -245,7 +245,7 @@ namespace menoh_impl {
                                                           "LRN",
                                                           "MaxPool",
                                                           "Softmax",
-                                                          "Sum",
+                                                          "Sum"}};
 
         std::unordered_map<std::string, std::vector<int>> variable_dims_table(
           input_name_and_dims_pair_list.begin(),

From 38e06014cdaceeb2fa101c410e0b63ae3ac03d35 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 15 Sep 2018 23:14:02 +0900
Subject: [PATCH 121/321] fix style

---
 menoh/graph.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 1d4466e..569f193 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -386,7 +386,8 @@ namespace menoh_impl {
                 variable_dims_table.insert(
                   {node.output_name_list.at(0), output_dims});
             } else if(std::find(supported_operator_list.begin(),
-                                supported_operator_list.end(), node.op_type) !=
+                                supported_operator_list.end(),
+                                node.op_type) !=
                       supported_operator_list
                         .end()) { // check if supported operator
                 auto input_name = node.input_name_list.at(0);

From bd19abdaf16112d4101d1c174ae57d44de3715f9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 00:01:47 +0900
Subject: [PATCH 122/321] refactor generic_context

---
 .../backend/generic/generic_context.cpp       | 184 +++++++++---------
 1 file changed, 94 insertions(+), 90 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 13e17d7..e810b35 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -9,20 +9,6 @@ namespace menoh_impl {
                 procedure_factory_table_.emplace("Relu", make_relu);
             }
 
-            optional<std::function<void()>>
-            generic_context::try_to_get_input_from_common_table(
-              std::string const& input_name,
-              std::unordered_map<std::string, array> const& common_table) {
-                auto found = common_table.find(input_name);
-                if(found != common_table.end()) {
-                    variable_table_.emplace(input_name, found->second);
-                    return std::function<void()>([this, &input_name]() {
-                        variable_table_.erase(input_name);
-                    });
-                }
-                return nullopt;
-            }
-
             optional<std::tuple<std::vector<procedure>, int>>
             generic_context::do_process_node_list(
               std::string const& context_name, int current_index,
@@ -36,98 +22,116 @@ namespace menoh_impl {
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
               logger_handle logger) {
-                auto const& node = node_list.at(current_index);
+
+                auto first_node_index = current_index;
                 std::vector<procedure> procedure_list;
-                std::vector<array> input_list;
-                std::vector<std::function<void()>> rollback_list;
-                for(auto const& input_name : node.input_name_list) {
-                    if(variable_table_.find(input_name) !=
-                       variable_table_.end()) {
-                        *logger << input_name
-                                << " is found in self variable table"
-                                << std::endl;
-                        continue; // when found
-                    }
-                    do {
-                        {
-                            // normally, copy once array here, because
-                            // parameter is statically fixed
-                            auto rollback = try_to_get_input_from_common_table(
-                              input_name, common_parameter_table);
-                            if(rollback) {
+
+                std::vector<procedure> new_op_proc_list;
+
+                for(; current_index < node_list.size(); ++current_index) {
+                    auto const& node = node_list.at(current_index);
+                    std::vector<array> input_list;
+                    std::vector<procedure> new_copy_procedure_list;
+
+                    for(auto const& input_name : node.input_name_list) {
+                        do {
+                            // search in self variable table
+                            auto found_from_variable_table =
+                              variable_table_.find(input_name);
+                            if(found_from_variable_table !=
+                               variable_table_.end()) {
+                                *logger << input_name
+                                        << " is found in self variable table"
+                                        << std::endl;
+                                input_list.push_back(
+                                  found_from_variable_table->second);
+                                break;
+                            }
+
+                            // search in common parameter and input table
+                            auto found_from_common_table =
+                              [&](auto const& table) {
+                                  auto found = table.find(input_name);
+                                  if(found != table.end()) {
+                                      assert(found->second.dims().size() == 2 ||
+                                             found->second.dims().size() == 4);
+                                      input_list.push_back(found->second);
+                                      return true;
+                                  }
+                                  return false;
+                              };
+                            if(found_from_common_table(
+                                 common_parameter_table)) {
                                 *logger << input_name
                                         << " is found in common parameter table"
                                         << std::endl;
-                                rollback_list.emplace_back(*rollback);
                                 break;
                             }
-                        }
-                        {
-                            // normally, allocate buffer for variable and
-                            // issue copy procedure
-                            auto rollback = try_to_get_input_from_common_table(
-                              input_name, common_input_table);
-                            if(rollback) {
+                            if(found_from_common_table(common_input_table)) {
                                 *logger << input_name
                                         << " is found in common input table"
                                         << std::endl;
-                                rollback_list.emplace_back(*rollback);
                                 break;
                             }
-                        }
 
-                        // take from other context
-                        bool is_found_from_other_context = false;
-                        for(auto const& context_pair : context_list) {
-                            std::string name = context_pair.first;
-                            context* con = context_pair.second.get();
-                            if(name == context_name) {
-                                continue; // skip self
-                            }
-                            auto found = con->try_to_get_variable(input_name);
-                            if(found) {
-                                *logger << input_name
-                                        << " is found in other context's "
-                                           "varibale table: "
-                                        << context_pair.first << std::endl;
-                                procedure proc;
-                                array arr;
-                                std::tie(proc, arr) = *found;
-                                procedure_list.push_back(proc);
-                                variable_table_.emplace(input_name, arr);
-                                rollback_list.push_back([this, &input_name]() {
-                                    variable_table_.erase(input_name);
-                                });
-                                is_found_from_other_context = true;
-                                break;
+                            // search in other contexts' variable table
+                            bool is_found_from_other_context = false;
+                            for(auto const& context_pair : context_list) {
+                                if(context_pair.first == context_name) {
+                                    continue; // skip self
+                                }
+                                auto found =
+                                  context_pair.second->try_to_get_variable(
+                                    input_name);
+                                if(found) {
+                                    *logger << input_name
+                                            << " is found in other context's "
+                                               "varibale table: "
+                                            << context_pair.first << std::endl;
+                                    procedure copy_proc;
+                                    array arr;
+                                    std::tie(copy_proc, arr) = *found;
+                                    new_copy_procedure_list.push_back(
+                                      copy_proc);
+                                    input_list.push_back(arr);
+                                    is_found_from_other_context = true;
+                                    break;
+                                }
                             }
-                        }
-                        assert(is_found_from_other_context);
-                    } while(false);
-                    assert(variable_table_.find(input_name) !=
-                           variable_table_.end());
-                    input_list.push_back(variable_table_.at(input_name));
-                }
-                procedure proc;
-                std::vector<std::pair<std::string, array>> new_variables;
-                try {
-                    auto factory = procedure_factory_table_.at(node.op_type);
-                    std::tie(proc, new_variables) =
-                      factory.operator()(current_index, node_list, input_list,
-                                         required_output_table);
-                } catch(...) {
-                    for(auto const& rollback : rollback_list) {
-                        rollback(); // remove new inputs
+                            assert(is_found_from_other_context);
+                        } while(false);
                     }
+                    procedure op_proc;
+                    std::vector<std::pair<std::string, array>> new_outputs;
+                    try {
+                        auto factory =
+                          procedure_factory_table_.at(node.op_type);
+                        std::tie(op_proc, new_outputs) =
+                          factory.operator()(current_index, node_list,
+                                             input_list, required_output_table);
+                    } catch(...) { break; }
+                    new_op_proc_list.push_back(op_proc);
+                    procedure_list.insert(
+                      procedure_list.end(),
+                      std::make_move_iterator(new_copy_procedure_list.begin()),
+                      std::make_move_iterator(new_copy_procedure_list.end()));
+                    variable_table_.insert(
+                      std::make_move_iterator(new_outputs.begin()),
+                      std::make_move_iterator(new_outputs.end()));
+                }
+
+                // when no nodes are processed
+                if(current_index == first_node_index) {
                     return nullopt;
                 }
-                procedure_list.push_back(std::move(proc));
-                variable_table_.insert(
-                  std::make_move_iterator(new_variables.begin()),
-                  std::make_move_iterator(new_variables.end()));
-                return std::make_tuple(procedure_list, current_index + 1);
+
+                procedure_list.insert(
+                  procedure_list.end(),
+                  std::make_move_iterator(new_op_proc_list.begin()),
+                  std::make_move_iterator(new_op_proc_list.end()));
+
+                return std::make_tuple(procedure_list, current_index);
             }
         } // namespace generic_backend
-
-    } // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
 } // namespace menoh_impl

From 7b28ce5945d68d2d4be8ee5508a60695f0766f3f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 00:02:09 +0900
Subject: [PATCH 123/321] fix style

---
 .../backend/mkldnn/mkldnn_context.cpp                         | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 7b2d57b..243a9e3 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -28,6 +28,7 @@ namespace menoh_impl {
               logger_handle logger) {
                 auto first_node_index = current_index;
                 std::vector<procedure> procedure_list;
+
                 std::vector<mkldnn::primitive> primitive_list;
 
                 for(; current_index < node_list.size(); ++current_index) {
@@ -145,6 +146,7 @@ namespace menoh_impl {
                 if(current_index == first_node_index) {
                     return nullopt;
                 }
+
                 procedure_list.emplace_back([this, primitive_list]() {
                     mkldnn::stream(mkldnn::stream::kind::eager)
                       .submit(primitive_list)
@@ -155,5 +157,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    } // namespace mkldnn_with_generic_fallback_backend
 } // namespace menoh_impl

From 9b3ad78eca163887e78225ac782c5bc751a60370 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 00:26:19 +0900
Subject: [PATCH 124/321] make mkldnn context give variables with NCHW order to
 other variables

---
 .../backend/mkldnn/mkldnn_context.hpp         | 31 +++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
index 35a44e4..65fb382 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -26,9 +26,36 @@ namespace menoh_impl {
                     }
                     auto dims =
                       ::menoh_impl::mkldnn_backend::extract_dims(found->second);
+                    auto variable_memory = found->second; // mutable
+                    procedure copy_proc(nullptr); // mutable
+                    if(dims.size() == 4) {
+                        auto format = static_cast<mkldnn::memory::format>(
+                          found->second.get_primitive_desc()
+                            .desc()
+                            .data.format);
+                        if(format != mkldnn::memory::nchw) {
+                            auto data_type =
+                              static_cast<mkldnn::memory::data_type>(
+                                found->second.get_primitive_desc()
+                                  .desc()
+                                  .data.data_type);
+                            variable_memory = mkldnn::memory(
+                              {{dims, data_type, mkldnn::memory::format::nchw},
+                               engine_});
+                            temp_memory_list_.push_back(variable_memory);
+                            std::vector<mkldnn::primitive> primitives(
+                              {mkldnn::reorder(found->second,
+                                               variable_memory)});
+                            copy_proc = [primitives]() {
+                                mkldnn::stream(mkldnn::stream::kind::eager)
+                                  .submit(primitives)
+                                  .wait();
+                            };
+                        }
+                    }
                     return std::make_tuple(
-                      procedure(), array(dtype_t::float_, dims,
-                                         found->second.get_data_handle()));
+                      copy_proc, array(dtype_t::float_, dims,
+                                       found->second.get_data_handle()));
                 }
 
                 virtual optional<std::tuple<std::vector<procedure>, int>>

From 6570196e841c3dc577f604a92d762a415feec256 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 14 Sep 2018 17:49:53 +0900
Subject: [PATCH 125/321] link libprotobuf to menoh_test

---
 .gitmodules         |  3 +++
 CMakeLists.txt      |  6 ------
 test/CMakeLists.txt | 15 ++++++++++++++-
 test/lib/filesystem |  1 +
 4 files changed, 18 insertions(+), 7 deletions(-)
 create mode 160000 test/lib/filesystem

diff --git a/.gitmodules b/.gitmodules
index 2ee7f0e..17edb59 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -4,3 +4,6 @@
 [submodule "test/lib/googletest"]
 	path = test/lib/googletest
 	url = https://github.com/google/googletest.git
+[submodule "test/lib/filesystem"]
+	path = test/lib/filesystem
+	url = https://github.com/wjakob/filesystem.git
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b51806e..751fe2f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,12 +67,6 @@ endif()
 include_directories("${MKLDNN_INCLUDE_DIR}")
 
 if(${ENABLE_TEST})
-    enable_testing()
-    # GTest setup
-    set(GTEST_DIR test/lib/googletest)
-    execute_process(COMMAND git submodule update --init -- ${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-    message(STATUS "# add_subdirectory\(${GTEST_DIR}\)")
-    add_subdirectory(${GTEST_DIR})
     message(STATUS "# add_subdirectory\(test\)")
     add_subdirectory(test)
 endif()
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index d920bce..8d302d8 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,3 +1,16 @@
+enable_testing()
+
+# GTest setup
+set(GTEST_DIR "lib/googletest")
+execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+message(STATUS "# add_subdirectory\(${GTEST_DIR}\)")
+add_subdirectory(${GTEST_DIR})
+
+# filesystem setup
+set(FILESYSTEM_DIR "lib/filesystem")
+execute_process(COMMAND git submodule update --init -- test/${FILESYSTEM_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+include_directories("${FILESYSTEM_DIR}")
+
 add_executable(menoh_test
     np_io.cpp
     array.cpp
@@ -13,6 +26,6 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main menoh_test_target)
+target_link_libraries(menoh_test gtest_main menoh_test_target ${PROTOBUF_LIBRARY})
 
 add_test(NAME menoh_test COMMAND menoh_test)
diff --git a/test/lib/filesystem b/test/lib/filesystem
new file mode 160000
index 0000000..0a539a6
--- /dev/null
+++ b/test/lib/filesystem
@@ -0,0 +1 @@
+Subproject commit 0a539a6c988dc8691af317e077893e831dee2908

From a9a06b9957353f1c0ff9780f363b87fc61784534 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 14 Sep 2018 17:51:26 +0900
Subject: [PATCH 126/321] add test code

---
 menoh/onnx.cpp    |   10 +-
 test/common.hpp   |    4 +-
 test/operator.cpp | 1229 ++++++++-------------------------------------
 3 files changed, 225 insertions(+), 1018 deletions(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index e1813e6..bc4ac2b 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -23,7 +23,7 @@
 
 namespace menoh_impl {
 
-    auto tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt) {
+    dtype_t tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt) {
         if(tpdt == onnx::TensorProto_DataType_FLOAT) {
             return dtype_t::float_;
         }
@@ -167,7 +167,6 @@ namespace menoh_impl {
         return node_list;
     }
 
-
     model_data make_model_from_onnx(onnx::ModelProto& onnx_model) {
         // onnx opset version check
         if(onnx_model.opset_import_size() != 0) {
@@ -229,14 +228,17 @@ namespace menoh_impl {
         return make_model_from_onnx(onnx_model);
     }
 
-    model_data make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data, int32_t size) {
+    model_data
+    make_model_data_from_onnx_data_on_memory(const uint8_t* onnx_data,
+                                             int32_t size) {
         namespace gpio = ::google::protobuf::io;
         gpio::ArrayInputStream ais(onnx_data, size);
         gpio::CodedInputStream cis(&ais);
         cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
                                std::numeric_limits<int>::max());
         onnx::ModelProto onnx_model;
-        if(!onnx_model.ParseFromCodedStream(&cis) || !cis.ConsumedEntireMessage()) {
+        if(!onnx_model.ParseFromCodedStream(&cis) ||
+           !cis.ConsumedEntireMessage()) {
             throw onnx_parse_error("parse binary onnx data on memory");
         }
         return make_model_from_onnx(onnx_model);
diff --git a/test/common.hpp b/test/common.hpp
index 31474a2..3fb29a8 100644
--- a/test/common.hpp
+++ b/test/common.hpp
@@ -6,11 +6,11 @@
 namespace menoh_impl {
 
     template <typename Iter1, typename Iter2>
-    auto assert_eq_list(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2) {
+    auto assert_eq_list(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2, float eps=1.e-4) {
         ASSERT_EQ(std::distance(first1, last1), std::distance(first2, last2))
           << "size is different";
         while(first1 != last1) {
-            ASSERT_EQ(*first1, *first2)
+            ASSERT_NEAR(*first1, *first2, eps)
               << *first1 << " and " << *first2 << " are different";
             ++first1;
             ++first2;
diff --git a/test/operator.cpp b/test/operator.cpp
index 1f610ae..729e664 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -1,5 +1,5 @@
+/*
 #include <fstream>
-#include <gtest/gtest.h>
 #include <iostream>
 #include <numeric>
 #include <sstream>
@@ -15,1027 +15,232 @@
 #include <menoh/mkldnn/operator.hpp>
 #include <menoh/mkldnn/utility.hpp>
 #include <menoh/model_core.hpp>
+*/
+#include <gtest/gtest.h>
 
-namespace menoh_impl {
-    namespace mkldnn_backend {
-
-        auto load_np_array_as_memory(std::string const& filename,
-                                     mkldnn::engine const& engine) {
-            auto data = menoh_impl::load_np_array_as_array(filename);
-            assert(data.dims().size() == 2 || data.dims().size() == 4);
-            mkldnn::memory::format format = data.dims().size() == 2
-                                              ? mkldnn::memory::format::nc
-                                              : mkldnn::memory::format::nchw;
-            mkldnn::memory memory(
-              {{{data.dims()},
-                dtype_to_mkldnn_memory_data_type(data.dtype()),
-                format},
-               engine});
-            std::copy(fbegin(data), fend(data),
-                      static_cast<float*>(memory.get_data_handle()));
-            return memory;
-        }
-
-        class OperatorTest : public ::testing::Test {
-        protected:
-            OperatorTest() = default;
-            virtual void SetUp() {}
-
-            auto relu_test(std::string const& input_filename,
-                           std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{"", {"input"}, {"output"}, {}};
-                auto factory_return = make_relu_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto
-            leaky_relu_test(std::string const& input_filename,
-                            std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{
-                  "", {"input"}, {"output"}, {{"alpha", 0.001f}}};
-                auto factory_return = make_leaky_relu_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto elu_test(std::string const& input_filename,
-                          std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{
-                  "", {"input"}, {"output"}, {{"alpha", 1.1f}}};
-                auto factory_return = make_elu_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto abs_test(std::string const& input_filename,
-                          std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{"", {"input"}, {"output"}, {}};
-                auto factory_return = make_abs_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto sqrt_test(std::string const& input_filename,
-                           std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{"", {"input"}, {"output"}, {}};
-                auto factory_return = make_sqrt_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto tanh_test(std::string const& input_filename,
-                           std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto node = menoh_impl::node{"", {"input"}, {"output"}, {}};
-                auto factory_return = make_tanh_primitive(
-                  node, 0, {node}, {}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto softmax_test(std::string const& input_filename,
-                              std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_softmax_primitive(
-                  menoh_impl::node{"", {"input"}, {"output"}, {}}, {},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto fc_test(std::string const& input_filename,
-                         std::string const& weight_filename,
-                         std::string const& bias_filename,
-                         std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight =
-                  menoh_impl::load_np_array_as_array(weight_filename);
-                auto bias = menoh_impl::load_np_array_as_array(bias_filename);
-                std::vector<int> output_dims{extract_dims(input_memory).at(0),
-                                             weight.dims().at(0)};
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_fc_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight", "bias"},
-                                   {"output"},
-                                   {{"axis", 1}, {"axis_w", 1}}},
-                  {{"weight", weight}, {"bias", bias}},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto max_pool_test(std::string const& input_filename, int k, int s,
-                               int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, input_dims.at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_max_pool_primitive(
-                  menoh_impl::node{"",
-                                   {"input"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {}, {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/max_pooling_2d_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) + ".txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto global_max_pool_test(
-              std::string const& input_filename,
-              std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto input_dims = extract_dims(input_memory);
-                std::vector<int> strides{1, 1};
-                std::vector<int> kernel_shape{input_dims.at(2),
-                                              input_dims.at(3)};
-                std::vector<int> pads{0, 0, 0, 0};
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, input_dims.at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_global_max_pool_primitive(
-                  menoh_impl::node{"", {"input"}, {"output"}, {}}, {},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto average_pool_test(std::string const& input_filename, int k,
-                                   int s, int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, input_dims.at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_average_pool_primitive(
-                  menoh_impl::node{"",
-                                   {"input"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {}, {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/average_pooling_2d_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) + ".txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto global_average_pool_test(
-              std::string const& input_filename,
-              std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto input_dims = extract_dims(input_memory);
-                std::vector<int> strides{1, 1};
-                std::vector<int> kernel_shape{input_dims.at(2),
-                                              input_dims.at(3)};
-                std::vector<int> pads{0, 0, 0, 0};
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, input_dims.at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_global_average_pool_primitive(
-                  menoh_impl::node{"", {"input"}, {"output"}, {}}, {},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto conv_test(std::string const& input_filename, int k, int s,
-                           int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight = menoh_impl::load_np_array_as_array(
-                  "../data/random_weight_5_4_" + std::to_string(k) + "_" +
-                  std::to_string(k) + ".txt");
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, weight.dims().at(0), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_conv_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {{"weight", weight}}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/convolution_2d_w5_4_" + std::to_string(k) + "_" +
-                  std::to_string(k) + "_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) + ".txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto conv_with_bias_test(std::string const& input_filename, int k,
-                                     int s, int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight = menoh_impl::load_np_array_as_array(
-                  "../data/random_weight_5_4_" + std::to_string(k) + "_" +
-                  std::to_string(k) + ".txt");
-                auto bias = menoh_impl::load_np_array_as_array(
-                  "../data/random_bias_5.txt");
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims(
-                  input_dims, weight.dims().at(0), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_conv_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight", "bias"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {{"weight", weight}, {"bias", bias}},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/convolution_2d_w5_4_" + std::to_string(k) + "_" +
-                  std::to_string(k) + "_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) +
-                  "_with_bias.txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto conv_transpose_test(std::string const& input_filename, int k,
-                                     int s, int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight = menoh_impl::load_np_array_as_array(
-                  "../data/random_weight_4_5_" + std::to_string(k) + "_" +
-                  std::to_string(k) + ".txt");
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims_for_conv_transpose(
-                  input_dims, weight.dims().at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_conv_transpose_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {{"weight", weight}}, {{"input", input_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/deconvolution_2d_w4_5_" + std::to_string(k) + "_" +
-                  std::to_string(k) + "_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) + ".txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto
-            conv_transpose_with_bias_test(std::string const& input_filename,
-                                          int k, int s, int p) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight = menoh_impl::load_np_array_as_array(
-                  "../data/random_weight_4_5_" + std::to_string(k) + "_" +
-                  std::to_string(k) + ".txt");
-                auto bias = menoh_impl::load_np_array_as_array(
-                  "../data/random_bias_4.txt");
-                std::vector<int> strides{{s, s}};
-                std::vector<int> kernel_shape{{k, k}};
-                std::vector<int> pads{{p, p, p, p}};
-                auto input_dims = extract_dims(input_memory);
-                auto output_dims = calc_2d_output_dims_for_conv_transpose(
-                  input_dims, weight.dims().at(1), kernel_shape, strides, pads);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_conv_transpose_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight", "bias"},
-                                   {"output"},
-                                   {{"strides", strides},
-                                    {"kernel_shape", kernel_shape},
-                                    {"pads", pads}}},
-                  {{"weight", weight}, {"bias", bias}},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/deconvolution_2d_w4_5_" + std::to_string(k) + "_" +
-                  std::to_string(k) + "_k" + std::to_string(k) + "_s" +
-                  std::to_string(s) + "_p" + std::to_string(p) +
-                  "_with_bias.txt");
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto
-            batch_norm_test(std::string const& input_filename,
-                            std::string const& mean_filename,
-                            std::string const& var_fileanme,
-                            std::string const& gamma_filename,
-                            std::string const& beta_filename,
-                            std::string const& true_output_filename) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto mean = menoh_impl::load_np_array_as_array(mean_filename);
-                auto var = menoh_impl::load_np_array_as_array(var_fileanme);
-                auto gamma = menoh_impl::load_np_array_as_array(gamma_filename);
-                auto beta = menoh_impl::load_np_array_as_array(beta_filename);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_batch_norm_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "gamma", "beta", "mean", "var"},
-                                   {"output"},
-                                   {{"epsilon", 1e-5f}, {"is_test", 1}}},
-                  {{"gamma", gamma},
-                   {"beta", beta},
-                   {"mean", mean},
-                   {"var", var}},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
+#include <fstream>
+#include <iostream>
+#include <numeric>
 
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
+#include <filesystem/path.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <onnx/onnx.pb.h>
 
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
+#include <menoh/array.hpp>
+#include <menoh/dtype.hpp>
+#include <menoh/onnx.hpp>
 
-            auto add_test(std::string const& input_a_filename,
-                          std::string const& input_b_filename,
-                          std::string const& true_output_filename) const {
-                auto input_a_memory =
-                  load_np_array_as_memory(input_a_filename, engine_);
-                auto input_b_memory =
-                  load_np_array_as_memory(input_b_filename, engine_);
-                auto output_dims = extract_dims(input_a_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_add_primitive(
-                  menoh_impl::node{
-                    "", {"input_a", "input_b"}, {"output"}, {{"broadcast", 0}}},
-                  {},
-                  {{"input_a", input_a_memory}, {"input_b", input_b_memory}},
-                  {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
+#include <menoh/menoh.hpp>
 
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
+#include "common.hpp"
 
-            auto
-            concat_test(std::vector<std::string> const& input_filename_list,
-                        int axis,
-                        std::string const& true_output_filename) const {
-                std::vector<std::string> input_name_list;
-                std::unordered_map<std::string, mkldnn::memory>
-                  input_memory_table;
-                auto i = 0;
-                for(auto const& input_filename : input_filename_list) {
-                    auto input_name = std::to_string(i);
-                    input_name_list.push_back(input_name);
-                    input_memory_table.insert(
-                      {input_name,
-                       load_np_array_as_memory(input_filename, engine_)});
-                    ++i;
+namespace menoh_impl {
+    dtype_t tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt);
+}
+
+namespace {
+
+    struct named_array_data {
+        std::string name;
+        menoh::dtype_t dtype;
+        std::vector<int> dims;
+        std::unique_ptr<char[]> data;
+    };
+
+    auto load_param(filesystem::path const& filepath,
+                    bool squash_dims = false) {
+        namespace gpio = ::google::protobuf::io;
+
+        std::ifstream ifs(filepath.str(), std::ios::binary);
+        if(!ifs) {
+            std::cout << "invalid filename" << std::endl;
+            throw "invalid_filename";
+        }
+        gpio::IstreamInputStream iis(&ifs);
+        gpio::CodedInputStream cis(&iis);
+        cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
+                               std::numeric_limits<int>::max());
+        onnx::TensorProto tensor;
+        if(!tensor.ParseFromCodedStream(&cis)) {
+            std::cout << "invalid filename" << std::endl;
+            throw "onnx_parse_error";
+        }
+
+        // TODO int array
+        std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
+        assert(2 <= dims.size());
+        if(squash_dims) {
+            dims.at(1) = std::accumulate(dims.begin() + 1, dims.end(), 1,
+                                         std::multiplies<int>());
+            dims.erase(dims.begin() + 2, dims.end());
+        }
+        auto total_size =
+          std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int>());
+        assert(tensor.has_raw_data());
+        assert(
+          tensor.raw_data().length() ==
+          static_cast<decltype(tensor.raw_data().length())>(total_size * 4));
+
+        using float_t =
+          menoh_impl::dtype_to_type_t<menoh_impl::dtype_t::float_>;
+        auto data = std::make_unique<char[]>(total_size * 4);
+        std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
+                  data.get());
+        return named_array_data{
+          tensor.name(),
+          static_cast<menoh::dtype_t>(
+            menoh_impl::tensor_proto_data_type_to_dtype(tensor.data_type())),
+          std::move(dims), std::move(data)};
+    }
+
+    class OperatorTest : public ::testing::Test {
+    protected:
+        OperatorTest()
+          : onnx_test_data_dir_path_(
+              "../external/onnx/onnx/backend/test/data/node/") {}
+
+        void run_test(std::string backend_name, std::string const& test_name,
+                      float eps, bool squash_dims = false) {
+            auto parent_dir_path = onnx_test_data_dir_path_ / test_name;
+
+            for(int data_set_index = 0; true; ++data_set_index) {
+                auto dataset_path =
+                  parent_dir_path /
+                  ("test_data_set_" + std::to_string(data_set_index));
+                if(!dataset_path.exists()) {
+                    break;
                 }
-                auto output_dims =
-                  extract_dims(input_memory_table.begin()->second);
-                output_dims.at(axis) = 0;
-                for(auto const& name_and_memory : input_memory_table) {
-                    output_dims.at(axis) +=
-                      extract_dims(name_and_memory.second).at(axis);
+                std::vector<named_array_data> input_list;
+                for(int input_index = 0;; ++input_index) {
+                    auto input_data_path =
+                      dataset_path /
+                      ("input_" + std::to_string(input_index) + ".pb");
+                    if(!input_data_path.exists()) {
+                        break;
+                    }
+                    input_list.push_back(
+                      load_param(input_data_path, squash_dims));
+                }
+                std::vector<named_array_data> true_output_list;
+                for(int output_index = 0;; ++output_index) {
+                    auto output_data_path =
+                      dataset_path /
+                      ("output_" + std::to_string(output_index) + ".pb");
+                    if(!output_data_path.exists()) {
+                        break;
+                    }
+                    true_output_list.push_back(
+                      load_param(output_data_path, squash_dims));
                 }
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_concat_primitive(
-                  menoh_impl::node{
-                    "", input_name_list, {"output"}, {{"axis", axis}}},
-                  {}, input_memory_table, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto lrn_test(std::string const& input_filename, float alpha,
-                          float beta, float bias, int size,
-                          std::string const& true_output_filename) {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto output_dims = extract_dims(input_memory);
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_lrn_primitive(
-                  menoh_impl::node{"",
-                                   {"input"},
-                                   {"output"},
-                                   {{"alpha", alpha},
-                                    {"beta", beta},
-                                    {"bias", bias},
-                                    {"size", size}}},
-                  {}, {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
-                /*
-                auto true_output = menoh_impl::load_np_array_as_array(
-                  "../data/lrn_alpha" + std::to_string(alpha) + "_beta" +
-                  std::to_string(beta) + "_bias" + std::to_string(bias) +
-                  "_size" + std::to_string(size) + ".txt");
-                */
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
-            }
-
-            auto gemm_test(std::string const& input_filename,
-                           std::string const& weight_filename,
-                           std::string const& bias_filename,
-                           std::string const& true_output_filename, float alpha,
-                           float beta, int trans_a, int trans_b) const {
-                auto input_memory =
-                  load_np_array_as_memory(input_filename, engine_);
-                auto weight =
-                  menoh_impl::load_np_array_as_array(weight_filename);
-                auto bias = menoh_impl::load_np_array_as_array(bias_filename);
-                std::vector<int> output_dims{extract_dims(input_memory).at(0),
-                                             weight.dims().at(0)};
-                auto output = array(dtype_t::float_, output_dims);
-                auto factory_return = make_gemm_primitive(
-                  menoh_impl::node{"",
-                                   {"input", "weight", "bias"},
-                                   {"output"},
-                                   {{"alpha", alpha},
-                                    {"beta", beta},
-                                    {"transA", trans_a},
-                                    {"transB", trans_b}}},
-                  {{"weight", weight}, {"bias", bias}},
-                  {{"input", input_memory}}, {{"output", output}}, engine_);
-                auto& net = std::get<0>(factory_return);
-                mkldnn::stream(mkldnn::stream::kind::eager).submit(net).wait();
 
-                auto true_output =
-                  menoh_impl::load_np_array_as_array(true_output_filename);
+                menoh::variable_profile_table_builder vpt_builder;
+                for(auto const& input : input_list) {
+                    vpt_builder.add_input_profile(input.name, input.dtype,
+                                                  input.dims);
+                }
+                for(auto const& output : true_output_list) {
+                    vpt_builder.add_output_profile(output.name, output.dtype);
+                }
+                auto onnx_model_filename = parent_dir_path / "model.onnx";
+                auto model_data =
+                  menoh::make_model_data_from_onnx(onnx_model_filename.str());
+                auto vpt = vpt_builder.build_variable_profile_table(model_data);
+                menoh::model_builder model_builder(vpt);
+
+                for(auto const& input : input_list) {
+                    model_builder.attach_external_buffer(
+                      input.name, static_cast<void*>(input.data.get()));
+                }
+                auto model =
+                  model_builder.build_model(model_data, backend_name);
+                model_data.reset();
 
-                assert_near_list(fbegin(output), fend(output),
-                                 fbegin(true_output), fend(true_output),
-                                 10.e-4);
+                std::vector<menoh::variable> output_list;
+                for(auto const& true_output : true_output_list) {
+                    output_list.push_back(model.get_variable(true_output.name));
+                }
+                model.run();
+                assert(true_output_list.size() == output_list.size());
+                auto static_cast_to_float_ptr = [](auto p) {
+                    return static_cast<float*>(static_cast<void*>(p));
+                };
+                for(int output_index = 0;
+                    output_index < true_output_list.size(); ++output_index) {
+                    auto const& input = input_list.front();
+                    auto const& output = output_list.at(output_index);
+                    auto const& true_output = true_output_list.at(output_index);
+                    auto total_size = std::accumulate(true_output.dims.begin(),
+                                                      true_output.dims.end(), 1,
+                                                      std::multiplies<int>());
+                    /*
+                    std::cout << true_output.name << std::endl;
+                    for(auto i = 0; i < 10; ++i) {
+                        std::cout
+                          << *(static_cast<float*>(
+                                 static_cast<void*>(input.data.get())) +
+                               i)
+                          << " "
+                          << *(static_cast<float*>(output.buffer_handle) + i)
+                          << " "
+                          << *(static_cast<float*>(
+                                 static_cast<void*>(true_output.data.get())) +
+                               i)
+                          << std::endl;
+                    }
+                    */
+                    menoh_impl::assert_eq_list(
+                      static_cast<float*>(output.buffer_handle),
+                      static_cast<float*>(output.buffer_handle) + total_size,
+                      static_cast_to_float_ptr(true_output.data.get()),
+                      static_cast_to_float_ptr(true_output.data.get()) +
+                        total_size,
+                      eps);
+                }
             }
-
-            mkldnn::engine engine_{mkldnn::engine::cpu, 0};
-        };
-
-        TEST_F(OperatorTest, relu_1d_test) {
-            relu_test("../data/random_input_3_4096.txt", "../data/relu_1d.txt");
-        }
-        TEST_F(OperatorTest, relu_2d_test) {
-            relu_test("../data/random_input_3_4_32_32.txt",
-                      "../data/relu_2d.txt");
-        }
-
-        TEST_F(OperatorTest, leaky_relu_1d_test) {
-            leaky_relu_test("../data/random_input_3_4096.txt",
-                            "../data/leaky_relu_1d.txt");
-        }
-        TEST_F(OperatorTest, leaky_relu_2d_test) {
-            leaky_relu_test("../data/random_input_3_4_32_32.txt",
-                            "../data/leaky_relu_2d.txt");
-        }
-
-        TEST_F(OperatorTest, elu_1d_test) {
-            elu_test("../data/random_input_3_4096.txt", "../data/elu_1d.txt");
-        }
-        TEST_F(OperatorTest, elu_2d_test) {
-            elu_test("../data/random_input_3_4_32_32.txt",
-                     "../data/elu_2d.txt");
-        }
-
-        TEST_F(OperatorTest, abs_1d_test) {
-            abs_test("../data/random_input_3_4096.txt", "../data/abs_1d.txt");
-        }
-        TEST_F(OperatorTest, abs_2d_test) {
-            abs_test("../data/random_input_3_4_32_32.txt",
-                     "../data/abs_2d.txt");
-        }
-
-        TEST_F(OperatorTest, sqrt_1d_test) {
-            sqrt_test("../data/random_positive_input_3_4096.txt",
-                      "../data/sqrt_1d.txt");
-        }
-        TEST_F(OperatorTest, sqrt_2d_test) {
-            sqrt_test("../data/random_positive_input_3_4_32_32.txt",
-                      "../data/sqrt_2d.txt");
-        }
-
-        TEST_F(OperatorTest, tanh_1d_test) {
-            tanh_test("../data/random_input_3_4096.txt", "../data/tanh_1d.txt");
-        }
-        TEST_F(OperatorTest, tanh_2d_test) {
-            tanh_test("../data/random_input_3_4_32_32.txt",
-                      "../data/tanh_2d.txt");
-        }
-
-        TEST_F(OperatorTest, softmax_1d_test) {
-            softmax_test("../data/random_input_3_4096.txt",
-                         "../data/softmax_1d.txt");
-        }
-        TEST_F(OperatorTest, softmax_2d_test) {
-            softmax_test("../data/random_input_3_4_32_32.txt",
-                         "../data/softmax_2d.txt");
-        }
-
-        TEST_F(OperatorTest, fc_1d_test) {
-            fc_test("../data/random_input_3_4096.txt",
-                    "../data/random_weight_256_4096.txt",
-                    "../data/random_bias_256.txt",
-                    "../data/linear_1d_w256_4096_b_256.txt");
-        }
-        TEST_F(OperatorTest, fc_2d_test) {
-            fc_test("../data/random_input_3_4_32_32.txt",
-                    "../data/random_weight_256_4096.txt",
-                    "../data/random_bias_256.txt",
-                    "../data/linear_2d_w256_4096_b_256.txt");
-        }
-
-        TEST_F(OperatorTest, max_pool_2_2_0_test) {
-            max_pool_test("../data/random_input_3_4_32_32.txt", 2, 2, 0);
-        }
-        TEST_F(OperatorTest, max_pool_3_2_0_test) {
-            max_pool_test("../data/random_input_3_4_32_32.txt", 3, 2, 0);
-        }
-        TEST_F(OperatorTest, max_pool_3_2_1_test) {
-            max_pool_test("../data/random_input_3_4_32_32.txt", 3, 2, 1);
-        }
-
-        TEST_F(OperatorTest, average_pool_2_2_0_test) {
-            average_pool_test("../data/random_input_3_4_32_32.txt", 2, 2, 0);
-        }
-        TEST_F(OperatorTest, average_pool_3_2_0_test) {
-            average_pool_test("../data/random_input_3_4_32_32.txt", 3, 2, 0);
-        }
-        TEST_F(OperatorTest, average_pool_3_2_1_test) {
-            average_pool_test("../data/random_input_3_4_32_32.txt", 3, 2, 1);
-        }
-
-        TEST_F(OperatorTest, global_max_pool_test) {
-            global_max_pool_test("../data/random_input_3_4_32_32.txt",
-                                 "../data/global_max_pooling_2d.txt");
-        }
-
-        TEST_F(OperatorTest, global_average_pool_test) {
-            global_average_pool_test("../data/random_input_3_4_32_32.txt",
-                                     "../data/global_average_pooling_2d.txt");
-        }
-
-        TEST_F(OperatorTest, conv_1_1_0_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 1, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_2_1_0_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 2, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_2_1_1_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 2, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_2_2_0_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 2, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_2_2_1_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 2, 2, 1);
-        }
-        TEST_F(OperatorTest, conv_3_1_1_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 3, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_3_2_0_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 3, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_3_2_1_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 3, 2, 1);
-        }
-        TEST_F(OperatorTest, conv_with_bias_1_1_0_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 1, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_with_bias_2_1_0_test) {
-            conv_test("../data/random_input_3_4_32_32.txt", 2, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_with_bias_2_1_1_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 2, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_with_bias_2_2_0_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 2, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_with_bias_2_2_1_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 2, 2, 1);
-        }
-        TEST_F(OperatorTest, conv_with_bias_3_1_1_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 3, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_with_bias_3_2_0_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 3, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_with_bias_3_2_1_test) {
-            conv_with_bias_test("../data/random_input_3_4_32_32.txt", 3, 2, 1);
-        }
-
-        TEST_F(OperatorTest, conv_transpose_1_1_0_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 1, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_2_1_0_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 2, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_2_1_1_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 2, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_2_2_0_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 2, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_2_2_1_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 2, 2, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_3_1_1_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 3, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_3_2_0_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 3, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_3_2_1_test) {
-            conv_transpose_test("../data/random_input_3_4_32_32.txt", 3, 2, 1);
-        }
-
-        TEST_F(OperatorTest, conv_transpose_with_bias_1_1_0_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          1, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_2_1_0_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          2, 1, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_2_1_1_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          2, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_2_2_0_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          2, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_2_2_1_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          2, 2, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_3_1_1_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          3, 1, 1);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_3_2_0_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          3, 2, 0);
-        }
-        TEST_F(OperatorTest, conv_transpose_with_bias_3_2_1_test) {
-            conv_transpose_with_bias_test("../data/random_input_3_4_32_32.txt",
-                                          3, 2, 1);
-        }
-
-        TEST_F(OperatorTest, batch_norm_test) {
-            batch_norm_test(
-              "../data/random_input_3_4_32_32.txt", "../data/random_mean_4.txt",
-              "../data/random_var_4.txt", "../data/random_gamma_4.txt",
-              "../data/random_beta_4.txt", "../data/batch_normalization.txt");
-        }
-
-        TEST_F(OperatorTest, add_1d_test) {
-            add_test("../data/random_input_3_4096.txt",
-                     "../data/random_input_3_4096.txt", "../data/add_1d.txt");
-        }
-        TEST_F(OperatorTest, add_2d_test) {
-            add_test("../data/random_input_3_4_32_32.txt",
-                     "../data/random_input_3_4_32_32.txt",
-                     "../data/add_2d.txt");
-        }
-
-        TEST_F(OperatorTest, concat_1d_2_inputs_axis_0_test) {
-            concat_test({"../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt"},
-                        0, "../data/concat_1d_6_4096.txt");
-        }
-        TEST_F(OperatorTest, concat_1d_2_inputs_axis_1_test) {
-            concat_test({"../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt"},
-                        1, "../data/concat_1d_3_8192.txt");
-        }
-        TEST_F(OperatorTest, concat_1d_3_inputs_axis_0_test) {
-            concat_test({"../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt"},
-                        0, "../data/concat_1d_9_4096.txt");
-        }
-        TEST_F(OperatorTest, concat_1d_3_inputs_axis_1_test) {
-            concat_test({"../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt",
-                         "../data/random_input_3_4096.txt"},
-                        1, "../data/concat_1d_3_12288.txt");
-        }
-
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_1_size_1_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 1, 1,
-                     "../data/lrn_alpha0.0001_beta0.75_bias1_size1.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_1_size_2_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 1, 2,
-                     "../data/lrn_alpha0.0001_beta0.75_bias1_size2.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_1_size_3_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 1, 3,
-                     "../data/lrn_alpha0.0001_beta0.75_bias1_size3.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_1_size_4_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 1, 4,
-                     "../data/lrn_alpha0.0001_beta0.75_bias1_size4.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_2_size_1_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 2, 1,
-                     "../data/lrn_alpha0.0001_beta0.75_bias2_size1.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_2_size_2_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 2, 2,
-                     "../data/lrn_alpha0.0001_beta0.75_bias2_size2.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_2_size_3_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 2, 3,
-                     "../data/lrn_alpha0.0001_beta0.75_bias2_size3.txt");
-        }
-        TEST_F(OperatorTest, lrn_alpha_00004_beta_075_bias_2_size_4_test) {
-            lrn_test("../data/random_input_3_4_32_32.txt", 0.0001, 0.75, 2, 4,
-                     "../data/lrn_alpha0.0001_beta0.75_bias2_size4.txt");
-        }
-
-        TEST_F(OperatorTest, gemm_1d_test) {
-            gemm_test("../data/random_input_3_4096.txt",
-                      "../data/random_weight_256_4096.txt",
-                      "../data/random_bias_256.txt",
-                      "../data/linear_1d_w256_4096_b_256.txt", 1, 1, 0, 1);
-        }
-        TEST_F(OperatorTest, gemm_2d_test) {
-            gemm_test("../data/random_input_3_4_32_32.txt",
-                      "../data/random_weight_256_4096.txt",
-                      "../data/random_bias_256.txt",
-                      "../data/linear_2d_w256_4096_b_256.txt", 1, 1, 0, 1);
-        }
-        TEST_F(OperatorTest, gemm_1d_test_invalid_alpha) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4096.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_1d_w256_4096_b_256.txt", 2, 1, 0,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_2d_test_invalid_alpha) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4_32_32.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_2d_w256_4096_b_256.txt", 2, 1, 0,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_1d_test_invalid_beta) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4096.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_1d_w256_4096_b_256.txt", 1, 2, 0,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_2d_test_invalid_beta) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4_32_32.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_2d_w256_4096_b_256.txt", 1, 2, 0,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_1d_test_invalid_transA) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4096.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_1d_w256_4096_b_256.txt", 1, 1, 1,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_2d_test_invalid_transA) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4_32_32.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_2d_w256_4096_b_256.txt", 1, 1, 1,
-                            1);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_1d_test_invalid_transB) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4096.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_1d_w256_4096_b_256.txt", 1, 1, 0,
-                            0);
-              },
-              failed_to_configure_operator);
-        }
-        TEST_F(OperatorTest, gemm_2d_test_invalid_transB) {
-            EXPECT_THROW(
-              {
-                  gemm_test("../data/random_input_3_4_32_32.txt",
-                            "../data/random_weight_256_4096.txt",
-                            "../data/random_bias_256.txt",
-                            "../data/linear_2d_w256_4096_b_256.txt", 1, 1, 0,
-                            0);
-              },
-              failed_to_configure_operator);
         }
 
-    } // namespace mkldnn_backend
-} // namespace menoh_impl
+    private:
+        filesystem::path onnx_test_data_dir_path_;
+    };
+
+#define TEST_OP(backend_name, test_name, eps) \
+    TEST_F(OperatorTest, test_name) { run_test(backend_name, #test_name, eps); }
+#define TEST_OP_SQUASH_DIMS(backend_name, test_name, eps) \
+    TEST_F(OperatorTest, test_name) {                     \
+        run_test(backend_name, #test_name, eps, true);    \
+    }
+
+    float eps = 1.e-4;
+    TEST_OP_SQUASH_DIMS("mkldnn", test_abs, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_elu, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_elu_default, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_leakyrelu, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_leakyrelu_default, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_relu, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_sqrt, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_tanh, eps);
+
+    TEST_OP("mkldnn", test_averagepool_2d_default, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_add, eps);
+    // TEST_OP_SQUASH_DIMS("mkldnn", test_batchnormalization, eps); // not found
+    // TEST_OP("mkldnn", test_concat_2d_axis_0, eps);
+    // TEST_OP("mkldnn", test_concat_2d_axis_1, eps);
+    // TEST_OP("mkldnn", test_conv_with_strides_padding, eps);
+    // TEST_OP_SQUASH_DIMS("mkldnn", test_convtranspose, eps); // not found
+    // TEST_OP("mkldnn", test_gemm_nobroadcast, eps);
+    TEST_OP("mkldnn", test_globalaveragepool, eps);
+    TEST_OP("mkldnn", test_globalmaxpool, eps);
+    TEST_OP("mkldnn", test_maxpool_2d_default, eps);
+    TEST_OP_SQUASH_DIMS("mkldnn", test_softmax_axis_1, eps);
+    // TEST_OP_SQUASH_DIMS("mkldnn", test_sum_one_input, eps);
+    // TEST_OP_SQUASH_DIMS("mkldnn", test_sum_two_inputs, eps);
+
+    // TEST_OP("mkldnn", test_averagepool_2d_pads, eps);
+    // TEST_OP("mkldnn", test_averagepool_2d_precomputed_pads, eps);
+    // TEST_OP("mkldnn", test_averagepool_2d_precomputed_same_upper, eps);
+
+#undef TEST_OP_SQUASH_DIMS
+#undef TEST_OP
+
+} // namespace

From 28e0474afba690c16b088b97808f3d35548da293 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 14 Sep 2018 23:58:15 +0900
Subject: [PATCH 127/321] remove comments

---
 test/operator.cpp | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 729e664..f67d65d 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -1,21 +1,3 @@
-/*
-#include <fstream>
-#include <iostream>
-#include <numeric>
-#include <sstream>
-#include <string>
-
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
-#include "./common.hpp"
-#include "np_io.hpp"
-
-#include <menoh/dims.hpp>
-#include <menoh/mkldnn/operator.hpp>
-#include <menoh/mkldnn/utility.hpp>
-#include <menoh/model_core.hpp>
-*/
 #include <gtest/gtest.h>
 
 #include <fstream>

From aaa52f3699bff1122c4dc709731708c5bf9ac9b9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 00:38:19 +0900
Subject: [PATCH 128/321] add inline keyword

---
 test/operator.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index f67d65d..8bef961 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -18,7 +18,8 @@
 #include "common.hpp"
 
 namespace menoh_impl {
-    dtype_t tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt);
+    inline dtype_t
+    tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt);
 }
 
 namespace {

From a9fe370556acab650b05e558507b9bed628898de Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 12:43:51 +0900
Subject: [PATCH 129/321] remove dependency to menoh_impl

---
 test/operator.cpp | 19 +++----------------
 1 file changed, 3 insertions(+), 16 deletions(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 8bef961..3a788df 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -9,19 +9,10 @@
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <onnx/onnx.pb.h>
 
-#include <menoh/array.hpp>
-#include <menoh/dtype.hpp>
-#include <menoh/onnx.hpp>
-
 #include <menoh/menoh.hpp>
 
 #include "common.hpp"
 
-namespace menoh_impl {
-    inline dtype_t
-    tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt);
-}
-
 namespace {
 
     struct named_array_data {
@@ -65,16 +56,12 @@ namespace {
           tensor.raw_data().length() ==
           static_cast<decltype(tensor.raw_data().length())>(total_size * 4));
 
-        using float_t =
-          menoh_impl::dtype_to_type_t<menoh_impl::dtype_t::float_>;
         auto data = std::make_unique<char[]>(total_size * 4);
         std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
                   data.get());
-        return named_array_data{
-          tensor.name(),
-          static_cast<menoh::dtype_t>(
-            menoh_impl::tensor_proto_data_type_to_dtype(tensor.data_type())),
-          std::move(dims), std::move(data)};
+        // TODO other dtype
+        return named_array_data{tensor.name(), menoh::dtype_t::float_,
+                                std::move(dims), std::move(data)};
     }
 
     class OperatorTest : public ::testing::Test {

From 5fb7dfee027f7c9fe792b120b7393125f3f398e7 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 14:18:23 +0900
Subject: [PATCH 130/321] indicate backend name when operator testing

---
 test/operator.cpp | 73 ++++++++++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 33 deletions(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 3a788df..9e0097b 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -174,43 +174,50 @@ namespace {
         filesystem::path onnx_test_data_dir_path_;
     };
 
-#define TEST_OP(backend_name, test_name, eps) \
-    TEST_F(OperatorTest, test_name) { run_test(backend_name, #test_name, eps); }
-#define TEST_OP_SQUASH_DIMS(backend_name, test_name, eps) \
-    TEST_F(OperatorTest, test_name) {                     \
-        run_test(backend_name, #test_name, eps, true);    \
-    }
+#define TEST_OP_IMPL(backend_name, test_name, eps, squash) \
+    TEST_F(OperatorTest, backend_name##_##test_name) { run_test(#backend_name, #test_name, eps, squash); }
+#define TEST_OP(backend_name, test_name, eps) TEST_OP_IMPL(backend_name, test_name, eps, false)
+#define TEST_OP_SQUASH_DIMS(backend_name, test_name, eps) TEST_OP_IMPL(backend_name, test_name, eps, true)
 
     float eps = 1.e-4;
-    TEST_OP_SQUASH_DIMS("mkldnn", test_abs, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_elu, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_elu_default, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_leakyrelu, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_leakyrelu_default, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_relu, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_sqrt, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_tanh, eps);
-
-    TEST_OP("mkldnn", test_averagepool_2d_default, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_add, eps);
-    // TEST_OP_SQUASH_DIMS("mkldnn", test_batchnormalization, eps); // not found
-    // TEST_OP("mkldnn", test_concat_2d_axis_0, eps);
-    // TEST_OP("mkldnn", test_concat_2d_axis_1, eps);
-    // TEST_OP("mkldnn", test_conv_with_strides_padding, eps);
-    // TEST_OP_SQUASH_DIMS("mkldnn", test_convtranspose, eps); // not found
-    // TEST_OP("mkldnn", test_gemm_nobroadcast, eps);
-    TEST_OP("mkldnn", test_globalaveragepool, eps);
-    TEST_OP("mkldnn", test_globalmaxpool, eps);
-    TEST_OP("mkldnn", test_maxpool_2d_default, eps);
-    TEST_OP_SQUASH_DIMS("mkldnn", test_softmax_axis_1, eps);
-    // TEST_OP_SQUASH_DIMS("mkldnn", test_sum_one_input, eps);
-    // TEST_OP_SQUASH_DIMS("mkldnn", test_sum_two_inputs, eps);
-
-    // TEST_OP("mkldnn", test_averagepool_2d_pads, eps);
-    // TEST_OP("mkldnn", test_averagepool_2d_precomputed_pads, eps);
-    // TEST_OP("mkldnn", test_averagepool_2d_precomputed_same_upper, eps);
+
+    // Tests for MKLDNN backend
+    TEST_OP_SQUASH_DIMS(mkldnn, test_abs, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_elu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_elu_default, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_leakyrelu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_leakyrelu_default, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_relu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_sqrt, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_tanh, eps);
+
+    TEST_OP(mkldnn, test_averagepool_2d_default, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_add, eps);
+    // TEST_OP_SQUASH_DIMS(mkldnn, test_batchnormalization, eps); // not found
+    // TEST_OP(mkldnn, test_concat_2d_axis_0, eps);
+    // TEST_OP(mkldnn, test_concat_2d_axis_1, eps);
+    // TEST_OP(mkldnn, test_conv_with_strides_padding, eps);
+    // TEST_OP_SQUASH_DIMS(mkldnn, test_convtranspose, eps); // not found
+    // TEST_OP(mkldnn, test_gemm_nobroadcast, eps);
+    TEST_OP(mkldnn, test_globalaveragepool, eps);
+    TEST_OP(mkldnn, test_globalmaxpool, eps);
+    TEST_OP(mkldnn, test_maxpool_2d_default, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn, test_softmax_axis_1, eps);
+    // TEST_OP_SQUASH_DIMS(mkldnn, test_sum_one_input, eps);
+    // TEST_OP_SQUASH_DIMS(mkldnn, test_sum_two_inputs, eps);
+
+    // TEST_OP(mkldnn, test_averagepool_2d_pads, eps);
+    // TEST_OP(mkldnn, test_averagepool_2d_precomputed_pads, eps);
+    // TEST_OP(mkldnn, test_averagepool_2d_precomputed_same_upper, eps);
+
+
+    // Tests for MKLDNN with Generic fallback backend
+    TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
+
+    TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP
+#undef TEST_OP_IMPL
 
 } // namespace

From 7d27e9737f9b6c38cc140121a41c5d61b7a2dd79 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 16 Sep 2018 21:26:25 +0900
Subject: [PATCH 131/321] modify shape inference for test

---
 menoh/graph.cpp | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 569f193..2a049f9 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -250,16 +250,20 @@ namespace menoh_impl {
         std::unordered_map<std::string, std::vector<int>> variable_dims_table(
           input_name_and_dims_pair_list.begin(),
           input_name_and_dims_pair_list.end());
-        auto graph = make_graph(model_data.node_list);
-        auto parameter_table = std::unordered_map<std::string, array>(
+        std::transform(
           model_data.parameter_name_and_array_list.begin(),
-          model_data.parameter_name_and_array_list.end());
+          model_data.parameter_name_and_array_list.end(),
+          std::inserter(variable_dims_table, variable_dims_table.end()),
+          [](auto const& p) {
+              return std::make_pair(p.first, p.second.dims());
+          });
+        auto graph = make_graph(model_data.node_list);
         for(auto const& node : graph.node_list()) {
             if(node.op_type == "Conv") {
                 auto weight_name = node.input_name_list.at(1);
                 auto output_channel_num =
                   get_output_channel_num_from_parameter_dims(
-                    find_value(parameter_table, weight_name).dims());
+                    find_value(variable_dims_table, weight_name));
                 auto output_dims = calc_2d_output_dims(node, output_channel_num,
                                                        variable_dims_table);
                 auto dilations =
@@ -283,7 +287,7 @@ namespace menoh_impl {
                 auto weight_name = node.input_name_list.at(1);
                 auto output_channel_num =
                   get_output_channel_num_from_parameter_dims(
-                    find_value(parameter_table, weight_name).dims());
+                    find_value(variable_dims_table, weight_name));
                 auto output_dims = calc_2d_output_dims_for_conv_transpose(
                   node, output_channel_num, variable_dims_table);
                 auto dilations =
@@ -339,8 +343,7 @@ namespace menoh_impl {
                 auto batch_size = get_batch_size_from_variable_dims(
                   find_value(variable_dims_table, input_name));
                 auto weight_dims =
-                  find_value(parameter_table, node.input_name_list.at(1))
-                    .dims();
+                  find_value(variable_dims_table, node.input_name_list.at(1));
                 auto input_size =
                   std::accumulate(input_dims.begin() + 1, input_dims.end(), 1,
                                   std::multiplies<void>());
@@ -359,8 +362,7 @@ namespace menoh_impl {
                 auto batch_size = get_batch_size_from_variable_dims(
                   find_value(variable_dims_table, input_name));
                 auto weight_dims =
-                  find_value(parameter_table, node.input_name_list.at(1))
-                    .dims();
+                  find_value(variable_dims_table, node.input_name_list.at(1));
                 auto trans_a = optional_attribute_int(node, "transA", 0);
                 if(trans_a) {
                     throw unsupported_operator_attribute(

From 93f87e355a213ed9ddbccd03594b55f616ec1fbb Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 14 Sep 2018 19:14:57 +0900
Subject: [PATCH 132/321] fix to install mkldnn under ${HOME} in coverity build

---
 .travis.yml                   | 32 +++++++++---------
 .travis/README.md             |  2 +-
 .travis/build-menoh.sh        | 14 ++++++--
 .travis/init-build-linux.sh   | 27 ++++++++-------
 .travis/init-build-osx.sh     |  5 +--
 .travis/linux-x86_64/build.sh |  2 +-
 .travis/prepare-menoh-data.sh |  2 +-
 .travis/run-build.sh          | 62 ++++++++++++++++-------------------
 8 files changed, 78 insertions(+), 68 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a013fd5..77131b7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,6 +30,7 @@ matrix:
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
+        # Use Travis directly instead of container to run static code analysis using Coverity
         - os: linux
           env: RUN_COVERITY=true
           addons:
@@ -52,7 +53,9 @@ matrix:
                   notification_email: menoh-oss@preferred.jp
                   build_command_prepend: >-
                       cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
-                      cmake .
+                          cmake
+                              -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn-${MKLDNN_VERSION}/include"
+                              -DMKLDNN_LIBRARY="$HOME/mkl-dnn-${MKLDNN_VERSION}/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
           before_install:
@@ -64,29 +67,24 @@ matrix:
                     --version ${MKLDNN_VERSION} \
                     --download-dir ${HOME}/downloads \
                     --build-dir ${HOME}/build \
-                    --install-dir /usr/local \
+                    --install-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION} \
                     --parallel ${MAKE_JOBS}
               - pip install --user chainer
-              - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/prepare-menoh-data.sh \
-                    --source-dir ${TRAVIS_BUILD_DIR} \
-                    --python-executable python
           script:
               #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
               # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
               - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
-              - if [ -d "build" ]; then mkdir -p build; fi
-              - cd build
-              - cmake -DENABLE_TEST=ON ..
-              - make
+              - |
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/build-menoh.sh \
+                    --source-dir ${TRAVIS_BUILD_DIR} \
+                    --mkldnn-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION}
+              - |
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/prepare-menoh-data.sh \
+                    --source-dir ${TRAVIS_BUILD_DIR} \
+                    --python-executable python
+              - cd ${TRAVIS_BUILD_DIR}/build
               - ./test/menoh_test
               - ldd menoh/libmenoh.so
 
 script:
-    - |
-      echo "travis_fold:start:run-build.sh"
-      echo -e "\e[33;1mRunning .travis/run-build.sh\e[0m"
-
-      bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh
-
-      echo "travis_fold:end:run-build.sh"
+    - bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh
diff --git a/.travis/README.md b/.travis/README.md
index 5f0d845..1fdf3ca 100644
--- a/.travis/README.md
+++ b/.travis/README.md
@@ -18,7 +18,7 @@ Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/)
     - It runs a Docker container before calling `build.sh` if it is in the Linux-based platforms
     - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
 2. `build.sh`
-    - In Linux, the build workflow is run *in the container*. All commands are run by `docker_exec` and `docker_exec_cmd` functions
+    - In Linux, the build workflow is run *in the container*. All commands are run by `docker_exec` and `docker_exec_script` functions
     - Install the prerequisites
     - Run a build
     - Run a test
diff --git a/.travis/build-menoh.sh b/.travis/build-menoh.sh
index 35fcf1c..4d35f01 100644
--- a/.travis/build-menoh.sh
+++ b/.travis/build-menoh.sh
@@ -15,6 +15,10 @@ while [[ $# != 0 ]]; do
             ARG_INSTALL_DIR="$2"
             shift 2
             ;;
+        --mkldnn-dir)
+            ARG_MKLDNN_DIR="$2"
+            shift 2
+            ;;
         --link-static-libgcc)
             ARG_LINK_STATIC_LIBGCC="$2"
             shift 2
@@ -52,11 +56,17 @@ cd ${ARG_SOURCE_DIR}
 
 cd build
 if [ -n "${ARG_INSTALL_DIR}" ]; then
-    CMAKE_INSTALL_PREFIX="-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}"
+    OPT_CMAKE_INSTALL_PREFIX=-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}
+fi
+if [ -n "${ARG_MKLDNN_DIR}" ]; then
+    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
+    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 cmake \
     -DCMAKE_BUILD_TYPE=Release \
-    ${CMAKE_INSTALL_PREFIX} \
+    ${OPT_CMAKE_INSTALL_PREFIX} \
+    ${OPT_MKLDNN_INCLUDE_DIR} \
+    ${OPT_MKLDNN_LIBRARY} \
     -DLINK_STATIC_LIBGCC=${ARG_LINK_STATIC_LIBGCC} \
     -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
     -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index b2fe7c1..a9b84f1 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -1,8 +1,8 @@
 # check if variables are set
-test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID does not exist" 1>&2; exit 1; }
-test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION does not exist" 1>&2; exit 1; }
-test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION does not exist" 1>&2; exit 1; }
-test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist" 1>&2; exit 1; }
+test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID can't be empty" 1>&2; exit 1; }
+test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION can't be empty" 1>&2; exit 1; }
+test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION can't be empty" 1>&2; exit 1; }
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
 
 test -n "${LINK_STATIC}" || LINK_STATIC=false
 
@@ -13,17 +13,22 @@ export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 export PROTOBUF_INSTALL_DIR=/usr/local
 export MKLDNN_INSTALL_DIR=/usr/local
 
-# define shared functions for Linux-based platforms
+## define shared functions for Linux-based platforms
+
+# Run the specified string as command in the container
 function docker_exec() {
     docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xec "$1"
+    return $?
 }
 
-function docker_exec_cmd() {
+# Run the specified shell script in the container
+function docker_exec_script() {
     docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xe $@
+    return $?
 }
 
 function install_protobuf() {
-    docker_exec_cmd \
+    docker_exec_script \
         ${PROJ_DIR}/.travis/install-protobuf.sh \
             --version ${PROTOBUF_VERSION} \
             --download-dir ${WORK_DIR}/downloads \
@@ -33,7 +38,7 @@ function install_protobuf() {
 }
 
 function install_mkldnn() {
-    docker_exec_cmd \
+    docker_exec_script \
         ${PROJ_DIR}/.travis/install-mkldnn.sh \
             --version ${MKLDNN_VERSION} \
             --download-dir ${WORK_DIR}/downloads \
@@ -43,7 +48,7 @@ function install_mkldnn() {
 }
 
 function prepare_menoh_data() {
-    docker_exec_cmd \
+    docker_exec_script \
         ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
             --source-dir ${PROJ_DIR} \
             --python-executable python3
@@ -51,11 +56,11 @@ function prepare_menoh_data() {
 
 function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
-        docker_exec_cmd \
+        docker_exec_script \
             ${PROJ_DIR}/.travis/build-menoh.sh \
                 --source-dir ${PROJ_DIR}
     else
-        docker_exec_cmd \
+        docker_exec_script \
             ${PROJ_DIR}/.travis/build-menoh.sh \
                 --source-dir ${PROJ_DIR} \
                 --link-static-libgcc ON \
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 619f119..fb8a6e9 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -1,5 +1,5 @@
 # check if variables are set
-test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS does not exist" 1>&2; exit 1; }
+test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
 
 # TODO: make them configurable for outside Travis
 export WORK_DIR=${HOME}
@@ -24,7 +24,8 @@ function build_menoh() {
 }
 
 function test_menoh() {
-    cd ${PROJ_DIR}/build && ./test/menoh_test
+    cd ${PROJ_DIR}/build
+    ./test/menoh_test
 }
 
 function check_menoh_artifact() {
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index d08f8f7..828af83 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -18,7 +18,7 @@ install_mkldnn
 
 docker_exec "pip3 install --user chainer" # for generating test data
 
-docker_exec "yum list installed"
+docker_exec "rpm -qa"
 docker_exec "pip3 list"
 
 # build and test menoh
diff --git a/.travis/prepare-menoh-data.sh b/.travis/prepare-menoh-data.sh
index fa19dba..e82bf44 100644
--- a/.travis/prepare-menoh-data.sh
+++ b/.travis/prepare-menoh-data.sh
@@ -27,7 +27,7 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_SOURCE_DIR}" || { echo "ARG_SOURCE_DIR does not exist" 1>&2; exit 1; }
+test -n "${ARG_SOURCE_DIR}" || { echo "ARG_SOURCE_DIR can't be empty" 1>&2; exit 1; }
 test -n "${ARG_PYTHON_EXECUTABLE}" || ARG_PYTHON_EXECUTABLE=python
 
 echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
diff --git a/.travis/run-build.sh b/.travis/run-build.sh
index 84b5d21..9b24043 100644
--- a/.travis/run-build.sh
+++ b/.travis/run-build.sh
@@ -1,51 +1,47 @@
 #!/bin/bash
 
 # check if variables have values
-test -n "${PLATFORM}" || { echo "PLATFORM does not exist" 1>&2; exit 1; }
+test -n "${PLATFORM}" || { echo "PLATFORM can't be empty" 1>&2; exit 1; }
 
 export PLATFORM_DIR=${TRAVIS_BUILD_DIR}/.travis/${PLATFORM}
 
 # "$TRAVIS_OS_NAME" == "linux"
 if [[ "$PLATFORM" == "linux-x86" ]] || [[ "$PLATFORM" == "linux-x86_64" ]] || [[ "$PLATFORM" =~ android ]]; then
-    test -n "${BUILDENV_IMAGE}" || { echo "BUILDENV_IMAGE does not exist" 1>&2; exit 1; }
+    if [ -n "${BUILDENV_IMAGE}" ]; then
+        docker pull ${BUILDENV_IMAGE} || true
 
-    docker pull ${BUILDENV_IMAGE} || true
+        # Run a docker container and map Travis's $HOME to the container's $HOME
+        # $HOME:$HOME = /home/travis                     : /home/travis
+        #               /home/travis/build               : /home/travis/build
+        #               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
+        # TODO: the ownership of files and directories mounted on the container
+        export DOCKER_CONTAINER_ID=$(docker run -d -it -v $HOME:$HOME -v /sys/fs/cgroup:/sys/fs/cgroup:ro ${BUILDENV_IMAGE} /bin/bash)
 
-    # Run a docker container and map Travis's $HOME to the container's $HOME
-    # $HOME:$HOME = /home/travis                     : /home/travis
-    #               /home/travis/build               : /home/travis/build
-    #               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
-    # TODO: the ownership of files and directories mounted on the container
-    export DOCKER_CONTAINER_ID=$(docker run -d -it -v $HOME:$HOME -v /sys/fs/cgroup:/sys/fs/cgroup:ro ${BUILDENV_IMAGE} /bin/bash)
+        # Note: You shouldn't do `docker run` with `--privileged /sbin/init`.
+        # See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
 
-    # Note: You shouldn't do `docker run` with `--privileged /sbin/init`.
-    # See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
+        if [ -z "${DOCKER_CONTAINER_ID}" ]; then
+            echo 'Failed to run a Docker container: '${BUILDENV_IMAGE} 1>&2
+            exit 1
+        fi
 
-    if [ -z "${DOCKER_CONTAINER_ID}" ]; then
-        echo 'Failed to run a Docker container: '${BUILDENV_IMAGE} 1>&2
-        exit 1
-    fi
-
-    # Stop the container when run-build.sh exits
-    trap '[[ "$DOCKER_CONTAINER_ID" ]] && docker stop ${DOCKER_CONTAINER_ID} && docker rm -v ${DOCKER_CONTAINER_ID}' 0 1 2 3 15
-
-    docker logs ${DOCKER_CONTAINER_ID}
+        # Stop the container when run-build.sh exits
+        trap '[[ "${DOCKER_CONTAINER_ID}" ]] && docker stop ${DOCKER_CONTAINER_ID} && docker rm -v ${DOCKER_CONTAINER_ID}' 0 1 2 3 15
 
-    if [ -e "${PLATFORM_DIR}/build.sh" ]; then
-        # Dispatch to the platform specific script
-        /bin/bash -ex ${PLATFORM_DIR}/build.sh
-    else
-        echo 'The specified platform not found: '${PLATFORM} 1>&2
-        exit 1
+        docker logs ${DOCKER_CONTAINER_ID}
     fi
 fi
 
 if [ "$TRAVIS_OS_NAME" == "osx" ]; then
-    if [ -e "${PLATFORM_DIR}/build.sh" ]; then
-        # Dispatch to the platform specific script
-        /bin/bash -ex ${PLATFORM_DIR}/build.sh
-    else
-        echo 'The specified platform not found: '${PLATFORM} 1>&2
-        exit 1
-    fi
+    true
+fi
+
+# Dispatch to platform specific build script
+if [ -e "${PLATFORM_DIR}/build.sh" ]; then
+    /bin/bash -ex ${PLATFORM_DIR}/build.sh
+    result=$?
+    exit ${result}
+else
+    echo 'The specified platform not found: '${PLATFORM} 1>&2
+    exit 1
 fi

From 66659c9d31cfe114ac859c22b3371b6a3d5117e5 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 18 Sep 2018 02:34:42 +0900
Subject: [PATCH 133/321] add run-container.sh

---
 .travis/README.md              |  7 ++---
 .travis/init-build-linux.sh    | 13 ++++++---
 .travis/linux-x86_64/build.sh  |  2 +-
 .travis/macosx-x86_64/build.sh |  2 +-
 .travis/run-build.sh           | 33 ++++-------------------
 .travis/run-container.sh       | 49 ++++++++++++++++++++++++++++++++++
 6 files changed, 70 insertions(+), 36 deletions(-)
 create mode 100644 .travis/run-container.sh

diff --git a/.travis/README.md b/.travis/README.md
index 1fdf3ca..c28634b 100644
--- a/.travis/README.md
+++ b/.travis/README.md
@@ -15,10 +15,11 @@ Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/)
 `.travis.yml` -> `run-build.sh` -> `build.sh` -> `install-*.sh` & `build-menoh.sh`
 
 1. `run-build.sh` calls `build.sh` at once for running the actual build workflow
-    - It runs a Docker container before calling `build.sh` if it is in the Linux-based platforms
-    - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
 2. `build.sh`
-    - In Linux, the build workflow is run *in the container*. All commands are run by `docker_exec` and `docker_exec_script` functions
+    - In Linux-based platforms, build workflow is run *in the container*
+        - It runs a Docker container before executing the workflow
+        - All commands are run via `docker_exec` and `docker_exec_script` functions
+        - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
     - Install the prerequisites
     - Run a build
     - Run a test
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index a9b84f1..5e6ef37 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -1,5 +1,4 @@
 # check if variables are set
-test -n "${DOCKER_CONTAINER_ID}" || { echo "DOCKER_CONTAINER_ID can't be empty" 1>&2; exit 1; }
 test -n "${PROTOBUF_VERSION}" || { echo "PROTOBUF_VERSION can't be empty" 1>&2; exit 1; }
 test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION can't be empty" 1>&2; exit 1; }
 test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
@@ -13,17 +12,25 @@ export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 export PROTOBUF_INSTALL_DIR=/usr/local
 export MKLDNN_INSTALL_DIR=/usr/local
 
+# Run a docker container and map Travis's $HOME to the container's $HOME
+# $HOME:$HOME = /home/travis                     : /home/travis
+#               /home/travis/build               : /home/travis/build
+#               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
+SHARED_SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+source ${SHARED_SCRIPT_DIR}/run-container.sh --image ${BUILDENV_IMAGE} --work-dir ${WORK_DIR}
+test -n "${BUILDENV_CONTAINER_ID}" || { echo "BUILDENV_CONTAINER_ID can't be empty" 1>&2; exit 1; }
+
 ## define shared functions for Linux-based platforms
 
 # Run the specified string as command in the container
 function docker_exec() {
-    docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xec "$1"
+    docker exec -it ${BUILDENV_CONTAINER_ID} /bin/bash -xec "$1"
     return $?
 }
 
 # Run the specified shell script in the container
 function docker_exec_script() {
-    docker exec -it ${DOCKER_CONTAINER_ID} /bin/bash -xe $@
+    docker exec -it ${BUILDENV_CONTAINER_ID} /bin/bash -xe $@
     return $?
 }
 
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index 828af83..0af7711 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -ex
 
-BASE_DIR=$(cd $(dirname $0) && pwd)
+BASE_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
 
 # initialize this script
 source ${BASE_DIR}/../init-build-linux.sh
diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index e63e625..a81b8ca 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-BASE_DIR=$(cd $(dirname $0) && pwd)
+BASE_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
 
 # initialize this script
 source ${BASE_DIR}/../init-build-osx.sh
diff --git a/.travis/run-build.sh b/.travis/run-build.sh
index 9b24043..fbcae03 100644
--- a/.travis/run-build.sh
+++ b/.travis/run-build.sh
@@ -5,34 +5,11 @@ test -n "${PLATFORM}" || { echo "PLATFORM can't be empty" 1>&2; exit 1; }
 
 export PLATFORM_DIR=${TRAVIS_BUILD_DIR}/.travis/${PLATFORM}
 
-# "$TRAVIS_OS_NAME" == "linux"
-if [[ "$PLATFORM" == "linux-x86" ]] || [[ "$PLATFORM" == "linux-x86_64" ]] || [[ "$PLATFORM" =~ android ]]; then
-    if [ -n "${BUILDENV_IMAGE}" ]; then
-        docker pull ${BUILDENV_IMAGE} || true
-
-        # Run a docker container and map Travis's $HOME to the container's $HOME
-        # $HOME:$HOME = /home/travis                     : /home/travis
-        #               /home/travis/build               : /home/travis/build
-        #               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
-        # TODO: the ownership of files and directories mounted on the container
-        export DOCKER_CONTAINER_ID=$(docker run -d -it -v $HOME:$HOME -v /sys/fs/cgroup:/sys/fs/cgroup:ro ${BUILDENV_IMAGE} /bin/bash)
-
-        # Note: You shouldn't do `docker run` with `--privileged /sbin/init`.
-        # See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
-
-        if [ -z "${DOCKER_CONTAINER_ID}" ]; then
-            echo 'Failed to run a Docker container: '${BUILDENV_IMAGE} 1>&2
-            exit 1
-        fi
-
-        # Stop the container when run-build.sh exits
-        trap '[[ "${DOCKER_CONTAINER_ID}" ]] && docker stop ${DOCKER_CONTAINER_ID} && docker rm -v ${DOCKER_CONTAINER_ID}' 0 1 2 3 15
-
-        docker logs ${DOCKER_CONTAINER_ID}
-    fi
-fi
-
-if [ "$TRAVIS_OS_NAME" == "osx" ]; then
+if [ "$TRAVIS_OS_NAME" == "linux" ]; then
+    # Run some setup procedures (basically it should be done in build.sh)
+    true
+elif [ "$TRAVIS_OS_NAME" == "osx" ]; then
+    # Run some setup procedures (basically it should be done in build.sh)
     true
 fi
 
diff --git a/.travis/run-container.sh b/.travis/run-container.sh
new file mode 100644
index 0000000..cf3f481
--- /dev/null
+++ b/.travis/run-container.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# Run a container for building source code and set it's container ID to ${BUILDENV_CONTAINER_ID}
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --image)
+            ARG_IMAGE="$2"
+            shift 2
+            ;;
+        --work-dir)
+            ARG_WORK_DIR="$2"
+            shift 2
+            ;;
+        -*)
+            err Unknown option \"$1\"
+            exit
+            ;;
+        *)
+            break
+            ;;
+
+    esac
+done
+
+unset BUILDENV_CONTAINER_ID
+
+docker pull ${ARG_IMAGE} || true
+
+# TODO: the ownership of files and directories mounted on the container
+export BUILDENV_CONTAINER_ID=$(docker run -d -it -v ${ARG_WORK_DIR}:${ARG_WORK_DIR} -v /sys/fs/cgroup:/sys/fs/cgroup:ro ${ARG_IMAGE} /bin/bash)
+
+# Note: You shouldn't do `docker run` with `--privileged /sbin/init`.
+# See https://bugzilla.redhat.com/show_bug.cgi?id=1046469 for the details.
+
+if [ -z "${BUILDENV_CONTAINER_ID}" ]; then
+    echo 'Failed to run a Docker container: '${ARG_IMAGE} 1>&2
+    exit 1
+fi
+
+# Stop the container when run-build.sh exits
+trap '[[ "${BUILDENV_CONTAINER_ID}" ]] && docker stop ${BUILDENV_CONTAINER_ID} && docker rm -v ${BUILDENV_CONTAINER_ID}' 0 1 2 3 15
+
+docker logs ${BUILDENV_CONTAINER_ID}

From 7a8e18652ae87c9664d3d131cd3d077e20384f47 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 18 Sep 2018 11:04:08 +0900
Subject: [PATCH 134/321] update README.md

---
 .travis/README.md         | 11 ++++++-----
 .travis/init-build-osx.sh |  4 +++-
 2 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/.travis/README.md b/.travis/README.md
index c28634b..1ef0312 100644
--- a/.travis/README.md
+++ b/.travis/README.md
@@ -14,12 +14,13 @@ Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/)
 ## Architecture
 `.travis.yml` -> `run-build.sh` -> `build.sh` -> `install-*.sh` & `build-menoh.sh`
 
-1. `run-build.sh` calls `build.sh` at once for running the actual build workflow
+1. `run-build.sh` just calls a platform's `build.sh` for running the actual build workflow
 2. `build.sh`
-    - In Linux-based platforms, build workflow is run *in the container*
-        - It runs a Docker container before executing the workflow
-        - All commands are run via `docker_exec` and `docker_exec_script` functions
-        - You can access `${HOME}` (`/home/travis`) directory from the container transparently because it maps `${HOME}` in the Travis environment to container's `/home/travis`
+    - For Linux-based platforms, the build workflow is executed *in the container*
+        - `build.sh` runs a Docker container at startup before executing the workflow
+        - All commands are run via `docker_exec` and `docker_exec_script` functions (defined in `init-build-linux.sh`)
+        - You can access `${HOME}` (`/home/travis`) directory from inside the container transparently because it maps `/home/travis` in the Travis environment to container's `/home/travis`
+    - For macOS (OSX), the build workflow is executed on the Travis' VM
     - Install the prerequisites
     - Run a build
     - Run a test
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index fb8a6e9..627e070 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -5,6 +5,8 @@ test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
 export WORK_DIR=${HOME}
 export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 
+## define shared functions for macOS (OSX) platforms
+
 function prepare_menoh_data() {
     bash -ex ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
         --source-dir ${PROJ_DIR} \
@@ -16,7 +18,7 @@ function build_menoh() {
         bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
             --source-dir ${PROJ_DIR}
     else
-    	# Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
+        # Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
         bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
             --source-dir ${PROJ_DIR} \
             --link-static-libprotobuf ON

From 21e73aba612767dca8e9b9169bd52830f5ca80d8 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 18 Sep 2018 15:48:30 +0900
Subject: [PATCH 135/321] remove the indents in YAML file

---
 .travis.yml                 | 6 +++---
 .travis/init-build-linux.sh | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 77131b7..a734d51 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -53,9 +53,9 @@ matrix:
                   notification_email: menoh-oss@preferred.jp
                   build_command_prepend: >-
                       cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
-                          cmake
-                              -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn-${MKLDNN_VERSION}/include"
-                              -DMKLDNN_LIBRARY="$HOME/mkl-dnn-${MKLDNN_VERSION}/lib/libmkldnn.so" .
+                      cmake
+                      -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn-${MKLDNN_VERSION}/include"
+                      -DMKLDNN_LIBRARY="$HOME/mkl-dnn-${MKLDNN_VERSION}/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
           before_install:
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index 5e6ef37..1c4eaba 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -81,5 +81,5 @@ function test_menoh() {
 }
 
 function check_menoh_artifact() {
-    ldd ${PROJ_DIR}/build/menoh/libmenoh.so
+    docker_exec "ldd ${PROJ_DIR}/build/menoh/libmenoh.so"
 }

From cc2c0fb3c76da40314d8d1a0e30f1f9e598c61e0 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 18 Sep 2018 16:23:38 +0900
Subject: [PATCH 136/321] skip build and test in the Coverity case

---
 .travis.yml | 20 +++-----------------
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index a734d51..fb09b92 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,7 +31,8 @@ matrix:
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
         # Use Travis directly instead of container to run static code analysis using Coverity
-        - os: linux
+        - if: branch = coverity_scan
+          os: linux
           env: RUN_COVERITY=true
           addons:
               apt:
@@ -69,22 +70,7 @@ matrix:
                     --build-dir ${HOME}/build \
                     --install-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION} \
                     --parallel ${MAKE_JOBS}
-              - pip install --user chainer
-          script:
-              #- if [ -f cov-int/build-log.txt ]; then cat cov-int/build-log.txt; fi
-              # CMakeCache.txt generated for coverity_scan build hinders out-of-source build
-              - if [ -f CMakeCache.txt ]; then rm CMakeCache.txt; fi
-              - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/build-menoh.sh \
-                    --source-dir ${TRAVIS_BUILD_DIR} \
-                    --mkldnn-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION}
-              - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/prepare-menoh-data.sh \
-                    --source-dir ${TRAVIS_BUILD_DIR} \
-                    --python-executable python
-              - cd ${TRAVIS_BUILD_DIR}/build
-              - ./test/menoh_test
-              - ldd menoh/libmenoh.so
+          script: true # skip build and test
 
 script:
     - bash -ex ${TRAVIS_BUILD_DIR}/.travis/run-build.sh

From 7334cb6da6ee37eb81c73be4557844ad82a8b821 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 18 Sep 2018 19:33:34 +0900
Subject: [PATCH 137/321] use --template in cov-configure

---
 .travis.yml | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index fb09b92..b2233ef 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -53,14 +53,10 @@ matrix:
                       description: "Menoh: DNN inference library"
                   notification_email: menoh-oss@preferred.jp
                   build_command_prepend: >-
-                      cov-configure --compiler /usr/bin/g++-7 --comptype g++ -- -march=native -fPIC -std=gnu++14 &&
-                      cmake
-                      -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn-${MKLDNN_VERSION}/include"
-                      -DMKLDNN_LIBRARY="$HOME/mkl-dnn-${MKLDNN_VERSION}/lib/libmkldnn.so" .
+                      cov-configure --compiler g++-7 --comptype g++ --template &&
+                      cmake -DMKLDNN_INCLUDE_DIR="$HOME/mkl-dnn-${MKLDNN_VERSION}/include" -DMKLDNN_LIBRARY="$HOME/mkl-dnn-${MKLDNN_VERSION}/lib/libmkldnn.so" .
                   build_command: make
                   branch_pattern: coverity_scan
-          before_install:
-              - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
           install:
               - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
               - |

From 3859191a10d7e338430d0b36fc5f0a410d33a7b2 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 19 Sep 2018 16:06:13 +0900
Subject: [PATCH 138/321] appveyor: fix to pass static linking option in MINGW
 build

I change to use -DLINK_STATIC_LIBPROTOBUF=ON unconditionally
in the commit 3a76eca9df6d3f6bcd5246fc79f60d8a3b669f5a, but
that was my mistake.
---
 appveyor.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/appveyor.yml b/appveyor.yml
index 90e1e4a..79fe31f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -69,7 +69,7 @@ build_script:
     )
   )
 - if [%TARGET%]==[mingw] (
-    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON -DLINK_STATIC_LIBPROTOBUF=ON -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
+    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
     make
   ) else (
     cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DENABLE_TOOL=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&

From a79c0593036cb36c311d1971159c609d73680264 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 19 Sep 2018 17:45:02 +0900
Subject: [PATCH 139/321] remove gemm test

---
 test/operator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 9e0097b..53893ed 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -214,7 +214,7 @@ namespace {
     // Tests for MKLDNN with Generic fallback backend
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
 
-    TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP

From bdd89ecbb2e5f2f97cf06181f8f9d222f8c96a62 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 19 Sep 2018 17:53:40 +0900
Subject: [PATCH 140/321] appveyor: add messages to split outputs of multiple
 ldd invocations

---
 appveyor.yml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/appveyor.yml b/appveyor.yml
index 79fe31f..ccfe61b 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -80,9 +80,12 @@ test_script:
 # to find libmenoh.dll, libgtest.dll and libgtest_main.dll
 - if [%TARGET%]==[mingw] set PATH=C:\projects\menoh\build\menoh;C:\projects\menoh\build\test\lib\googletest\googlemock\gtest;C:\msys64\mkl-dnn-86b7129-mingw\bin;%PATH%
 - if [%TARGET%]==[mingw] (
-    ldd test/menoh_test.exe &&
+    echo "ldd libmenoh.dll" &&
     ldd /c/projects/menoh/build/menoh/libmenoh.dll &&
+    echo "ldd libmkldnn.dll" &&
     ldd /mingw64/bin/libmkldnn.dll &&
+    echo "ldd menoh_test.exe" &&
+    ldd test/menoh_test.exe &&
     test\menoh_test
   )
 - cd ..

From 1e7eba6aae7acbba96be457d05e92267d47a529c Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 19 Sep 2018 17:13:59 +0900
Subject: [PATCH 141/321] fix to accept arbitrary options

---
 cmake/SetupProtobuf.cmake |  2 +-
 cmake/configure-helper.sh | 47 ++++++++++++++++++++++++++++++---------
 2 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 327edf4..8341490 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -24,7 +24,7 @@ if(LINK_STATIC_LIBPROTOBUF)
             URL_HASH ${PROTOBUF_HASH}
             DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
             BUILD_IN_SOURCE 1
-            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER} ${PROTOBUF_DIR} ${PROTOBUF_CFLAGS} ${PROTOBUF_CXXFLAGS}
+            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh --CC ${CMAKE_C_COMPILER} --CXX ${CMAKE_CXX_COMPILER} -- --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
             BUILD_COMMAND make -j4
             INSTALL_COMMAND make install
         )
diff --git a/cmake/configure-helper.sh b/cmake/configure-helper.sh
index 515fa34..91704cd 100644
--- a/cmake/configure-helper.sh
+++ b/cmake/configure-helper.sh
@@ -1,14 +1,41 @@
 #!/bin/bash -ex
 
-c_compiler=$1
-cxx_compiler=$2
-prefix=$3
-cflags=$4
-cxxflags=$5
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --CC)
+            ARG_CC="$2"
+            shift 2
+            ;;
+        --CPP)
+            ARG_CPP="$2"
+            shift 2
+            ;;
+        --CXX)
+            ARG_CXX="$2"
+            shift 2
+            ;;
+        --CXXCPP)
+            ARG_CXXCPP="$2"
+            shift 2
+            ;;
+        -*)
+            echo Unknown option \"$1\" 1>&2
+            exit
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
 
-export CC=${c_compiler}
-export CPP="${c_compiler} -E"
-export CXX=${cxx_compiler}
-export CXXCPP="${cxx_compiler} -E"
+export CC=${ARG_CC}
+[ -n "${ARG_CPP}" ] && export CPP=${ARG_CPP} || export CPP="${ARG_CC} -E"
+export CXX=${ARG_CXX}
+[ -n "${ARG_CXXCPP}" ] && export CXXCPP=${ARG_CXXCPP} || export CXXCPP="${ARG_CXX} -E"
 
-./configure --prefix=${prefix} CFLAGS=${cflags} CXXFLAGS=${cxxflags}
+./configure $@

From a7a597b8336d5a70e7eacb79047ded1416d592b1 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 20 Sep 2018 12:35:02 +0900
Subject: [PATCH 142/321] add build*-.sh

---
 .travis.yml                   |  7 ++-
 .travis/build-menoh.sh        | 40 ++++++++------
 .travis/build-mkldnn.sh       | 98 +++++++++++++++++++++++++++++++++++
 .travis/build-protobuf.sh     | 88 +++++++++++++++++++++++++++++++
 .travis/init-build-linux.sh   | 26 +++++++---
 .travis/init-build-osx.sh     |  2 +
 .travis/install-mkldnn.sh     | 74 +++-----------------------
 .travis/install-protobuf.sh   | 61 +++-------------------
 .travis/linux-x86_64/build.sh |  2 +
 9 files changed, 256 insertions(+), 142 deletions(-)
 create mode 100644 .travis/build-mkldnn.sh
 create mode 100644 .travis/build-protobuf.sh

diff --git a/.travis.yml b/.travis.yml
index b2233ef..82cc3f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -60,12 +60,15 @@ matrix:
           install:
               - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
               - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/install-mkldnn.sh \
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/build-mkldnn.sh \
                     --version ${MKLDNN_VERSION} \
                     --download-dir ${HOME}/downloads \
-                    --build-dir ${HOME}/build \
+                    --extract-dir ${HOME}/build \
                     --install-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION} \
                     --parallel ${MAKE_JOBS}
+              - |
+                bash -ex ${TRAVIS_BUILD_DIR}/.travis/install-mkldnn.sh \
+                    --build-dir ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}/build
           script: true # skip build and test
 
 script:
diff --git a/.travis/build-menoh.sh b/.travis/build-menoh.sh
index 4d35f01..40db953 100644
--- a/.travis/build-menoh.sh
+++ b/.travis/build-menoh.sh
@@ -7,32 +7,40 @@ while [[ $# != 0 ]]; do
             shift
             break
             ;;
+        --build-type)
+            readonly ARG_BUILD_TYPE="$2"
+            shift 2
+            ;;
         --source-dir)
-            ARG_SOURCE_DIR="$2"
+            readonly ARG_SOURCE_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            readonly ARG_BUILD_DIR="$2"
             shift 2
             ;;
         --install-dir)
-            ARG_INSTALL_DIR="$2"
+            readonly ARG_INSTALL_DIR="$2"
             shift 2
             ;;
         --mkldnn-dir)
-            ARG_MKLDNN_DIR="$2"
+            readonly ARG_MKLDNN_DIR="$2"
             shift 2
             ;;
         --link-static-libgcc)
-            ARG_LINK_STATIC_LIBGCC="$2"
+            readonly ARG_LINK_STATIC_LIBGCC="$2"
             shift 2
             ;;
         --link-static-libstdcxx)
-            ARG_LINK_STATIC_LIBSTDCXX="$2"
+            readonly ARG_LINK_STATIC_LIBSTDCXX="$2"
             shift 2
             ;;
         --link-static-libprotobuf)
-            ARG_LINK_STATIC_LIBPROTOBUF="$2"
+            readonly ARG_LINK_STATIC_LIBPROTOBUF="$2"
             shift 2
             ;;
         -*)
-            err Unknown option \"$1\"
+            echo Unknown option \"$1\" 1>&2
             exit
             ;;
         *)
@@ -45,16 +53,18 @@ done
 # validate the arguments
 test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified" 1>&2; exit 1; }
 
-test -n "${ARG_LINK_STATIC_LIBGCC}" || ARG_LINK_STATIC_LIBGCC='OFF'
-test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || ARG_LINK_STATIC_LIBSTDCXX='OFF'
-test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || ARG_LINK_STATIC_LIBPROTOBUF='OFF'
+# options that have default value
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${ARG_SOURCE_DIR}/build
+test -n "${ARG_BUILD_TYPE}" || readonly ARG_BUILD_TYPE=Debug
+test -n "${ARG_LINK_STATIC_LIBGCC}" || readonly ARG_LINK_STATIC_LIBGCC='OFF'
+test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || readonly ARG_LINK_STATIC_LIBSTDCXX='OFF'
+test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || readonly ARG_LINK_STATIC_LIBPROTOBUF='OFF'
 
 echo -e "\e[33;1mBuilding Menoh\e[0m"
 
-cd ${ARG_SOURCE_DIR}
-[ -d "build" ] || mkdir -p build
+[ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
 
-cd build
+cd ${ARG_BUILD_DIR}
 if [ -n "${ARG_INSTALL_DIR}" ]; then
     OPT_CMAKE_INSTALL_PREFIX=-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}
 fi
@@ -63,7 +73,7 @@ if [ -n "${ARG_MKLDNN_DIR}" ]; then
     OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 cmake \
-    -DCMAKE_BUILD_TYPE=Release \
+    -DCMAKE_BUILD_TYPE=${ARG_BUILD_TYPE} \
     ${OPT_CMAKE_INSTALL_PREFIX} \
     ${OPT_MKLDNN_INCLUDE_DIR} \
     ${OPT_MKLDNN_LIBRARY} \
@@ -71,6 +81,6 @@ cmake \
     -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
     -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \
     -DENABLE_TEST=ON \
-    ..
+    ${ARG_SOURCE_DIR}
 
 make
diff --git a/.travis/build-mkldnn.sh b/.travis/build-mkldnn.sh
new file mode 100644
index 0000000..0277c69
--- /dev/null
+++ b/.travis/build-mkldnn.sh
@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --version)
+            readonly ARG_VERSION="$2"
+            shift 2
+            ;;
+        --download-dir)
+            readonly ARG_DOWNLOAD_DIR="$2"
+            shift 2
+            ;;
+        --extract-dir)
+            readonly ARG_EXTRACT_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            readonly ARG_BUILD_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            readonly ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --parallel)
+            readonly ARG_PARALLEL="$2"
+            shift 2
+            ;;
+        -*)
+            echo Unknown option \"$1\" 1>&2
+            exit
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
+
+readonly LIBRARY_NAME=mkl-dnn-${ARG_VERSION}
+readonly SOURCE_DIR=${ARG_EXTRACT_DIR}/${LIBRARY_NAME}
+
+# options that have default value
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${SOURCE_DIR}/build
+test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
+
+# download (if it isn't cached)
+if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
+    echo -e "\e[33;1mDownloading libmkldnn\e[0m"
+
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+
+    cd ${ARG_DOWNLOAD_DIR}
+    if [ ! -e "${LIBRARY_NAME}.tar.gz" ]; then
+        download_url="https://github.com/intel/mkl-dnn/archive/v${ARG_VERSION}.tar.gz"
+        wget -O ${LIBRARY_NAME}.tar.gz ${download_url}
+    fi
+    tar -zxf ${LIBRARY_NAME}.tar.gz -C ${ARG_EXTRACT_DIR}
+
+    echo -e "\e[32;1mlibmkldnn was successfully downloaded.\e[0m"
+else
+    echo -e "\e[32;1mlibmkldnn has been downloaded.\e[0m"
+fi
+
+# build (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/src/libmkldnn.so" ]; then
+    echo -e "\e[33;1mBuilding libmkldnn\e[0m"
+
+    cd ${SOURCE_DIR}/scripts
+    ./prepare_mkl.sh
+
+    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
+
+    cd ${ARG_BUILD_DIR}
+    cmake \
+        -DCMAKE_BUILD_TYPE=Release \
+        -DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR} \
+        -DWITH_TEST=OFF \
+        -DWITH_EXAMPLE=OFF \
+        -DARCH_OPT_FLAGS='' \
+        -Wno-error=unused-result \
+        ${SOURCE_DIR}
+    make -j${ARG_PARALLEL}
+
+    echo -e "\e[32;1mlibmkldnn was successfully built.\e[0m"
+else
+    echo -e "\e[32;1mlibmkldnn has been built.\e[0m"
+fi
diff --git a/.travis/build-protobuf.sh b/.travis/build-protobuf.sh
new file mode 100644
index 0000000..aee877c
--- /dev/null
+++ b/.travis/build-protobuf.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --version)
+            readonly ARG_VERSION="$2"
+            shift 2
+            ;;
+        --download-dir)
+            readonly ARG_DOWNLOAD_DIR="$2"
+            shift 2
+            ;;
+        --extract-dir)
+            readonly ARG_EXTRACT_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            readonly ARG_BUILD_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            readonly ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --parallel)
+            readonly ARG_PARALLEL="$2"
+            shift 2
+            ;;
+        -*)
+            echo Unknown option \"$1\" 1>&2
+            exit
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
+
+readonly LIBRARY_NAME=protobuf-${ARG_VERSION}
+readonly SOURCE_DIR=${ARG_EXTRACT_DIR}/${LIBRARY_NAME}
+
+# options that have default value
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${SOURCE_DIR}
+test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
+
+# download (if it isn't cached)
+if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
+    echo -e "\e[33;1mDownloading libprotobuf\e[0m"
+
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+
+    cd ${ARG_DOWNLOAD_DIR}
+    if [ ! -e "protobuf-cpp-${ARG_VERSION}.tar.gz" ]; then
+        download_dir="https://github.com/protocolbuffers/protobuf/releases/download/v${ARG_VERSION}/protobuf-cpp-${ARG_VERSION}.tar.gz"
+        wget ${download_dir}
+    fi
+    tar -zxf protobuf-cpp-${ARG_VERSION}.tar.gz -C ${ARG_EXTRACT_DIR}
+
+    echo -e "\e[32;1mlibprotobuf was successfully downloaded.\e[0m"
+else
+    echo -e "\e[32;1mlibprotobuf has been downloaded.\e[0m"
+fi
+
+# build (if it isn't cached)
+if [ ! -e "${ARG_BUILD_DIR}/src/libprotobuf.la" ]; then
+    echo -e "\e[33;1mBuilding libprotobuf\e[0m"
+
+    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
+
+    cd ${ARG_BUILD_DIR}
+    ${SOURCE_DIR}/configure --prefix=${ARG_INSTALL_DIR} CFLAGS=-fPIC CXXFLAGS=-fPIC
+    make -j${ARG_PARALLEL}
+
+    echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
+else
+    echo -e "\e[32;1mlibprotobuf has been built.\e[0m"
+fi
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index 1c4eaba..0a18580 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -34,26 +34,38 @@ function docker_exec_script() {
     return $?
 }
 
-function install_protobuf() {
+function build_protobuf() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/install-protobuf.sh \
+        ${PROJ_DIR}/.travis/build-protobuf.sh \
             --version ${PROTOBUF_VERSION} \
             --download-dir ${WORK_DIR}/downloads \
-            --build-dir ${WORK_DIR}/build \
+            --extract-dir ${WORK_DIR}/build \
             --install-dir ${PROTOBUF_INSTALL_DIR} \
             --parallel ${MAKE_JOBS}
 }
 
-function install_mkldnn() {
+function install_protobuf() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/install-mkldnn.sh \
+        ${PROJ_DIR}/.travis/install-protobuf.sh \
+            --build-dir ${WORK_DIR}/build/protobuf-${PROTOBUF_VERSION}
+}
+
+function build_mkldnn() {
+    docker_exec_script \
+        ${PROJ_DIR}/.travis/build-mkldnn.sh \
             --version ${MKLDNN_VERSION} \
             --download-dir ${WORK_DIR}/downloads \
-            --build-dir ${WORK_DIR}/build \
+            --extract-dir ${WORK_DIR}/build \
             --install-dir ${MKLDNN_INSTALL_DIR} \
             --parallel ${MAKE_JOBS}
 }
 
+function install_mkldnn() {
+    docker_exec_script \
+        ${PROJ_DIR}/.travis/install-mkldnn.sh \
+            --build-dir ${WORK_DIR}/build/mkl-dnn-${MKLDNN_VERSION}/build
+}
+
 function prepare_menoh_data() {
     docker_exec_script \
         ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
@@ -65,10 +77,12 @@ function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
         docker_exec_script \
             ${PROJ_DIR}/.travis/build-menoh.sh \
+                --build-type Release \
                 --source-dir ${PROJ_DIR}
     else
         docker_exec_script \
             ${PROJ_DIR}/.travis/build-menoh.sh \
+                --build-type Release \
                 --source-dir ${PROJ_DIR} \
                 --link-static-libgcc ON \
                 --link-static-libstdcxx ON \
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 627e070..3b74a82 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -16,10 +16,12 @@ function prepare_menoh_data() {
 function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
         bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
+            --build-type Release \
             --source-dir ${PROJ_DIR}
     else
         # Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
         bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
+            --build-type Release \
             --source-dir ${PROJ_DIR} \
             --link-static-libprotobuf ON
     fi
diff --git a/.travis/install-mkldnn.sh b/.travis/install-mkldnn.sh
index cb797e8..3024147 100644
--- a/.travis/install-mkldnn.sh
+++ b/.travis/install-mkldnn.sh
@@ -7,90 +7,32 @@ while [[ $# != 0 ]]; do
             shift
             break
             ;;
-        --version)
-            ARG_VERSION="$2"
-            shift 2
-            ;;
-        --download-dir)
-            ARG_DOWNLOAD_DIR="$2"
-            shift 2
-            ;;
         --build-dir)
-            ARG_BUILD_DIR="$2"
+            readonly ARG_BUILD_DIR="$2"
             shift 2
             ;;
-        --install-dir)
-            ARG_INSTALL_DIR="$2"
-            shift 2
-            ;;
-        --parallel)
-            ARG_PARALLEL="$2"
+        --dest-dir)
+            readonly ARG_DESTDIR="$2"
             shift 2
             ;;
         -*)
-            err Unknown option \"$1\"
+            echo Unknown option \"$1\" 1>&2
             exit
             ;;
         *)
             break
             ;;
-
     esac
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
-test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
-
-# download (if it isn't cached)
-if [ ! -e "${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/LICENSE" ]; then
-    echo -e "\e[33;1mDownloading libmkldnn\e[0m"
-
-    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
-
-    cd ${ARG_DOWNLOAD_DIR}
-    if [ ! -e "mkl-dnn-${ARG_VERSION}.tar.gz" ]; then
-        download_url="https://github.com/intel/mkl-dnn/archive/v${ARG_VERSION}.tar.gz"
-        wget -O mkl-dnn-${ARG_VERSION}.tar.gz ${download_url}
-    fi
-    tar -zxf mkl-dnn-${ARG_VERSION}.tar.gz -C ${ARG_BUILD_DIR}
-
-    echo -e "\e[32;1mlibmkldnn was successfully downloaded.\e[0m"
-else
-    echo -e "\e[32;1mlibmkldnn has been downloaded.\e[0m"
-fi
-
-# build (if it isn't cached)
-if [ ! -e "${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/build/src/libmkldnn.so" ]; then
-    echo -e "\e[33;1mBuilding libmkldnn\e[0m"
-
-    cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/scripts
-    ./prepare_mkl.sh
-
-    cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}
-    [ -d "build" ] || mkdir -p build
-
-    cd build
-    cmake \
-        -DCMAKE_BUILD_TYPE=Release \
-        -DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR} \
-        -DWITH_TEST=OFF \
-        -DWITH_EXAMPLE=OFF \
-        -DARCH_OPT_FLAGS='' \
-        -Wno-error=unused-result \
-        ..
-    make -j${ARG_PARALLEL}
-
-    echo -e "\e[32;1mlibmkldnn was successfully built.\e[0m"
-else
-    echo -e "\e[32;1mlibmkldnn has been built.\e[0m"
-fi
 
 # install (always)
 echo -e "\e[33;1mInstalling libmkldnn\e[0m"
 
-cd ${ARG_BUILD_DIR}/mkl-dnn-${ARG_VERSION}/build
+# install to ${DESTDIR}/${CMAKE_INSTALL_PREFIX} if it is specified
+[ -n "${ARG_DESTDIR}" ] && export DESTDIR=${ARG_DESTDIR}
+
+cd ${ARG_BUILD_DIR}
 make install/strip
diff --git a/.travis/install-protobuf.sh b/.travis/install-protobuf.sh
index f3b4fd5..131e0e3 100644
--- a/.travis/install-protobuf.sh
+++ b/.travis/install-protobuf.sh
@@ -7,77 +7,32 @@ while [[ $# != 0 ]]; do
             shift
             break
             ;;
-        --version)
-            ARG_VERSION="$2"
-            shift 2
-            ;;
-        --download-dir)
-            ARG_DOWNLOAD_DIR="$2"
-            shift 2
-            ;;
         --build-dir)
-            ARG_BUILD_DIR="$2"
+            readonly ARG_BUILD_DIR="$2"
             shift 2
             ;;
-        --install-dir)
-            ARG_INSTALL_DIR="$2"
-            shift 2
-            ;;
-        --parallel)
-            ARG_PARALLEL="$2"
+        --dest-dir)
+            readonly ARG_DESTDIR="$2"
             shift 2
             ;;
         -*)
-            err Unknown option \"$1\"
+            echo Unknown option \"$1\" 1>&2
             exit
             ;;
         *)
             break
             ;;
-
     esac
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
-test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_PARALLEL}" || ARG_PARALLEL=1
-
-# download (if it isn't cached)
-if [ ! -e "${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}/LICENSE" ]; then
-    echo -e "\e[33;1mDownloading libprotobuf\e[0m"
-
-    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
-
-    cd ${ARG_DOWNLOAD_DIR}
-    if [ ! -e "protobuf-cpp-${ARG_VERSION}.tar.gz" ]; then
-        download_dir="https://github.com/protocolbuffers/protobuf/releases/download/v${ARG_VERSION}/protobuf-cpp-${ARG_VERSION}.tar.gz"
-        wget ${download_dir}
-    fi
-    tar -zxf protobuf-cpp-${ARG_VERSION}.tar.gz -C ${ARG_BUILD_DIR}
-
-    echo -e "\e[32;1mlibprotobuf was successfully downloaded.\e[0m"
-else
-    echo -e "\e[32;1mlibprotobuf has been downloaded.\e[0m"
-fi
-
-# build (if it isn't cached)
-if [ ! -e "${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}/src/libprotobuf.la" ]; then
-    echo -e "\e[33;1mBuilding libprotobuf\e[0m"
-
-    cd ${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}
-    ./configure --prefix=${ARG_INSTALL_DIR} CFLAGS=-fPIC CXXFLAGS=-fPIC
-    make -j${ARG_PARALLEL}
-
-    echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
-else
-    echo -e "\e[32;1mlibprotobuf has been built.\e[0m"
-fi
 
 # install (always)
 echo -e "\e[33;1mInstalling libprotobuf\e[0m"
 
-cd ${ARG_BUILD_DIR}/protobuf-${ARG_VERSION}
+# install to ${DESTDIR}/`--prefix` if it is specified
+[ -n "${ARG_DESTDIR}" ] && export DESTDIR=${ARG_DESTDIR}
+
+cd ${ARG_BUILD_DIR}
 make install
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index 0af7711..692b86c 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -13,7 +13,9 @@ docker_exec "ls -l ${WORK_DIR}/build/${TRAVIS_REPO_SLUG}"
 docker_exec "(printenv | grep PATH) && make --version && cmake --version && g++ --version && ldd --version"
 
 # build and install prerequisites
+build_protobuf
 install_protobuf
+build_mkldnn
 install_mkldnn
 
 docker_exec "pip3 install --user chainer" # for generating test data

From 83f1b749ab56ffd21a8d4f7544fb1a919678c725 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 20 Sep 2018 15:23:52 +0900
Subject: [PATCH 143/321] move scripts under scripts directory

---
 .travis.yml                                  |  4 +-
 .travis/README.md                            |  2 +-
 .travis/init-build-linux.sh                  | 44 ++++++++++----------
 .travis/init-build-osx.sh                    | 16 +++----
 .travis/linux-x86_64/build.sh                |  2 +-
 .travis/macosx-x86_64/build.sh               |  2 +-
 BUILDING.md                                  |  2 +-
 README.md                                    |  6 +--
 appveyor.yml                                 |  8 ++--
 docs/getting_started.md                      |  4 +-
 docs/main.md                                 |  2 +-
 {.travis => scripts}/build-menoh.sh          | 36 ++++++++--------
 {.travis => scripts}/build-mkldnn.sh         | 29 ++++++-------
 {.travis => scripts}/build-protobuf.sh       | 25 +++++------
 gen_test_data.py => scripts/gen_test_data.py |  0
 {.travis => scripts}/install-mkldnn.sh       |  6 +--
 {.travis => scripts}/install-protobuf.sh     |  6 +--
 {.travis => scripts}/prepare-menoh-data.sh   | 18 ++++----
 retrieve_data.py => scripts/retrieve_data.py |  0
 {.travis => scripts}/run-container.sh        |  0
 20 files changed, 108 insertions(+), 104 deletions(-)
 rename {.travis => scripts}/build-menoh.sh (79%)
 mode change 100644 => 100755
 rename {.travis => scripts}/build-mkldnn.sh (76%)
 mode change 100644 => 100755
 rename {.travis => scripts}/build-protobuf.sh (75%)
 mode change 100644 => 100755
 rename gen_test_data.py => scripts/gen_test_data.py (100%)
 rename {.travis => scripts}/install-mkldnn.sh (88%)
 mode change 100644 => 100755
 rename {.travis => scripts}/install-protobuf.sh (88%)
 mode change 100644 => 100755
 rename {.travis => scripts}/prepare-menoh-data.sh (52%)
 mode change 100644 => 100755
 rename retrieve_data.py => scripts/retrieve_data.py (100%)
 rename {.travis => scripts}/run-container.sh (100%)

diff --git a/.travis.yml b/.travis.yml
index 82cc3f7..ac28c6d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -60,14 +60,14 @@ matrix:
           install:
               - if [ "$TRAVIS_OS_NAME" = "linux" -a "$CXX" = "g++" ]; then export CXX="g++-7" CC="gcc-7"; fi
               - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/build-mkldnn.sh \
+                bash -ex ${TRAVIS_BUILD_DIR}/scripts/build-mkldnn.sh \
                     --version ${MKLDNN_VERSION} \
                     --download-dir ${HOME}/downloads \
                     --extract-dir ${HOME}/build \
                     --install-dir ${HOME}/mkl-dnn-${MKLDNN_VERSION} \
                     --parallel ${MAKE_JOBS}
               - |
-                bash -ex ${TRAVIS_BUILD_DIR}/.travis/install-mkldnn.sh \
+                bash -ex ${TRAVIS_BUILD_DIR}/scripts/install-mkldnn.sh \
                     --build-dir ${HOME}/build/mkl-dnn-${MKLDNN_VERSION}/build
           script: true # skip build and test
 
diff --git a/.travis/README.md b/.travis/README.md
index 1ef0312..8f45bcc 100644
--- a/.travis/README.md
+++ b/.travis/README.md
@@ -12,7 +12,7 @@ Linux-based platforms requires a container image with the following softwares:
 Currently it uses [okapies/buildenv](https://hub.docker.com/r/okapies/buildenv/) image for linux-x86_64 platform.
 
 ## Architecture
-`.travis.yml` -> `run-build.sh` -> `build.sh` -> `install-*.sh` & `build-menoh.sh`
+`.travis.yml` -> `run-build.sh` -> `build.sh` -> `scripts/*.sh`
 
 1. `run-build.sh` just calls a platform's `build.sh` for running the actual build workflow
 2. `build.sh`
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index 0a18580..a5e5f16 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -16,8 +16,8 @@ export MKLDNN_INSTALL_DIR=/usr/local
 # $HOME:$HOME = /home/travis                     : /home/travis
 #               /home/travis/build               : /home/travis/build
 #               /home/travis/build/<user>/<repo> : /home/travis/build/<user>/<repo> (= ${TRAVIS_BUILD_DIR})
-SHARED_SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
-source ${SHARED_SCRIPT_DIR}/run-container.sh --image ${BUILDENV_IMAGE} --work-dir ${WORK_DIR}
+SOURCE_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}/..")"; pwd)
+source ${SOURCE_DIR}/scripts/run-container.sh --image ${BUILDENV_IMAGE} --work-dir ${WORK_DIR}
 test -n "${BUILDENV_CONTAINER_ID}" || { echo "BUILDENV_CONTAINER_ID can't be empty" 1>&2; exit 1; }
 
 ## define shared functions for Linux-based platforms
@@ -36,54 +36,54 @@ function docker_exec_script() {
 
 function build_protobuf() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/build-protobuf.sh \
+        "${PROJ_DIR}/scripts/build-protobuf.sh" \
             --version ${PROTOBUF_VERSION} \
-            --download-dir ${WORK_DIR}/downloads \
-            --extract-dir ${WORK_DIR}/build \
-            --install-dir ${PROTOBUF_INSTALL_DIR} \
+            --download-dir "${WORK_DIR}/downloads" \
+            --extract-dir "${WORK_DIR}/build" \
+            --install-dir "${PROTOBUF_INSTALL_DIR}" \
             --parallel ${MAKE_JOBS}
 }
 
 function install_protobuf() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/install-protobuf.sh \
-            --build-dir ${WORK_DIR}/build/protobuf-${PROTOBUF_VERSION}
+        "${PROJ_DIR}/scripts/install-protobuf.sh" \
+            --build-dir "${WORK_DIR}/build/protobuf-${PROTOBUF_VERSION}"
 }
 
 function build_mkldnn() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/build-mkldnn.sh \
+        "${PROJ_DIR}/scripts/build-mkldnn.sh" \
             --version ${MKLDNN_VERSION} \
-            --download-dir ${WORK_DIR}/downloads \
-            --extract-dir ${WORK_DIR}/build \
-            --install-dir ${MKLDNN_INSTALL_DIR} \
+            --download-dir "${WORK_DIR}/downloads" \
+            --extract-dir "${WORK_DIR}/build" \
+            --install-dir "${MKLDNN_INSTALL_DIR}" \
             --parallel ${MAKE_JOBS}
 }
 
 function install_mkldnn() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/install-mkldnn.sh \
-            --build-dir ${WORK_DIR}/build/mkl-dnn-${MKLDNN_VERSION}/build
+        "${PROJ_DIR}/scripts/install-mkldnn.sh" \
+            --build-dir "${WORK_DIR}/build/mkl-dnn-${MKLDNN_VERSION}/build"
 }
 
 function prepare_menoh_data() {
     docker_exec_script \
-        ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
-            --source-dir ${PROJ_DIR} \
+        "${PROJ_DIR}/scripts/prepare-menoh-data.sh" \
+            --source-dir "${PROJ_DIR}" \
             --python-executable python3
 }
 
 function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
         docker_exec_script \
-            ${PROJ_DIR}/.travis/build-menoh.sh \
+            "${PROJ_DIR}/scripts/build-menoh.sh" \
                 --build-type Release \
-                --source-dir ${PROJ_DIR}
+                --source-dir "${PROJ_DIR}"
     else
         docker_exec_script \
-            ${PROJ_DIR}/.travis/build-menoh.sh \
+            "${PROJ_DIR}/scripts/build-menoh.sh" \
                 --build-type Release \
-                --source-dir ${PROJ_DIR} \
+                --source-dir "${PROJ_DIR}" \
                 --link-static-libgcc ON \
                 --link-static-libstdcxx ON \
                 --link-static-libprotobuf ON
@@ -91,9 +91,9 @@ function build_menoh() {
 }
 
 function test_menoh() {
-    docker_exec "cd ${PROJ_DIR}/build && ./test/menoh_test"
+    docker_exec "cd \"${PROJ_DIR}/build\" && ./test/menoh_test"
 }
 
 function check_menoh_artifact() {
-    docker_exec "ldd ${PROJ_DIR}/build/menoh/libmenoh.so"
+    docker_exec "ldd \"${PROJ_DIR}/build/menoh/libmenoh.so\""
 }
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 3b74a82..c1228d8 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -8,30 +8,30 @@ export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 ## define shared functions for macOS (OSX) platforms
 
 function prepare_menoh_data() {
-    bash -ex ${PROJ_DIR}/.travis/prepare-menoh-data.sh \
-        --source-dir ${PROJ_DIR} \
+    bash -ex "${PROJ_DIR}/scripts/prepare-menoh-data.sh" \
+        --source-dir "${PROJ_DIR}" \
         --python-executable python
 }
 
 function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
-        bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
+        bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
             --build-type Release \
-            --source-dir ${PROJ_DIR}
+            --source-dir "${PROJ_DIR}"
     else
         # Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
-        bash -ex ${PROJ_DIR}/.travis/build-menoh.sh \
+        bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
             --build-type Release \
-            --source-dir ${PROJ_DIR} \
+            --source-dir "${PROJ_DIR}" \
             --link-static-libprotobuf ON
     fi
 }
 
 function test_menoh() {
-    cd ${PROJ_DIR}/build
+    cd "${PROJ_DIR}/build"
     ./test/menoh_test
 }
 
 function check_menoh_artifact() {
-    otool -L ${PROJ_DIR}/build/menoh/libmenoh.dylib
+    otool -L "${PROJ_DIR}/build/menoh/libmenoh.dylib"
 }
diff --git a/.travis/linux-x86_64/build.sh b/.travis/linux-x86_64/build.sh
index 692b86c..205f028 100644
--- a/.travis/linux-x86_64/build.sh
+++ b/.travis/linux-x86_64/build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -ex
 
-BASE_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+BASE_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd)
 
 # initialize this script
 source ${BASE_DIR}/../init-build-linux.sh
diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index a81b8ca..ec672cc 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-BASE_DIR=$(cd $(dirname ${BASH_SOURCE:-$0}); pwd)
+BASE_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd)
 
 # initialize this script
 source ${BASE_DIR}/../init-build-osx.sh
diff --git a/BUILDING.md b/BUILDING.md
index 698309d..eb6fea1 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -124,7 +124,7 @@ make install # as root
 To run the example, you also need to download model data:
 
 ```
-python retrieve_data.py
+python scripts/retrieve_data.py
 ```
 
 #### Static linking
diff --git a/README.md b/README.md
index 3516f9c..03663ac 100644
--- a/README.md
+++ b/README.md
@@ -59,7 +59,7 @@ This codebase contains C API and C++ API.
 Execute following commands in root directory.
 
 ```
-python retrieve_data.py
+python scripts/retrieve_data.py
 mkdir build && cd build
 cmake ..
 make
@@ -111,7 +111,7 @@ Setup chainer
 Then, execute following commands in root directory.
 
 ```
-python gen_test_data.py
+python scripts/gen_test_data.py
 cd build
 cmake -DENABLE_TEST=ON ..
 make
@@ -155,7 +155,7 @@ make
 
 Menoh is released under MIT License. Please see the LICENSE file for details.
 
-Note: `retrieve_data.py` downloads `data/VGG16.onnx`. `data/VGG16.onnx` is generated by onnx-chainer from pre-trained model which is uploaded
+Note: `scripts/retrieve_data.py` downloads `data/VGG16.onnx`. `data/VGG16.onnx` is generated by onnx-chainer from pre-trained model which is uploaded
 at http://www.robots.ox.ac.uk/%7Evgg/software/very_deep/caffe/VGG_ILSVRC_16_layers.caffemodel
 
 That pre-trained model is released under Creative Commons Attribution License.
diff --git a/appveyor.yml b/appveyor.yml
index 90e1e4a..ea5580f 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -40,13 +40,13 @@ install:
 - if [%TARGET%]==[mingw] (
     pip3 install --user chainer &&
     mkdir -p data &&
-    python3 retrieve_data.py &&
-    python3 gen_test_data.py
+    python3 scripts/retrieve_data.py &&
+    python3 scripts/gen_test_data.py
   ) else (
     pip install --user chainer &&
     md data &&
-    python retrieve_data.py &&
-    python gen_test_data.py
+    python scripts/retrieve_data.py &&
+    python scripts/gen_test_data.py
   )
 
 before_build:
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 2060c40..26be544 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -39,7 +39,7 @@ make install
 Execute below command in root directory:
 
 ```
-python retrieve_data.py
+python scripts/retrieve_data.py
 cd build
 ./example/vgg16_example
 ```
@@ -68,7 +68,7 @@ Please give `--help` option for details
 Execute below commands in root directory:
 
 ```
-python gen_test_data.py
+python scripts/gen_test_data.py
 cd build
 cmake -DENABLE_TEST=ON ..
 make
diff --git a/docs/main.md b/docs/main.md
index 4b7a94d..c123ee3 100644
--- a/docs/main.md
+++ b/docs/main.md
@@ -43,7 +43,7 @@ Menoh is released under MIT License.
 
 Menoh is released under MIT License. Please see the LICENSE file for details.
 
-Note: `retrieve_data.sh` downloads `data/VGG16.onnx`.
+Note: `scripts/retrieve_data.sh` downloads `data/VGG16.onnx`.
 
 `data/VGG16.onnx` is generated by onnx-chainer from pre-trained model which is uploaded
 at http://www.robots.ox.ac.uk/%7Evgg/software/very_deep/caffe/VGG_ILSVRC_16_layers.caffemodel
diff --git a/.travis/build-menoh.sh b/scripts/build-menoh.sh
old mode 100644
new mode 100755
similarity index 79%
rename from .travis/build-menoh.sh
rename to scripts/build-menoh.sh
index 40db953..6f7f80b
--- a/.travis/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -1,4 +1,6 @@
-#!/bin/bash
+#!/bin/bash -e
+
+BASE_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd)
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -50,37 +52,35 @@ while [[ $# != 0 ]]; do
     esac
 done
 
-# validate the arguments
-test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified" 1>&2; exit 1; }
-
 # options that have default value
-test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${ARG_SOURCE_DIR}/build
 test -n "${ARG_BUILD_TYPE}" || readonly ARG_BUILD_TYPE=Debug
+test -n "${ARG_SOURCE_DIR}" || readonly ARG_SOURCE_DIR="${BASE_DIR}/.."
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${ARG_SOURCE_DIR}/build"
+test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
+
+if [ -n "${ARG_MKLDNN_DIR}" ]; then
+    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
+    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
+fi
+
 test -n "${ARG_LINK_STATIC_LIBGCC}" || readonly ARG_LINK_STATIC_LIBGCC='OFF'
 test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || readonly ARG_LINK_STATIC_LIBSTDCXX='OFF'
 test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || readonly ARG_LINK_STATIC_LIBPROTOBUF='OFF'
 
 echo -e "\e[33;1mBuilding Menoh\e[0m"
 
-[ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
+[ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
-cd ${ARG_BUILD_DIR}
-if [ -n "${ARG_INSTALL_DIR}" ]; then
-    OPT_CMAKE_INSTALL_PREFIX=-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}
-fi
-if [ -n "${ARG_MKLDNN_DIR}" ]; then
-    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
-    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
-fi
+cd "${ARG_BUILD_DIR}"
 cmake \
     -DCMAKE_BUILD_TYPE=${ARG_BUILD_TYPE} \
-    ${OPT_CMAKE_INSTALL_PREFIX} \
-    ${OPT_MKLDNN_INCLUDE_DIR} \
-    ${OPT_MKLDNN_LIBRARY} \
+    "-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}" \
+    "${OPT_MKLDNN_INCLUDE_DIR}" \
+    "${OPT_MKLDNN_LIBRARY}" \
     -DLINK_STATIC_LIBGCC=${ARG_LINK_STATIC_LIBGCC} \
     -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
     -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \
     -DENABLE_TEST=ON \
-    ${ARG_SOURCE_DIR}
+    "${ARG_SOURCE_DIR}"
 
 make
diff --git a/.travis/build-mkldnn.sh b/scripts/build-mkldnn.sh
old mode 100644
new mode 100755
similarity index 76%
rename from .travis/build-mkldnn.sh
rename to scripts/build-mkldnn.sh
index 0277c69..52ed504
--- a/.travis/build-mkldnn.sh
+++ b/scripts/build-mkldnn.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -42,30 +42,31 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
 test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
+
+# options that have default value
+test -n "${ARG_VERSION}" || readonly ARG_VERSION=0.16
 
 readonly LIBRARY_NAME=mkl-dnn-${ARG_VERSION}
-readonly SOURCE_DIR=${ARG_EXTRACT_DIR}/${LIBRARY_NAME}
+readonly SOURCE_DIR="${ARG_EXTRACT_DIR}/${LIBRARY_NAME}"
 
-# options that have default value
-test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${SOURCE_DIR}/build
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}/build"
+test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
 
 # download (if it isn't cached)
 if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
     echo -e "\e[33;1mDownloading libmkldnn\e[0m"
 
-    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p "${ARG_DOWNLOAD_DIR}"
 
-    cd ${ARG_DOWNLOAD_DIR}
+    cd "${ARG_DOWNLOAD_DIR}"
     if [ ! -e "${LIBRARY_NAME}.tar.gz" ]; then
         download_url="https://github.com/intel/mkl-dnn/archive/v${ARG_VERSION}.tar.gz"
         wget -O ${LIBRARY_NAME}.tar.gz ${download_url}
     fi
-    tar -zxf ${LIBRARY_NAME}.tar.gz -C ${ARG_EXTRACT_DIR}
+    tar -zxf ${LIBRARY_NAME}.tar.gz -C "${ARG_EXTRACT_DIR}"
 
     echo -e "\e[32;1mlibmkldnn was successfully downloaded.\e[0m"
 else
@@ -76,20 +77,20 @@ fi
 if [ ! -e "${ARG_BUILD_DIR}/src/libmkldnn.so" ]; then
     echo -e "\e[33;1mBuilding libmkldnn\e[0m"
 
-    cd ${SOURCE_DIR}/scripts
+    cd "${SOURCE_DIR}/scripts"
     ./prepare_mkl.sh
 
-    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
+    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
-    cd ${ARG_BUILD_DIR}
+    cd "${ARG_BUILD_DIR}"
     cmake \
         -DCMAKE_BUILD_TYPE=Release \
-        -DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR} \
+        "-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}" \
         -DWITH_TEST=OFF \
         -DWITH_EXAMPLE=OFF \
         -DARCH_OPT_FLAGS='' \
         -Wno-error=unused-result \
-        ${SOURCE_DIR}
+        "${SOURCE_DIR}"
     make -j${ARG_PARALLEL}
 
     echo -e "\e[32;1mlibmkldnn was successfully built.\e[0m"
diff --git a/.travis/build-protobuf.sh b/scripts/build-protobuf.sh
old mode 100644
new mode 100755
similarity index 75%
rename from .travis/build-protobuf.sh
rename to scripts/build-protobuf.sh
index aee877c..cb668b9
--- a/.travis/build-protobuf.sh
+++ b/scripts/build-protobuf.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -42,30 +42,31 @@ while [[ $# != 0 ]]; do
 done
 
 # validate the arguments
-test -n "${ARG_VERSION}" || { echo "--version is not specified" 1>&2; exit 1; }
 test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
 test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_INSTALL_DIR}" || { echo "--install-dir is not specified" 1>&2; exit 1; }
+
+# options that have default value
+test -n "${ARG_VERSION}" || readonly ARG_VERSION=3.6.1
 
 readonly LIBRARY_NAME=protobuf-${ARG_VERSION}
-readonly SOURCE_DIR=${ARG_EXTRACT_DIR}/${LIBRARY_NAME}
+readonly SOURCE_DIR="${ARG_EXTRACT_DIR}/${LIBRARY_NAME}"
 
-# options that have default value
-test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR=${SOURCE_DIR}
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}"
+test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
 
 # download (if it isn't cached)
 if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
     echo -e "\e[33;1mDownloading libprotobuf\e[0m"
 
-    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p ${ARG_DOWNLOAD_DIR}
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p "${ARG_DOWNLOAD_DIR}"
 
-    cd ${ARG_DOWNLOAD_DIR}
+    cd "${ARG_DOWNLOAD_DIR}"
     if [ ! -e "protobuf-cpp-${ARG_VERSION}.tar.gz" ]; then
         download_dir="https://github.com/protocolbuffers/protobuf/releases/download/v${ARG_VERSION}/protobuf-cpp-${ARG_VERSION}.tar.gz"
         wget ${download_dir}
     fi
-    tar -zxf protobuf-cpp-${ARG_VERSION}.tar.gz -C ${ARG_EXTRACT_DIR}
+    tar -zxf protobuf-cpp-${ARG_VERSION}.tar.gz -C "${ARG_EXTRACT_DIR}"
 
     echo -e "\e[32;1mlibprotobuf was successfully downloaded.\e[0m"
 else
@@ -76,10 +77,10 @@ fi
 if [ ! -e "${ARG_BUILD_DIR}/src/libprotobuf.la" ]; then
     echo -e "\e[33;1mBuilding libprotobuf\e[0m"
 
-    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p ${ARG_BUILD_DIR}
+    [ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
-    cd ${ARG_BUILD_DIR}
-    ${SOURCE_DIR}/configure --prefix=${ARG_INSTALL_DIR} CFLAGS=-fPIC CXXFLAGS=-fPIC
+    cd "${ARG_BUILD_DIR}"
+    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS=-fPIC CXXFLAGS=-fPIC
     make -j${ARG_PARALLEL}
 
     echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
diff --git a/gen_test_data.py b/scripts/gen_test_data.py
similarity index 100%
rename from gen_test_data.py
rename to scripts/gen_test_data.py
diff --git a/.travis/install-mkldnn.sh b/scripts/install-mkldnn.sh
old mode 100644
new mode 100755
similarity index 88%
rename from .travis/install-mkldnn.sh
rename to scripts/install-mkldnn.sh
index 3024147..763cdec
--- a/.travis/install-mkldnn.sh
+++ b/scripts/install-mkldnn.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -32,7 +32,7 @@ test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1
 echo -e "\e[33;1mInstalling libmkldnn\e[0m"
 
 # install to ${DESTDIR}/${CMAKE_INSTALL_PREFIX} if it is specified
-[ -n "${ARG_DESTDIR}" ] && export DESTDIR=${ARG_DESTDIR}
+[ -n "${ARG_DESTDIR}" ] && export DESTDIR="${ARG_DESTDIR}"
 
-cd ${ARG_BUILD_DIR}
+cd "${ARG_BUILD_DIR}"
 make install/strip
diff --git a/.travis/install-protobuf.sh b/scripts/install-protobuf.sh
old mode 100644
new mode 100755
similarity index 88%
rename from .travis/install-protobuf.sh
rename to scripts/install-protobuf.sh
index 131e0e3..c5f5fd0
--- a/.travis/install-protobuf.sh
+++ b/scripts/install-protobuf.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -32,7 +32,7 @@ test -n "${ARG_BUILD_DIR}" || { echo "--build-dir is not specified" 1>&2; exit 1
 echo -e "\e[33;1mInstalling libprotobuf\e[0m"
 
 # install to ${DESTDIR}/`--prefix` if it is specified
-[ -n "${ARG_DESTDIR}" ] && export DESTDIR=${ARG_DESTDIR}
+[ -n "${ARG_DESTDIR}" ] && export DESTDIR="${ARG_DESTDIR}"
 
-cd ${ARG_BUILD_DIR}
+cd "${ARG_BUILD_DIR}"
 make install
diff --git a/.travis/prepare-menoh-data.sh b/scripts/prepare-menoh-data.sh
old mode 100644
new mode 100755
similarity index 52%
rename from .travis/prepare-menoh-data.sh
rename to scripts/prepare-menoh-data.sh
index e82bf44..9f99002
--- a/.travis/prepare-menoh-data.sh
+++ b/scripts/prepare-menoh-data.sh
@@ -1,4 +1,6 @@
-#!/bin/bash
+#!/bin/bash -e
+
+BASE_DIR=$(cd "$(dirname "${BASH_SOURCE:-$0}")"; pwd)
 
 # retrieve arguments
 while [[ $# != 0 ]]; do
@@ -26,14 +28,14 @@ while [[ $# != 0 ]]; do
     esac
 done
 
-# validate the arguments
-test -n "${ARG_SOURCE_DIR}" || { echo "ARG_SOURCE_DIR can't be empty" 1>&2; exit 1; }
-test -n "${ARG_PYTHON_EXECUTABLE}" || ARG_PYTHON_EXECUTABLE=python
+# options that have default value
+test -n "${ARG_SOURCE_DIR}" || readonly ARG_SOURCE_DIR="${BASE_DIR}/.."
+test -n "${ARG_PYTHON_EXECUTABLE}" || readonly ARG_PYTHON_EXECUTABLE=python
 
-echo -e "\e[33;1mPreparing data/ for Menoh\e[0m"
+echo -e "\e[33;1mPreparing data for Menoh tests and examples\e[0m"
 
-cd ${ARG_SOURCE_DIR}
+cd "${ARG_SOURCE_DIR}"
 [ -d "data" ] || mkdir -p data
 
-${ARG_PYTHON_EXECUTABLE} retrieve_data.py
-${ARG_PYTHON_EXECUTABLE} gen_test_data.py
+${ARG_PYTHON_EXECUTABLE} scripts/retrieve_data.py
+${ARG_PYTHON_EXECUTABLE} scripts/gen_test_data.py
diff --git a/retrieve_data.py b/scripts/retrieve_data.py
similarity index 100%
rename from retrieve_data.py
rename to scripts/retrieve_data.py
diff --git a/.travis/run-container.sh b/scripts/run-container.sh
similarity index 100%
rename from .travis/run-container.sh
rename to scripts/run-container.sh

From 7ee11204ab28720615672140da43384bccfc8a84 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 20 Sep 2018 16:54:45 +0900
Subject: [PATCH 144/321] add default options explicitly

---
 scripts/build-protobuf.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/build-protobuf.sh b/scripts/build-protobuf.sh
index cb668b9..f694b8b 100755
--- a/scripts/build-protobuf.sh
+++ b/scripts/build-protobuf.sh
@@ -80,7 +80,7 @@ if [ ! -e "${ARG_BUILD_DIR}/src/libprotobuf.la" ]; then
     [ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
     cd "${ARG_BUILD_DIR}"
-    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS=-fPIC CXXFLAGS=-fPIC
+    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS="-g -O2 -fPIC" CXXFLAGS="-g -O2 -fPIC"
     make -j${ARG_PARALLEL}
 
     echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"

From 2375e7df96296560b67b6ef16eec59df624b8c7a Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 20 Sep 2018 16:31:13 +0900
Subject: [PATCH 145/321] add default options explicitly

---
 cmake/SetupProtobuf.cmake | 6 +++---
 cmake/configure-helper.sh | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
index 8341490..0f86f77 100644
--- a/cmake/SetupProtobuf.cmake
+++ b/cmake/SetupProtobuf.cmake
@@ -12,8 +12,8 @@ if(LINK_STATIC_LIBPROTOBUF)
         set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
 
         # Requires `-fPIC` for linking with a shared library
-        set(PROTOBUF_CFLAGS -fPIC)
-        set(PROTOBUF_CXXFLAGS -fPIC)
+        set(PROTOBUF_CFLAGS "-g -O2 -fPIC")
+        set(PROTOBUF_CXXFLAGS "-g -O2 -fPIC")
         if(USE_OLD_GLIBCXX_ABI)
             set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
         endif()
@@ -24,7 +24,7 @@ if(LINK_STATIC_LIBPROTOBUF)
             URL_HASH ${PROTOBUF_HASH}
             DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
             BUILD_IN_SOURCE 1
-            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh --CC ${CMAKE_C_COMPILER} --CXX ${CMAKE_CXX_COMPILER} -- --prefix=${PROTOBUF_DIR} CFLAGS=${PROTOBUF_CFLAGS} CXXFLAGS=${PROTOBUF_CXXFLAGS}
+            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh --CC ${CMAKE_C_COMPILER} --CXX ${CMAKE_CXX_COMPILER} -- "--prefix=${PROTOBUF_DIR}" "CFLAGS=${PROTOBUF_CFLAGS}" "CXXFLAGS=${PROTOBUF_CXXFLAGS}"
             BUILD_COMMAND make -j4
             INSTALL_COMMAND make install
         )
diff --git a/cmake/configure-helper.sh b/cmake/configure-helper.sh
index 91704cd..8abab51 100644
--- a/cmake/configure-helper.sh
+++ b/cmake/configure-helper.sh
@@ -38,4 +38,4 @@ export CC=${ARG_CC}
 export CXX=${ARG_CXX}
 [ -n "${ARG_CXXCPP}" ] && export CXXCPP=${ARG_CXXCPP} || export CXXCPP="${ARG_CXX} -E"
 
-./configure $@
+./configure "$@"

From b7d51fe8a9a851a37d5cd184f6a8dcf9f35bc3a2 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 21 Sep 2018 11:47:35 +0900
Subject: [PATCH 146/321] fix multiple definition of protobuf symbols in
 menoh_test

---
 test/CMakeLists.txt | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 8d302d8..506b0ac 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -26,6 +26,11 @@ add_executable(menoh_test
     #vgg16.cpp
 
 )
-target_link_libraries(menoh_test gtest_main menoh_test_target ${PROTOBUF_LIBRARY})
+
+if(LINK_STATIC_LIBPROTOBUF)
+  target_link_libraries(menoh_test gtest_main menoh_test_target)
+else()
+  target_link_libraries(menoh_test gtest_main menoh_test_target ${PROTOBUF_LIBRARY})
+endif()
 
 add_test(NAME menoh_test COMMAND menoh_test)

From 2a96c2c069d52f10a3b14009c5aaa9f1e93dca0d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 27 Sep 2018 12:40:07 +0900
Subject: [PATCH 147/321] add new APIs to construct model_data by hand

- menoh_make_model_data()
- menoh_model_data_add_new_node()
- menoh_model_data_add_input_name_to_current_node()
- menoh_model_data_add_output_name_to_current_node()
- menoh_model_data_add_attribute_int_to_current_node()
- menoh_model_data_add_attribute_float_to_current_node()
- menoh_model_data_add_attribute_ints_to_current_node()
- menoh_model_data_add_attribute_floats_to_current_node()
- menoh_model_data_add_initializer()
---
 include/menoh/menoh.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index d561a1b..c3d4841 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -121,7 +121,6 @@ menoh_error_code MENOH_API menoh_make_model_data_from_onnx_data_on_memory(
 menoh_error_code MENOH_API
 menoh_make_model_data(menoh_model_data_handle* dst_handle);
 /*! \brief Add a new parameter in model_data
- *
  * \note Duplication of parameter_name is not allowed and it throws error.
  */
 menoh_error_code MENOH_API menoh_model_data_add_parameter(

From eac67905d2e6d674a1dbeb7088cc8acffefd7bfa Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 18 Sep 2018 20:07:06 +0900
Subject: [PATCH 148/321] add array_profile

---
 menoh/array.hpp | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/menoh/array.hpp b/menoh/array.hpp
index 2bb70bc..9b9ce2c 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -11,6 +11,21 @@
 
 namespace menoh_impl {
 
+    class array_profile {
+    public:
+        array_profile() = default;
+
+        array_profile(dtype_t dtype, std::vector<int> const& dims)
+          : dtype_(dtype), dims_(dims) {}
+
+        dtype_t dtype() const { return dtype_; }
+        auto const& dims() const { return dims_; }
+
+    private:
+        dtype_t dtype_ = dtype_t::undefined;
+        std::vector<int> dims_;
+    };
+
     class array {
     public:
         array() = default;
@@ -22,14 +37,25 @@ namespace menoh_impl {
 
         array(dtype_t d, std::vector<int> const& dims);
 
+        array(array_profile const& profile, void* data_handle)
+          : array(profile.dtype(), profile.dims(), data_handle) {}
+
+        array(array_profile const& profile, std::shared_ptr<void> const& data)
+          : array(profile.dtype(), profile.dims(), data) {}
+
+        explicit array(array_profile const& profile)
+          : array(profile.dtype(), profile.dims()) {}
+
         dtype_t dtype() const { return dtype_; }
         auto const& dims() const { return dims_; }
+
         auto* data() const { return data_handle_; }
         bool has_ownership() const { return static_cast<bool>(data_); }
 
     private:
         dtype_t dtype_ = dtype_t::undefined;
         std::vector<int> dims_;
+
         std::shared_ptr<void> data_;
         void* data_handle_ = nullptr;
     };

From 96f00d3a7f599dd5c1fc5e1f08eec8c75e043ac1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 18 Sep 2018 20:11:03 +0900
Subject: [PATCH 149/321] deprecated add_output_profile and add add_output_name

---
 include/menoh/menoh.h | 13 ++++++++++++-
 menoh/menoh.cpp       | 34 +++++++++++++++++++++-------------
 2 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index c3d4841..5ec3a8a 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -232,11 +232,22 @@ menoh_variable_profile_table_builder_add_input_profile_dims_4(
   menoh_dtype dtype, int32_t num, int32_t channel, int32_t height,
   int32_t width);
 
-/*! \brief Add output profile
+/*! \brief Add output name
+ *
+ * dims amd dtype of output are calculated automatically
+ * when calling of menoh_build_variable_profile_table.
+ */
+menoh_error_code MENOH_API menoh_variable_profile_table_builder_add_output_name(
+  menoh_variable_profile_table_builder_handle builder, const char* name);
+
+/*! \brief [DEPRECATED] Add output profile
  *
  * Output profile contains name and dtype. Its dims are calculated automatically
  * when calling of menoh_build_variable_profile_table.
  */
+MENOH_DEPRECATED_ATTRIBUTE(
+  "please use menoh_variable_profile_table_builder_add_output_name() instead. "
+  "dtype is totally ignored.")
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_output_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index dfc56d5..dde02c8 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -10,6 +10,7 @@
 
 #include <menoh/menoh.h>
 
+#include <menoh/array.hpp>
 #include <menoh/exception.hpp>
 #include <menoh/model_core.hpp>
 #include <menoh/model_core_factory.hpp>
@@ -272,37 +273,44 @@ menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_4(
   int32_t width) {
     return check_error([&]() {
         std::vector<int> dims = {num, channel, height, width};
-        builder->input_name_and_dtype_and_dims_list.push_back(
-          std::make_tuple(std::string(name), dtype, dims));
+        builder->input_name_and_profile_list.emplace_back(
+          std::string(name), menoh_impl::array_profile(
+                               static_cast<menoh_impl::dtype_t>(dtype), dims));
         return menoh_error_code_success;
     });
 }
 
-menoh_error_code menoh_variable_profile_table_builder_add_output_profile(
-  menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype) {
+menoh_error_code menoh_variable_profile_table_builder_add_output_name(
+  menoh_variable_profile_table_builder_handle builder, const char* name) {
     return check_error([&]() {
-        auto found = std::find_if(
-          builder->output_name_and_dtype_list.begin(),
-          builder->output_name_and_dtype_list.end(),
-          [name](auto const& t) { return name == std::get<0>(t); });
-        if(found != builder->output_name_and_dtype_list.end()) {
+        auto found = std::find(builder->required_output_name_list.begin(),
+                               builder->required_output_name_list.end(),
+                               std::string(name));
+        if(found != builder->required_output_name_list.end()) {
             auto message =
               std::string("menoh same named variable already exist: ") + name;
             menoh_impl::set_last_error_message(message.c_str());
             return menoh_error_code_same_named_variable_already_exist;
         }
-        builder->output_name_and_dtype_list.push_back(
-          std::make_tuple(std::string(name), dtype));
+        builder->required_output_name_list.emplace_back(name);
         return menoh_error_code_success;
     });
 }
 
+/*
+ * deprecated. dtype is totally ignored.
+ */
+menoh_error_code menoh_variable_profile_table_builder_add_output_profile(
+  menoh_variable_profile_table_builder_handle builder, const char* name,
+  menoh_dtype dtype) {
+    return menoh_variable_profile_table_builder_add_output_name(builder, name);
+}
+
 /*
  * variable_profile_table
  */
 struct menoh_variable_profile_table {
-    std::unordered_map<std::string, std::tuple<menoh_dtype, std::vector<int>>>
+    std::unordered_map<std::string, menoh_impl::array_profile>
       input_profile_table;
     std::unordered_map<std::string, std::tuple<menoh_dtype, std::vector<int>>>
       output_profile_table;

From c6fe6b2656783d6eecc45a95b9058fcf79e13454 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 18 Sep 2018 20:11:36 +0900
Subject: [PATCH 150/321] modify implementations to use array_profile and
 context to take output_profile_table

---
 menoh/menoh.cpp                               | 150 ++++++++----------
 .../backend/generic/generic_context.cpp       |   2 +
 .../backend/generic/generic_context.hpp       |   2 +
 .../backend/mkldnn/mkldnn_context.cpp         |   4 +-
 .../backend/mkldnn/mkldnn_context.hpp         |   4 +-
 .../mkldnn_with_generic_fallback/context.hpp  |   7 +-
 .../model_core.cpp                            |   5 +-
 .../model_core.hpp                            |   2 +
 menoh/model.cpp                               |  71 ---------
 menoh/model.hpp                               |  43 -----
 menoh/model_core_factory.cpp                  |  10 +-
 menoh/model_core_factory.hpp                  |  13 +-
 test/CMakeLists.txt                           |   2 -
 test/mkldnn.cpp                               | 104 ------------
 test/model.cpp                                |  45 ------
 15 files changed, 101 insertions(+), 363 deletions(-)
 delete mode 100644 menoh/model.cpp
 delete mode 100644 menoh/model.hpp
 delete mode 100644 test/mkldnn.cpp
 delete mode 100644 test/model.cpp

diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index dde02c8..ecc035d 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -227,10 +227,9 @@ menoh_error_code MENOH_API menoh_model_data_add_parameter(
  * variable_profile_table_builder
  */
 struct menoh_variable_profile_table_builder {
-    std::vector<std::tuple<std::string, menoh_dtype, std::vector<int>>>
-      input_name_and_dtype_and_dims_list;
-    std::vector<std::tuple<std::string, menoh_dtype>>
-      output_name_and_dtype_list;
+    std::vector<std::pair<std::string, menoh_impl::array_profile>>
+      input_name_and_profile_list;
+    std::vector<std::string> required_output_name_list;
 };
 
 menoh_error_code menoh_make_variable_profile_table_builder(
@@ -250,9 +249,10 @@ menoh_error_code menoh_variable_profile_table_builder_add_input_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
   menoh_dtype dtype, int32_t dims_size, const int32_t* dims) {
     return check_error([&]() {
-        builder->input_name_and_dtype_and_dims_list.push_back(
-          std::make_tuple(std::string(name), dtype,
-                          std::vector<int32_t>(dims, dims + dims_size)));
+        builder->input_name_and_profile_list.emplace_back(
+          std::string(name), menoh_impl::array_profile(
+                               static_cast<menoh_impl::dtype_t>(dtype),
+                               std::vector<int32_t>(dims, dims + dims_size)));
         return menoh_error_code_success;
     });
 }
@@ -262,8 +262,9 @@ menoh_error_code menoh_variable_profile_table_builder_add_input_profile_dims_2(
   menoh_dtype dtype, int32_t num, int32_t size) {
     return check_error([&]() {
         std::vector<int> dims = {num, size};
-        builder->input_name_and_dtype_and_dims_list.push_back(
-          std::make_tuple(std::string(name), dtype, dims));
+        builder->input_name_and_profile_list.emplace_back(
+          std::string(name), menoh_impl::array_profile(
+                               static_cast<menoh_impl::dtype_t>(dtype), dims));
         return menoh_error_code_success;
     });
 }
@@ -312,8 +313,9 @@ menoh_error_code menoh_variable_profile_table_builder_add_output_profile(
 struct menoh_variable_profile_table {
     std::unordered_map<std::string, menoh_impl::array_profile>
       input_profile_table;
-    std::unordered_map<std::string, std::tuple<menoh_dtype, std::vector<int>>>
+    std::unordered_map<std::string, menoh_impl::array_profile>
       output_profile_table;
+    std::vector<std::string> required_output_name_list;
 };
 
 menoh_error_code menoh_build_variable_profile_table(
@@ -321,49 +323,41 @@ menoh_error_code menoh_build_variable_profile_table(
   const menoh_model_data_handle model_data,
   menoh_variable_profile_table_handle* dst_handle) {
     return check_error([&]() {
-        std::unordered_map<std::string,
-                           std::tuple<menoh_dtype, std::vector<int>>>
-          input_profile_table;
-        std::transform(
-          builder->input_name_and_dtype_and_dims_list.begin(),
-          builder->input_name_and_dtype_and_dims_list.end(),
-          std::inserter(input_profile_table, input_profile_table.end()),
-          [](auto const& t) {
-              return std::make_pair(
-                std::get<0>(t),
-                std::make_tuple(std::get<1>(t), std::get<2>(t)));
-          });
+        std::unordered_map<std::string, menoh_impl::array_profile>
+          input_profile_table(builder->input_name_and_profile_list.begin(),
+                              builder->input_name_and_profile_list.end());
 
+        // FIXME BEGIN dtype inference is also needed
+        // currently dtype is fixed to float
         std::vector<std::pair<std::string, std::vector<int>>>
           input_name_and_dims_pair_list;
-        std::transform(
-          builder->input_name_and_dtype_and_dims_list.begin(),
-          builder->input_name_and_dtype_and_dims_list.end(),
-          std::back_inserter(input_name_and_dims_pair_list), [](auto const& t) {
-              return std::make_pair(std::get<0>(t), std::get<2>(t));
-          });
+        std::transform(builder->input_name_and_profile_list.begin(),
+                       builder->input_name_and_profile_list.end(),
+                       std::back_inserter(input_name_and_dims_pair_list),
+                       [](auto const& p) {
+                           return std::make_pair(p.first, p.second.dims());
+                       });
         auto output_dims_table = menoh_impl::make_output_dims_table(
           model_data->model_data, input_name_and_dims_pair_list);
 
-        std::unordered_map<std::string,
-                           std::tuple<menoh_dtype, std::vector<int>>>
+        std::unordered_map<std::string, menoh_impl::array_profile>
           output_profile_table;
         std::transform(
-          builder->output_name_and_dtype_list.begin(),
-          builder->output_name_and_dtype_list.end(),
+          output_dims_table.begin(), output_dims_table.end(),
           std::inserter(output_profile_table, output_profile_table.end()),
-          [&output_dims_table](auto const& t) {
-              std::string name;
-              menoh_dtype dtype;
-              std::tie(name, dtype) = t;
+          [](auto const& p) {
+              // here fixed to float
               return std::make_pair(
-                name, std::make_tuple(dtype, menoh_impl::find_value(
-                                               output_dims_table, name)));
+                p.first, menoh_impl::array_profile(
+                           static_cast<menoh_impl::dtype_t>(menoh_dtype_float),
+                           p.second));
           });
+        // FIXME END
         *dst_handle =
           std::make_unique<menoh_variable_profile_table>(
             menoh_variable_profile_table{std::move(input_profile_table),
-                                         std::move(output_profile_table)})
+                                         std::move(output_profile_table),
+                                         builder->required_output_name_list})
             .release();
         return menoh_error_code_success;
     });
@@ -405,18 +399,16 @@ menoh_error_code menoh_variable_profile_table_get_dtype(
   const menoh_variable_profile_table_handle variable_profile_table,
   const char* name, menoh_dtype* dst_dtype) {
     return impl::menoh_variable_profile_table_get_variable_attribute(
-      variable_profile_table, name,
-      [&](std::tuple<menoh_dtype, std::vector<int>> const& t) {
-          *dst_dtype = std::get<0>(t);
+      variable_profile_table, name, [&](auto const& profile) {
+          *dst_dtype = static_cast<menoh_dtype>(profile.dtype());
       });
 }
 menoh_error_code menoh_variable_profile_table_get_dims_size(
   const menoh_variable_profile_table_handle variable_profile_table,
   const char* name, int32_t* dst_size) {
     return impl::menoh_variable_profile_table_get_variable_attribute(
-      variable_profile_table, name,
-      [&](std::tuple<menoh_dtype, std::vector<int>> const& t) {
-          *dst_size = static_cast<int32_t>(std::get<1>(t).size());
+      variable_profile_table, name, [&](auto const& profile) {
+          *dst_size = static_cast<int32_t>(profile.dims().size());
       });
 }
 menoh_error_code menoh_variable_profile_table_get_dims_at(
@@ -424,9 +416,7 @@ menoh_error_code menoh_variable_profile_table_get_dims_at(
   const char* name, int32_t index, int32_t* dst_size) {
     return impl::menoh_variable_profile_table_get_variable_attribute(
       variable_profile_table, name,
-      [&](std::tuple<menoh_dtype, std::vector<int>> const& t) {
-          *dst_size = std::get<1>(t).at(index);
-      });
+      [&](auto const& profile) { *dst_size = profile.dims().at(index); });
 }
 
 menoh_error_code menoh_model_data_optimize(
@@ -449,10 +439,11 @@ menoh_error_code menoh_model_data_optimize(
  * model builder
  */
 struct menoh_model_builder {
-    std::unordered_map<std::string, std::tuple<menoh_dtype, std::vector<int>>>
+    std::unordered_map<std::string, menoh_impl::array_profile>
       input_profile_table;
-    std::unordered_map<std::string, std::tuple<menoh_dtype, std::vector<int>>>
+    std::unordered_map<std::string, menoh_impl::array_profile>
       output_profile_table;
+    std::vector<std::string> required_output_name_list;
     std::unordered_map<std::string, void*> external_buffer_handle_table;
 };
 
@@ -460,12 +451,13 @@ menoh_error_code menoh_make_model_builder(
   const menoh_variable_profile_table_handle variable_profile_table,
   menoh_model_builder_handle* dst_handle) {
     return check_error([&]() {
-        *dst_handle =
-          std::make_unique<menoh_model_builder>(
-            menoh_model_builder{variable_profile_table->input_profile_table,
-                                variable_profile_table->output_profile_table,
-                                {}})
-            .release();
+        *dst_handle = std::make_unique<menoh_model_builder>(
+                        menoh_model_builder{
+                          variable_profile_table->input_profile_table,
+                          variable_profile_table->output_profile_table,
+                          variable_profile_table->required_output_name_list,
+                          {}})
+                        .release();
         return menoh_error_code_success;
     });
 }
@@ -511,54 +503,44 @@ menoh_error_code menoh_build_model(const menoh_model_builder_handle builder,
         std::unordered_map<std::string, menoh_impl::array> input_table;
         for(auto p : builder->input_profile_table) {
             std::string name;
-            std::tuple<menoh_dtype, std::vector<int>> t;
-            std::tie(name, t) = p;
-            menoh_dtype dtype;
-            std::vector<int> dims;
-            std::tie(dtype, dims) = t;
+            menoh_impl::array_profile profile;
+            std::tie(name, profile) = p;
 
             auto buff = builder->external_buffer_handle_table.find(name);
 
             if(buff == builder->external_buffer_handle_table.end()) {
-                input_table.insert(
-                  {name, menoh_impl::array(
-                           static_cast<menoh_impl::dtype_t>(dtype), dims)});
+                input_table.emplace(name, menoh_impl::array(profile));
             } else {
-                input_table.insert(
-                  {name,
-                   menoh_impl::array(static_cast<menoh_impl::dtype_t>(dtype),
-                                     dims, buff->second)});
+                input_table.emplace(name,
+                                    menoh_impl::array(profile, buff->second));
             }
         }
 
-        std::unordered_map<std::string, menoh_impl::array> output_table;
-        for(auto p : builder->output_profile_table) {
+        std::unordered_map<std::string, menoh_impl::array>
+          required_output_table;
+        for(auto const& required_output_name :
+            builder->required_output_name_list) {
+            auto p = *builder->output_profile_table.find(required_output_name);
             std::string name;
-            std::tuple<menoh_dtype, std::vector<int>> t;
-            std::tie(name, t) = p;
-            menoh_dtype dtype;
-            std::vector<int> dims;
-            std::tie(dtype, dims) = t;
+            menoh_impl::array_profile profile;
+            std::tie(name, profile) = p;
 
             auto buff = builder->external_buffer_handle_table.find(name);
 
             if(buff == builder->external_buffer_handle_table.end()) {
-                output_table.insert(
-                  {name, menoh_impl::array(
-                           static_cast<menoh_impl::dtype_t>(dtype), dims)});
+                required_output_table.emplace(name, menoh_impl::array(profile));
             } else {
-                output_table.insert(
-                  {name,
-                   menoh_impl::array(static_cast<menoh_impl::dtype_t>(dtype),
-                                     dims, buff->second)});
+                required_output_table.emplace(
+                  name, menoh_impl::array(profile, buff->second));
             }
         }
 
         *dst_model_handle =
           std::make_unique<menoh_model>(
-            menoh_model{input_table, output_table,
+            menoh_model{input_table, required_output_table,
                         menoh_impl::make_model_core(
-                          input_table, output_table, model_data->model_data,
+                          input_table, required_output_table,
+                          builder->output_profile_table, model_data->model_data,
                           backend_name, backend_config)})
             .release();
         return menoh_error_code_success;
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index e810b35..0488321 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -18,6 +18,8 @@ namespace menoh_impl {
               std::unordered_map<std::string, array> const& common_input_table,
               std::unordered_map<std::string, array> const&
                 required_output_table,
+              std::unordered_map<std::string, array_profile> const&
+                output_profile_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
index 7a1bb2b..251e918 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
@@ -32,6 +32,8 @@ namespace menoh_impl {
                     common_input_table,
                   std::unordered_map<std::string, array> const&
                     required_output_table,
+                  std::unordered_map<std::string, array_profile> const&
+                    output_profile_table,
                   std::vector<
                     std::pair<std::string, std::unique_ptr<context>>> const&
                     context_list,
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 243a9e3..14ea6b8 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -22,6 +22,8 @@ namespace menoh_impl {
               std::unordered_map<std::string, array> const& common_input_table,
               std::unordered_map<std::string, array> const&
                 required_output_table,
+              std::unordered_map<std::string, array_profile> const&
+                output_profile_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
@@ -157,5 +159,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    } // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
index 65fb382..493095b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -27,7 +27,7 @@ namespace menoh_impl {
                     auto dims =
                       ::menoh_impl::mkldnn_backend::extract_dims(found->second);
                     auto variable_memory = found->second; // mutable
-                    procedure copy_proc(nullptr); // mutable
+                    procedure copy_proc(nullptr);         // mutable
                     if(dims.size() == 4) {
                         auto format = static_cast<mkldnn::memory::format>(
                           found->second.get_primitive_desc()
@@ -68,6 +68,8 @@ namespace menoh_impl {
                     common_input_table,
                   std::unordered_map<std::string, array> const&
                     required_output_table,
+                  std::unordered_map<std::string, array_profile> const&
+                    output_profile_table,
                   std::vector<
                     std::pair<std::string, std::unique_ptr<context>>> const&
                     context_list,
diff --git a/menoh/mkldnn_with_generic_fallback/context.hpp b/menoh/mkldnn_with_generic_fallback/context.hpp
index f8aafbc..de56e1f 100644
--- a/menoh/mkldnn_with_generic_fallback/context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/context.hpp
@@ -29,6 +29,8 @@ namespace menoh_impl {
               std::unordered_map<std::string, array> const& common_input_table,
               std::unordered_map<std::string, array> const&
                 required_output_table,
+              std::unordered_map<std::string, array_profile> const&
+                output_profile_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
@@ -36,7 +38,8 @@ namespace menoh_impl {
                 return do_process_node_list(
                   context_name, current_index, node_list,
                   common_parameter_table, common_input_table,
-                  required_output_table, context_list, logger);
+                  required_output_table, output_profile_table, context_list,
+                  logger);
             }
 
             // for specialized optimization across backends
@@ -57,6 +60,8 @@ namespace menoh_impl {
               std::unordered_map<std::string, array> const& common_input_table,
               std::unordered_map<std::string, array> const&
                 required_output_table,
+              std::unordered_map<std::string, array_profile> const&
+                output_profile_table,
               std::vector<
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index a39c678..273d607 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -25,6 +25,8 @@ namespace menoh_impl {
             context_list,
           std::unordered_map<std::string, array> const& input_table,
           std::unordered_map<std::string, array> const& output_table,
+          std::unordered_map<std::string, array_profile> const&
+            output_profile_table,
           menoh_impl::model_data const& model_data,
           backend_config const& config)
           : menoh_impl::model_core(),
@@ -72,7 +74,8 @@ namespace menoh_impl {
                       context->process_node_list(
                         context_name, current_index, graph.node_list(),
                         common_parameter_table_, common_input_table_,
-                        required_output_table_, context_list_, logger_.get());
+                        required_output_table_, output_profile_table,
+                        context_list_, logger_.get());
 
                     // if succeeded processing, add procedures into
                     // procedure_list
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.hpp b/menoh/mkldnn_with_generic_fallback/model_core.hpp
index e4cc405..dc19dc4 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.hpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.hpp
@@ -24,6 +24,8 @@ namespace menoh_impl {
                 context_list,
               std::unordered_map<std::string, array> const& input_table,
               std::unordered_map<std::string, array> const& output_table,
+              std::unordered_map<std::string, array_profile> const&
+                output_profile_table,
               menoh_impl::model_data const& model_data, backend_config const& config);
 
         private:
diff --git a/menoh/model.cpp b/menoh/model.cpp
deleted file mode 100644
index 24be8e9..0000000
--- a/menoh/model.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <menoh/model.hpp>
-
-#include <menoh/utility.hpp>
-
-namespace menoh_impl {
-
-    model::model(
-      std::vector<
-        std::tuple<std::string, dtype_t, std::vector<int>, void*>> const&
-        input_name_and_dtype_and_dims_and_data_handle_list,
-      std::vector<std::tuple<std::string, dtype_t, void*>> const&
-        required_output_name_and_dtype_and_data_handle_list,
-      menoh_impl::model_data const& model_data, std::string const& backend_name,
-      backend_config const& config) {
-        std::vector<std::pair<std::string, std::vector<int>>>
-          input_name_and_dims_pair_list;
-        for(auto const& t :
-            input_name_and_dtype_and_dims_and_data_handle_list) {
-            std::string input_name;
-            dtype_t dtype;
-            std::vector<int> input_dims;
-            void* data_handle;
-            std::tie(input_name, dtype, input_dims, data_handle) = t;
-            assert(input_table_.find(input_name) == input_table_.end());
-            if(data_handle) {
-                input_table_.insert(
-                  {input_name, array(dtype, input_dims, data_handle)});
-            } else {
-                input_table_.insert({input_name, array(dtype, input_dims)});
-            }
-            input_name_and_dims_pair_list.push_back({input_name, input_dims});
-        }
-
-        auto output_dims_table =
-          make_output_dims_table(model_data, input_name_and_dims_pair_list);
-
-        std::unordered_map<std::string, array> output_table;
-        for(auto const& t :
-            required_output_name_and_dtype_and_data_handle_list) {
-            std::string output_name;
-            dtype_t dtype;
-            void* data_handle;
-            std::tie(output_name, dtype, data_handle) = t;
-            assert(output_table_.find(output_name) == output_table_.end());
-            if(data_handle) {
-                output_table_.insert(
-                  {output_name,
-                   array(dtype, find_value(output_dims_table, output_name),
-                         data_handle)});
-            } else {
-                output_table_.insert(
-                  {output_name,
-                   array(dtype, find_value(output_dims_table, output_name))});
-            }
-        }
-
-        model_ = make_model_core(input_table_, output_table_, model_data,
-                                 backend_name, config);
-    }
-
-    array const& model::input(std::string const& name) const {
-        return find_value(input_table_, name);
-    }
-
-    array const& model::output(std::string const& name) const {
-        return find_value(output_table_, name);
-    }
-
-    void model::run() { model_->run(); }
-
-} // namespace menoh_impl
diff --git a/menoh/model.hpp b/menoh/model.hpp
deleted file mode 100644
index 0664ef9..0000000
--- a/menoh/model.hpp
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef MENOH_MODEL_HPP
-#define MENOH_MODEL_HPP
-
-#include <memory>
-#include <string>
-#include <tuple>
-#include <unordered_map>
-#include <unordered_set>
-#include <vector>
-
-#include <menoh/array.hpp>
-#include <menoh/backend_config.hpp>
-#include <menoh/model_core.hpp>
-#include <menoh/model_core_factory.hpp>
-#include <menoh/model_data.hpp>
-
-namespace menoh_impl {
-
-    class model {
-    public:
-        model(
-          std::vector<
-            std::tuple<std::string, dtype_t, std::vector<int>, void*>> const&
-            input_name_and_dtype_and_dims_and_data_handle_list,
-          std::vector<std::tuple<std::string, dtype_t, void*>> const&
-            required_output_name_and_dtype_and_data_handle_list,
-          menoh_impl::model_data const& model_data, std::string const& backend_name,
-          backend_config const& config = backend_config());
-
-        array const& input(std::string const& name) const;
-
-        array const& output(std::string const& name) const;
-
-        void run();
-
-    private:
-        std::unordered_map<std::string, array> input_table_;
-        std::unordered_map<std::string, array> output_table_;
-        std::unique_ptr<model_core> model_;
-    };
-
-} // namespace menoh_impl
-#endif // MENOH_MODEL_HPP
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index 9d1a582..aa47dd4 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -11,13 +11,15 @@ namespace menoh_impl {
 
     std::unique_ptr<menoh_impl::model_core>
     make_model_core(std::unordered_map<std::string, array> const& input_table,
-                    std::unordered_map<std::string, array> const& output_table,
+                    std::unordered_map<std::string, array> const& required_output_table,
+                    std::unordered_map<std::string, array_profile> const&
+                      output_profile_table,
                     menoh_impl::model_data const& model_data,
                     std::string const& backend_name,
                     backend_config const& config) {
         if(backend_name == "mkldnn") {
             return std::make_unique<mkldnn_backend::model_core>(
-              mkldnn_backend::make_model_core(input_table, output_table,
+              mkldnn_backend::make_model_core(input_table, required_output_table,
                                               model_data, config));
         } else if(backend_name == "mkldnn_with_generic_fallback") {
             using namespace mkldnn_with_generic_fallback_backend;
@@ -32,8 +34,8 @@ namespace menoh_impl {
                                  generic_backend::generic_context>());
             return std::make_unique<
               mkldnn_with_generic_fallback_backend::model_core>(
-              std::move(context_list), input_table, output_table, model_data,
-              config);
+              std::move(context_list), input_table, required_output_table,
+              output_profile_table, model_data, config);
         }
 
         throw invalid_backend_name(backend_name);
diff --git a/menoh/model_core_factory.hpp b/menoh/model_core_factory.hpp
index d249057..52037e7 100644
--- a/menoh/model_core_factory.hpp
+++ b/menoh/model_core_factory.hpp
@@ -22,12 +22,13 @@ namespace menoh_impl {
 
     struct model_data;
 
-    std::unique_ptr<menoh_impl::model_core>
-    make_model_core(std::unordered_map<std::string, array> const& input_table,
-                    std::unordered_map<std::string, array> const& output_table,
-                    menoh_impl::model_data const& model_data,
-                    std::string const& backend_name,
-                    backend_config const& config = backend_config());
+    std::unique_ptr<menoh_impl::model_core> make_model_core(
+      std::unordered_map<std::string, array> const& input_table,
+      std::unordered_map<std::string, array> const& required_output_table,
+      std::unordered_map<std::string, array_profile> const&
+        output_profile_table,
+      menoh_impl::model_data const& model_data, std::string const& backend_name,
+      backend_config const& config = backend_config());
 
 } // namespace menoh_impl
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index dd301be..04f9813 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -17,10 +17,8 @@ add_executable(menoh_test
     node.cpp
     graph.cpp
     onnx.cpp
-    mkldnn.cpp
 
     operator.cpp
-    model.cpp
     mkldnn_with_generic_fallback_backend.cpp
     model_data.cpp
     #vgg16.cpp
diff --git a/test/mkldnn.cpp b/test/mkldnn.cpp
deleted file mode 100644
index 8799591..0000000
--- a/test/mkldnn.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <fstream>
-#include <iostream>
-#include <numeric>
-#include <string>
-#include <tuple>
-
-#include <google/protobuf/io/coded_stream.h>
-#include <google/protobuf/io/zero_copy_stream_impl.h>
-
-#include <menoh/mkldnn/model_core.hpp>
-#include <menoh/model.hpp>
-#include <menoh/onnx.hpp>
-#include <menoh/utility.hpp>
-
-namespace menoh_impl {
-    namespace {
-
-        class MKLDNNTest : public ::testing::Test {};
-
-        TEST_F(MKLDNNTest, run_onnx_model) {
-            static mkldnn::engine engine(mkldnn::engine::cpu, 0);
-            auto model_data =
-              make_model_data_from_onnx_file("../data/VGG16.onnx");
-            // model_data = trim_redundant_nodes(model_data);
-
-            auto input_name_list = extract_model_input_name_list(model_data);
-            if(input_name_list.size() != 1) {
-                throw std::runtime_error(
-                  "VGG16 data is invalid: input name list size is " +
-                  std::to_string(input_name_list.size()));
-            }
-            auto const& input_name = input_name_list.front();
-            constexpr auto batch_size = 1;
-            constexpr auto channel_num = 3;
-            constexpr auto height = 224;
-            constexpr auto width = 224;
-            std::vector<int> input_dims{batch_size, channel_num, height, width};
-            array input_arr(dtype_t::float_, input_dims);
-
-            auto output_name_list = extract_model_output_name_list(model_data);
-            if(output_name_list.size() != 1) {
-                throw std::runtime_error(
-                  "VGG16 data is invalid: input name list size is " +
-                  std::to_string(output_name_list.size()));
-            }
-            auto const& output_name = output_name_list.front();
-            auto output_dims_table =
-              make_output_dims_table(model_data, {{input_name, input_dims}});
-            array output_arr(dtype_t::float_,
-                             find_value(output_dims_table, output_name));
-            auto model = menoh_impl::mkldnn_backend::model_core(
-              {
-                {input_name, input_arr},
-              },
-              {
-                {output_name, output_arr},
-              },
-              model_data, engine);
-            model.run();
-            auto max_i =
-              std::max_element(fbegin(output_arr), fend(output_arr)) -
-              fbegin(output_arr);
-            std::cout << "max_i " << max_i << std::endl;
-        }
-
-        TEST_F(MKLDNNTest, make_mkldnn_model_with_invalid_backend_config) {
-            // Aliases to onnx's node input and output tensor name
-            auto conv1_1_in_name = "140326425860192";
-            auto softmax_out_name = "140326200803680";
-
-            constexpr auto batch_size = 1;
-            constexpr auto channel_num = 3;
-            constexpr auto height = 224;
-            constexpr auto width = 224;
-            // category_num is 1000
-
-            std::vector<int> input_dims{batch_size, channel_num, height, width};
-
-            // Load ONNX model data
-            auto model_data =
-              menoh_impl::make_model_data_from_onnx_file("../data/VGG16.onnx");
-
-            auto cpu_count =
-              mkldnn::engine::get_count(mkldnn::engine::kind::cpu);
-
-            // Construct computation primitive list and memories
-            ASSERT_THROW(
-              menoh_impl::model(
-                {std::make_tuple(
-                  conv1_1_in_name, menoh_impl::dtype_t::float_, input_dims,
-                  nullptr)}, // table of input_name, dtype, input_dims and
-                             // data_handle
-                {std::make_tuple(
-                  softmax_out_name, menoh_impl::dtype_t::float_,
-                  nullptr)}, // list of output names, dtypes and data_handles
-                model_data,
-                "mkldnn", "{\"cpu_id\":" + std::to_string(cpu_count + 2) + "}"),
-              menoh_impl::backend_error);
-        }
-
-    } // namespace
-} // namespace menoh_impl
diff --git a/test/model.cpp b/test/model.cpp
deleted file mode 100644
index 8509662..0000000
--- a/test/model.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <mkldnn.hpp>
-
-#include <menoh/model.hpp>
-#include <menoh/onnx.hpp>
-
-namespace menoh_impl {
-    namespace {
-        class ModelTest : public ::testing::Test {};
-
-        TEST_F(ModelTest, make_model) {
-            // Aliases to onnx's node input and output tensor name
-            auto conv1_1_in_name = "140326425860192";
-            auto softmax_out_name = "140326200803680";
-
-            constexpr auto batch_size = 1;
-            constexpr auto channel_num = 3;
-            constexpr auto height = 224;
-            constexpr auto width = 224;
-            // category_num is 1000
-
-            std::vector<int> input_dims{batch_size, channel_num, height, width};
-
-            // Load ONNX model data
-            auto model_data = std::make_unique<menoh_impl::model_data>(
-              menoh_impl::make_model_data_from_onnx_file("../data/VGG16.onnx"));
-
-            // Construct computation primitive list and memories
-            auto model = menoh_impl::model(
-              {std::make_tuple(conv1_1_in_name, dtype_t::float_, input_dims,
-                               nullptr)},
-              {std::make_tuple(softmax_out_name, dtype_t::float_, nullptr)},
-              *model_data, "mkldnn");
-            model_data.reset(); // delete model_data
-
-            model.run();
-        }
-
-    } // namespace
-} // namespace menoh_impl

From fc3ec79e1b5fcd1e54b178c63620d7b785abf1e3 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 27 Sep 2018 10:58:06 +0900
Subject: [PATCH 151/321] update C++ API

---
 include/menoh/menoh.hpp | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index e901f0b..b884971 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -280,13 +280,23 @@ namespace menoh {
                 dims.size(), dims.data()));
         }
 
-        //! Add output profile. That profile contains name, dtype.
-        /*! dims of output is calculated automatically.
+        //! Add a name of required output
+        /*! dtype and dims of output are calculated automatically.
          */
-        void add_output_profile(std::string const& name, dtype_t dtype) {
+        void add_output_name(std::string const& name) {
             MENOH_CPP_API_ERROR_CHECK(
-              menoh_variable_profile_table_builder_add_output_profile(
-                impl_.get(), name.c_str(), static_cast<menoh_dtype>(dtype)));
+              menoh_variable_profile_table_builder_add_output_name(
+                impl_.get(), name.c_str()));
+        }
+
+        //! Add output profile. That profile contains name and dtype
+        /*! dims of output are calculated automatically.
+         * \note This function is deprecated. Given dtype is totally ignored and
+         * inferenced by dtype of input. Use add_output_name() instead.
+         */
+        [[deprecated("Use add_output_name() instead")]]
+        void add_output_profile(std::string const& name, dtype_t) {
+            add_output_name(name);
         }
 
         //! Factory function for variable_profile_table.

From 9dac97a8926df67eae80d7d06f4fabb7087596ed Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 27 Sep 2018 10:59:18 +0900
Subject: [PATCH 152/321] update benchmark and test code

---
 benchmark/vgg16_benchmark.cpp                 | 2 +-
 test/backend.hpp                              | 3 +--
 test/mkldnn_with_generic_fallback_backend.cpp | 5 ++---
 3 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/benchmark/vgg16_benchmark.cpp b/benchmark/vgg16_benchmark.cpp
index 230edac..845b9f3 100644
--- a/benchmark/vgg16_benchmark.cpp
+++ b/benchmark/vgg16_benchmark.cpp
@@ -35,7 +35,7 @@ int main(int argc, char** argv) {
     menoh::variable_profile_table_builder vpt_builder;
     vpt_builder.add_input_profile(conv1_1_in_name, menoh::dtype_t::float_,
                                   {batch_size, 3, 224, 224});
-    vpt_builder.add_output_profile(softmax_out_name, menoh::dtype_t::float_);
+    vpt_builder.add_output_name(softmax_out_name);
     auto vpt = vpt_builder.build_variable_profile_table(model_data);
 
     // Build model
diff --git a/test/backend.hpp b/test/backend.hpp
index 0f42985..f16c150 100644
--- a/test/backend.hpp
+++ b/test/backend.hpp
@@ -61,9 +61,8 @@ namespace menoh {
             std::vector<float> data;
             std::tie(std::ignore, output_dims, data) =
               menoh_impl::load_np_array(output_filename);
-            dtype_t dtype = dtype_t::float_; // TODO other dtype
             true_output_table.insert({output_name, data});
-            vpt_builder.add_output_profile(output_name, dtype);
+            vpt_builder.add_output_name(output_name);
         }
 
         auto vpt = vpt_builder.build_variable_profile_table(model_data);
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index cfe8c45..58540ce 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -69,15 +69,14 @@ namespace menoh {
             std::string output_name;
             std::tie(output_name, std::ignore) = gemm_true_output_filename;
             model_data.add_output_name_to_current_node(output_name);
-            dtype_t dtype = dtype_t::float_; // TODO other dtype
-            vpt_builder.add_output_profile(output_name, dtype);
+            vpt_builder.add_output_name(output_name);
         }
 
         {
             model_data.add_new_node("Relu");
             model_data.add_input_name_to_current_node("gemm_out");
             model_data.add_output_name_to_current_node("relu_out");
-            vpt_builder.add_output_profile("relu_out", dtype_t::float_);
+            vpt_builder.add_output_name("relu_out");
         }
 
         auto vpt = vpt_builder.build_variable_profile_table(model_data);

From ee82a5d4d52427d440ae796178d6949dea16a1a9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 24 Sep 2018 23:36:14 +0900
Subject: [PATCH 153/321] add gen_graph_completion_hpp.py

---
 gen_graph_completion_hpp.py | 320 ++++++++++++++++++++++++++++++++++++
 1 file changed, 320 insertions(+)
 create mode 100644 gen_graph_completion_hpp.py

diff --git a/gen_graph_completion_hpp.py b/gen_graph_completion_hpp.py
new file mode 100644
index 0000000..dc46b12
--- /dev/null
+++ b/gen_graph_completion_hpp.py
@@ -0,0 +1,320 @@
+
+
+def make_completion_code(op_name,
+                         attribute_list=[],
+                         shape_inference_code='''
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+''',
+                         preprocess="",
+                         postprocess=""):
+    # attribute completion and definition
+    attribute_completion_code_list = []
+    attribute_definition_list = []
+    for attribute in attribute_list:
+        attr_name, attr_type, default_value = attribute
+        inner_code = ''
+        if default_value is None:
+            inner_code = '''
+assert(!"attribute not found: {attr_name}");
+'''.format(attr_name=attr_name)
+        else:
+            inner_code = '''
+node.attribute_table.emplace(
+    "{attr_name}", {default_value});
+'''.format(attr_name=attr_name, default_value=default_value)
+
+        attribute_completion_code = '''
+{{
+    auto found = node.attribute_table.find("{attr_name}");
+    if(found == node.attribute_table.end()) {{
+        {code}
+    }}
+}}
+'''.format(attr_name=attr_name, attr_type=attr_type, code=inner_code)
+        attribute_completion_code_list.append(attribute_completion_code)
+
+        attribute_definition = '''
+auto {attr_name} = get<{attr_type}>(node.attribute_table.at("{attr_name}"));
+'''.format(attr_name=attr_name, attr_type=attr_type)
+        attribute_definition_list.append(attribute_definition)
+    # end for
+
+    template = '''
+if(node.op_type == "{op_name}") {{
+    {preprocess}
+    {attribute_completion_code}
+    {postprocess}
+    {{
+        {attribute_definition}
+        {shape_inference_code}
+    }}
+}}
+else
+'''
+    return template.format(
+        op_name=op_name,
+        preprocess=preprocess,
+        attribute_definition="\n".join(attribute_definition_list),
+        shape_inference_code=shape_inference_code,
+        postprocess=postprocess,
+        attribute_completion_code="\n".join(
+            attribute_completion_code_list))
+
+
+def main():
+    template = """
+#ifndef MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+#define MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+
+#include <iostream>
+
+#include <algorithm>
+#include <cassert>
+#include <string>
+#include <unordered_map>
+
+#include <menoh/array.hpp>
+#include <menoh/model_data.hpp>
+
+namespace menoh_impl {{
+    inline auto complete_attribute_and_inference_shape(
+            model_data& model_data,
+            std::unordered_map<std::string, array_profile> const&
+                input_profile_table) {{
+        using ints = std::vector<int>;
+        std::unordered_map<std::string, array_profile> variable_profile_table(
+            input_profile_table.begin(), input_profile_table.end());
+        std::transform(
+            model_data.parameter_name_and_array_list.begin(),
+            model_data.parameter_name_and_array_list.end(),
+            std::inserter(variable_profile_table,
+                          variable_profile_table.end()),
+            [](auto const& p){{
+                return std::make_pair(
+                    p.first,
+                    array_profile(p.second.dtype(), p.second.dims())); }});
+        auto profile_of = [&variable_profile_table](std::string const& name){{
+            assert(variable_profile_table.find(name) ==
+                variable_profile_table.end());
+            return variable_profile_table.at(name);
+        }};
+        auto dims_of = [&variable_profile_table, profile_of](
+            std::string const& name){{
+                return profile_of(name).dims();
+        }};
+        auto dtype_of = [&variable_profile_table, profile_of](
+            std::string const& name){{
+                return profile_of(name).dtype();
+        }};
+        auto ndims_of = [&dims_of](std::string const& parameter_name) {{
+            return dims_of(parameter_name).size();
+        }};
+        auto add_variable_to_table = [&variable_profile_table](
+            std::string const& name,
+            dtype_t dtype, ints const& dims){{
+                variable_profile_table.emplace(
+                    name, array_profile(dtype, dims));
+            }};
+
+        auto graph = make_graph(model_data.node_list); // FIXME reorder nodes
+        model_data.node_list = graph.node_list();
+        for(auto& node : model_data.node_list) {{
+            auto input = [&node](int i){{
+                return node.input_name_list.at(i);
+            }};
+            auto output = [&node](int i){{
+                return node.output_name_list.at(i);
+            }};
+            {code}
+            {unsupported_operator}
+        }}
+        return variable_profile_table;
+    }}
+}} // namespace menoh_impl
+
+#endif // MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+"""
+    code_list = []
+    code_list.append(make_completion_code("Abs"))
+    code_list.append(make_completion_code("Add"))
+    code_list.append(
+        make_completion_code("AveragePool", [
+            ("count_include_pad", "int", "0"),
+            ("kernel_shape", "ints", None),
+            ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
+            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"),  # WORKAROUND: None is correct
+        ], '''
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(0)).at(1),
+        kernel_shape, strides, pads));
+''', preprocess='''
+assert(2 <= ndims_of(input(0)));
+'''))
+    code_list.append(
+        make_completion_code("BatchNorm", [
+            ("epsilon", "float", "1.e-05f"),
+            ("momentum", "float", "0.9f"),
+            ("spatial", "int", "1"),
+        ]))
+    code_list.append(
+        make_completion_code("Concat", [
+            ("axis", "int", None),
+        ], '''
+auto output_dims = dims_of(input(0));
+for(int i = 1; i < node.input_name_list.size(); ++i) {
+    // TODO dim check
+    output_dims.at(axis) += dims_of(input(i)).at(axis);
+}
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+'''))
+    code_list.append(
+        make_completion_code(
+            "Conv", [
+                ("dilations", "ints", "ints(kernel_ndims, 1)"),
+                ("group", "int", "1"),
+                ("kernel_shape", "ints", "kernel_shape"),
+                ("pads", "ints", "ints(kernel_ndims*2, 0)"),
+                ("strides", "ints", "ints(kernel_ndims, 1)"),
+            ], '''
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(1)).at(0),
+        kernel_shape, strides, pads));
+''',
+            preprocess='''
+auto kernel_ndims = ndims_of(input(1))-2;
+auto weights_shape = dims_of(input(1));
+auto kernel_shape = ints(weights_shape.begin()+2, weights_shape.end());
+'''))
+    code_list.append(
+        make_completion_code(
+            "ConvTranspose",
+            [
+                ("dilations", "ints", None),
+                ("group", "int", "1"),
+                ("kernel_shape", "ints", "kernel_shape"),
+                ("output_padding", "ints", None),
+                # ("output_shape", "ints", None),
+                # ("pads", "ints", None),
+                ("strides", "ints", "ints(kernel_ndims, 1)"),
+            ], '''
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims_for_conv_transpose(
+        dims_of(input(0)), dims_of(input(1)).at(0),
+        kernel_shape, strides, get<ints>(node.attribute_table.at("pads"))));
+''',
+            preprocess='''
+auto kernel_ndims = ndims_of(input(1))-2;
+auto weights_shape = dims_of(input(1));
+auto kernel_shape = ints(weights_shape.begin()+2, weights_shape.end());
+''',
+            postprocess='''
+{
+    auto found = node.attribute_table.find("output_shape");
+    assert(!(found == node.attribute_table.end() &&
+       node.attribute_table.find("pads") == node.attribute_table.end()));
+    if(found != node.attribute_table.end()) {
+        auto output_shape = get<ints>(found->second);
+        /* [dim0_begin, dim1_begin, ... , dim0_end, dim1_end, ..., ...] */
+        ints pads(kernel_ndims*2, 0);
+        auto output_padding =
+            get<ints>(node.attribute_table.at("output_padding"));
+        auto strides = get<ints>(node.attribute_table.at("strides"));
+        auto input_profile = input_profile_table.at(input(0));
+        ints input_size(input_profile.dims().begin()+2,
+                        input_profile.dims().end());
+
+        for(int i = 0; i < kernel_ndims; ++i) {
+            auto total_padding = strides[i] * (input_size[i] - 1)
+                + output_padding[i] + kernel_shape[i] - output_shape[i];
+            pads[i] = total_padding - (total_padding/2);
+            pads[i+kernel_ndims] = (total_padding/2);
+        }
+
+        node.attribute_table["pads"] = pads;
+    }
+}
+'''))
+    code_list.append(make_completion_code("Elu", [("alpha", "float", "1.f")]))
+    code_list.append(
+        make_completion_code("FC", [], '''
+auto output_dims = ints({dims_of(input(0)).at(0), dims_of(input(1)).at(0)});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
+'''))
+    code_list.append(
+        make_completion_code("Gemm", [
+            ("alpha", "float", "1.f"),
+            ("beta", "float", "1.f"),
+            ("transA", "int", "0"),
+            ("transB", "int", "0"),
+        ], '''
+auto a_dims = dims_of(input(0));
+assert(a_dims.size() == 2);
+if(transA) {
+    std::swap(a_dims.at(0), a_dims.at(1));
+}
+
+auto b_dims = dims_of(input(1));
+assert(b_dims.size() == 2);
+if(transB) {
+    std::swap(b_dims.at(0), b_dims.at(1));
+}
+
+auto output_dims = ints({a_dims.at(0), b_dims.at(1)});
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+'''))
+    code_list.append(
+        make_completion_code("LeakyRelu", [("alpha", "float", "0.01f")]))
+    code_list.append(
+        make_completion_code("LRN", [
+            ("alpha", "float", "0.0001f"),
+            ("beta", "float", "0.75f"),
+            ("bias", "float", "1.0f"),
+            ("size", "float", None),
+        ]))
+    code_list.append(
+        make_completion_code("MaxPool", [
+            ("kernel_shape", "ints", None),
+            ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
+            ("storage_order", "int", "0"),
+            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"), # WORKAROUND: None is correct
+        ], '''
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(0)).at(1),
+        kernel_shape, strides, pads));
+'''))
+    code_list.append(make_completion_code("Relu"))
+    code_list.append(make_completion_code("Softmax", [("axis", "int", "1")]))
+    code_list.append(make_completion_code("Sum"))
+    code_list.append(make_completion_code("Sqrt"))
+    code_list.append(make_completion_code("Tanh"))
+    code_list.append(
+        make_completion_code("Transpose", [
+            ("perm", "ints", "perm"),
+        ], '''
+auto input_dims = dims_of(input(0));
+ints output_dims(input_dims.size());
+for(int i = 0; i < input_dims.size(); ++i) {
+    output_dims.at(i) = input_dims.at(perm.at(i));
+}
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+''', preprocess="""
+ints perm(ndims_of(input(0)));
+for(int i = 0; i < perm.size(); ++i) {{
+    perm.at(i) = perm.size()-i-1;
+}}
+"""))
+    print(template.format(code="\n".join(code_list), unsupported_operator='''
+{
+    throw unsupported_operator(node.op_type);
+}
+'''))
+
+
+if __name__ == "__main__":
+    main()

From 2c23b3030881c24b4808ab72c9282d4fd09afe23 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 26 Sep 2018 20:54:01 +0900
Subject: [PATCH 154/321] replace make_output_dims_table

---
 ...bute_completion_and_shape_inference_hpp.py |   0
 menoh/graph.cpp                               | 182 ------------------
 menoh/graph.hpp                               |   5 -
 menoh/menoh.cpp                               |  29 +--
 4 files changed, 4 insertions(+), 212 deletions(-)
 rename gen_graph_completion_hpp.py => gen_attribute_completion_and_shape_inference_hpp.py (100%)

diff --git a/gen_graph_completion_hpp.py b/gen_attribute_completion_and_shape_inference_hpp.py
similarity index 100%
rename from gen_graph_completion_hpp.py
rename to gen_attribute_completion_and_shape_inference_hpp.py
diff --git a/menoh/graph.cpp b/menoh/graph.cpp
index 2a049f9..0f8789a 100644
--- a/menoh/graph.cpp
+++ b/menoh/graph.cpp
@@ -221,186 +221,4 @@ namespace menoh_impl {
                         node_list.end());
     }
 
-    std::unordered_map<std::string, std::vector<int>> make_output_dims_table(
-      menoh_impl::model_data const& model_data,
-      std::vector<std::pair<std::string, std::vector<int>>> const&
-        input_name_and_dims_pair_list) {
-
-        std::vector<std::string> supported_operator_list{{"Abs",
-                                                          "Elu",
-                                                          "LeakyRelu",
-                                                          "Relu",
-                                                          "Sqrt",
-                                                          "Tanh",
-                                                          "AveragePool",
-                                                          "Add",
-                                                          "BatchNormalization",
-                                                          "Concat",
-                                                          "Conv",
-                                                          "ConvTranspose",
-                                                          "FC",
-                                                          "Gemm",
-                                                          "GlobalAveragePool",
-                                                          "GlobalMaxPool",
-                                                          "LRN",
-                                                          "MaxPool",
-                                                          "Softmax",
-                                                          "Sum"}};
-
-        std::unordered_map<std::string, std::vector<int>> variable_dims_table(
-          input_name_and_dims_pair_list.begin(),
-          input_name_and_dims_pair_list.end());
-        std::transform(
-          model_data.parameter_name_and_array_list.begin(),
-          model_data.parameter_name_and_array_list.end(),
-          std::inserter(variable_dims_table, variable_dims_table.end()),
-          [](auto const& p) {
-              return std::make_pair(p.first, p.second.dims());
-          });
-        auto graph = make_graph(model_data.node_list);
-        for(auto const& node : graph.node_list()) {
-            if(node.op_type == "Conv") {
-                auto weight_name = node.input_name_list.at(1);
-                auto output_channel_num =
-                  get_output_channel_num_from_parameter_dims(
-                    find_value(variable_dims_table, weight_name));
-                auto output_dims = calc_2d_output_dims(node, output_channel_num,
-                                                       variable_dims_table);
-                auto dilations =
-                  optional_attribute_ints(node, "dilations", {1, 1});
-                if(dilations != std::vector<int>({1, 1})) {
-                    auto actual = "(" + std::to_string(dilations.at(0)) + ", " +
-                                  std::to_string(dilations.at(1)) + ")";
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "dilations",
-                      actual, "(1, 1)");
-                }
-                auto group = optional_attribute_int(node, "group", 1);
-                if(group != 1) {
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "group",
-                      std::to_string(group), "1");
-                }
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(node.op_type == "ConvTranspose") {
-                auto weight_name = node.input_name_list.at(1);
-                auto output_channel_num =
-                  get_output_channel_num_from_parameter_dims(
-                    find_value(variable_dims_table, weight_name));
-                auto output_dims = calc_2d_output_dims_for_conv_transpose(
-                  node, output_channel_num, variable_dims_table);
-                auto dilations =
-                  optional_attribute_ints(node, "dilations", {1, 1});
-                if(dilations != std::vector<int>({1, 1})) {
-                    auto actual = "(" + std::to_string(dilations.at(0)) + ", " +
-                                  std::to_string(dilations.at(1)) + ")";
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "dilations",
-                      actual, "(1, 1)");
-                }
-                auto group = optional_attribute_int(node, "group", 1);
-                if(group != 1) {
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "group",
-                      std::to_string(group), "1");
-                }
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(node.op_type == "MaxPool" ||
-                      node.op_type == "AveragePool") {
-                auto input_name = node.input_name_list.at(0);
-                auto output_channel_num = get_channel_num_from_variable_dims(
-                  find_value(variable_dims_table, input_name));
-                if(node.op_type == "AveragePool") {
-                    auto pads = optional_attribute_ints(node, "pads", {0, 0});
-                    auto count_include_pad = optional_attribute_int(
-                      node, "count_include_pad", 1); // TODO
-                    if(pads != std::vector<int>({0, 0}) &&
-                       count_include_pad == 0) {
-                        throw unsupported_operator_attribute(
-                          node.op_type, node.output_name_list.front(),
-                          "count_include_pad",
-                          std::to_string(count_include_pad), "0");
-                    }
-                }
-                auto output_dims = calc_2d_output_dims(node, output_channel_num,
-                                                       variable_dims_table);
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(node.op_type == "GlobalMaxPool" ||
-                      node.op_type == "GlobalAveragePool") {
-                auto input_name = node.input_name_list.at(0);
-                auto input_dims = find_value(variable_dims_table, input_name);
-                auto output_dims = input_dims;
-                output_dims.at(2) = 1;
-                output_dims.at(3) = 1;
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(node.op_type == "FC") {
-                auto input_name = node.input_name_list.at(0);
-                auto input_dims = find_value(variable_dims_table, input_name);
-                auto batch_size = get_batch_size_from_variable_dims(
-                  find_value(variable_dims_table, input_name));
-                auto weight_dims =
-                  find_value(variable_dims_table, node.input_name_list.at(1));
-                auto input_size =
-                  std::accumulate(input_dims.begin() + 1, input_dims.end(), 1,
-                                  std::multiplies<void>());
-                if(input_size != weight_dims[1]) {
-                    throw dimension_mismatch(
-                      node.op_type, node.output_name_list.front(),
-                      "input[1] and weight[1]", std::to_string(input_size),
-                      std::to_string(weight_dims[1]));
-                }
-                std::vector<int> output_dims{batch_size, weight_dims[0]};
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(node.op_type == "Gemm") {
-                auto input_name = node.input_name_list.at(0);
-                auto input_dims = find_value(variable_dims_table, input_name);
-                auto batch_size = get_batch_size_from_variable_dims(
-                  find_value(variable_dims_table, input_name));
-                auto weight_dims =
-                  find_value(variable_dims_table, node.input_name_list.at(1));
-                auto trans_a = optional_attribute_int(node, "transA", 0);
-                if(trans_a) {
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "transA",
-                      std::to_string(trans_a), "0");
-                }
-                auto trans_b = optional_attribute_int(node, "transB", 0);
-                if(!trans_b) {
-                    throw unsupported_operator_attribute(
-                      node.op_type, node.output_name_list.front(), "transB",
-                      std::to_string(trans_b), "1");
-                }
-                auto input_size =
-                  std::accumulate(input_dims.begin() + 1, input_dims.end(), 1,
-                                  std::multiplies<void>());
-                if(input_size != weight_dims[1]) {
-                    throw dimension_mismatch(
-                      node.op_type, node.output_name_list.front(),
-                      "input[1] and weight[1]", std::to_string(input_size),
-                      std::to_string(weight_dims[1]));
-                }
-                std::vector<int> output_dims{batch_size, weight_dims[0]};
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else if(std::find(supported_operator_list.begin(),
-                                supported_operator_list.end(),
-                                node.op_type) !=
-                      supported_operator_list
-                        .end()) { // check if supported operator
-                auto input_name = node.input_name_list.at(0);
-                auto output_dims = find_value(variable_dims_table, input_name);
-                variable_dims_table.insert(
-                  {node.output_name_list.at(0), output_dims});
-            } else {
-                throw unsupported_operator(node.op_type);
-            }
-        }
-        return variable_dims_table;
-    } // namespace menoh_impl
-
 } // namespace menoh_impl
diff --git a/menoh/graph.hpp b/menoh/graph.hpp
index 801a44d..7c7fe17 100644
--- a/menoh/graph.hpp
+++ b/menoh/graph.hpp
@@ -82,11 +82,6 @@ namespace menoh_impl {
                         " valid value: " + valid_value) {}
     };
 
-    std::unordered_map<std::string, std::vector<int>> make_output_dims_table(
-      menoh_impl::model_data const& model_data,
-      std::vector<std::pair<std::string, std::vector<int>>> const&
-        input_dims_table);
-
 } // namespace menoh_impl
 
 #endif // MENOH_GRAPH_HPP
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index ecc035d..3065e9f 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -11,6 +11,7 @@
 #include <menoh/menoh.h>
 
 #include <menoh/array.hpp>
+#include <menoh/attribute_completion_and_shape_inference.hpp>
 #include <menoh/exception.hpp>
 #include <menoh/model_core.hpp>
 #include <menoh/model_core_factory.hpp>
@@ -327,32 +328,10 @@ menoh_error_code menoh_build_variable_profile_table(
           input_profile_table(builder->input_name_and_profile_list.begin(),
                               builder->input_name_and_profile_list.end());
 
-        // FIXME BEGIN dtype inference is also needed
-        // currently dtype is fixed to float
-        std::vector<std::pair<std::string, std::vector<int>>>
-          input_name_and_dims_pair_list;
-        std::transform(builder->input_name_and_profile_list.begin(),
-                       builder->input_name_and_profile_list.end(),
-                       std::back_inserter(input_name_and_dims_pair_list),
-                       [](auto const& p) {
-                           return std::make_pair(p.first, p.second.dims());
-                       });
-        auto output_dims_table = menoh_impl::make_output_dims_table(
-          model_data->model_data, input_name_and_dims_pair_list);
+        auto output_profile_table =
+          menoh_impl::complete_attribute_and_inference_shape(
+            model_data->model_data, input_profile_table);
 
-        std::unordered_map<std::string, menoh_impl::array_profile>
-          output_profile_table;
-        std::transform(
-          output_dims_table.begin(), output_dims_table.end(),
-          std::inserter(output_profile_table, output_profile_table.end()),
-          [](auto const& p) {
-              // here fixed to float
-              return std::make_pair(
-                p.first, menoh_impl::array_profile(
-                           static_cast<menoh_impl::dtype_t>(menoh_dtype_float),
-                           p.second));
-          });
-        // FIXME END
         *dst_handle =
           std::make_unique<menoh_variable_profile_table>(
             menoh_variable_profile_table{std::move(input_profile_table),

From 2af69e641efde2a24b7f62ac0c9c56ae060797ed Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 26 Sep 2018 21:02:28 +0900
Subject: [PATCH 155/321] remove global_max/average_pool test

---
 ...tribute_completion_and_shape_inference.hpp | 887 ++++++++++++++++++
 ...bute_completion_and_shape_inference_hpp.py |   0
 test/operator.cpp                             |   4 +-
 3 files changed, 889 insertions(+), 2 deletions(-)
 create mode 100644 menoh/attribute_completion_and_shape_inference.hpp
 rename gen_attribute_completion_and_shape_inference_hpp.py => scripts/gen_attribute_completion_and_shape_inference_hpp.py (100%)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
new file mode 100644
index 0000000..1a6db14
--- /dev/null
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -0,0 +1,887 @@
+
+#ifndef MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+#define MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+
+#include <iostream>
+
+#include <algorithm>
+#include <cassert>
+#include <string>
+#include <unordered_map>
+
+#include <menoh/array.hpp>
+#include <menoh/model_data.hpp>
+
+namespace menoh_impl {
+    inline auto complete_attribute_and_inference_shape(
+            model_data& model_data,
+            std::unordered_map<std::string, array_profile> const&
+                input_profile_table) {
+        using ints = std::vector<int>;
+        std::unordered_map<std::string, array_profile> variable_profile_table(
+            input_profile_table.begin(), input_profile_table.end());
+        std::transform(
+            model_data.parameter_name_and_array_list.begin(),
+            model_data.parameter_name_and_array_list.end(),
+            std::inserter(variable_profile_table,
+                          variable_profile_table.end()),
+            [](auto const& p){
+                return std::make_pair(
+                    p.first,
+                    array_profile(p.second.dtype(), p.second.dims())); });
+        auto profile_of = [&variable_profile_table](std::string const& name){
+            assert(variable_profile_table.find(name) ==
+                variable_profile_table.end());
+            return variable_profile_table.at(name);
+        };
+        auto dims_of = [&variable_profile_table, profile_of](
+            std::string const& name){
+                return profile_of(name).dims();
+        };
+        auto dtype_of = [&variable_profile_table, profile_of](
+            std::string const& name){
+                return profile_of(name).dtype();
+        };
+        auto ndims_of = [&dims_of](std::string const& parameter_name) {
+            return dims_of(parameter_name).size();
+        };
+        auto add_variable_to_table = [&variable_profile_table](
+            std::string const& name,
+            dtype_t dtype, ints const& dims){
+                variable_profile_table.emplace(
+                    name, array_profile(dtype, dims));
+            };
+
+        auto graph = make_graph(model_data.node_list); // FIXME reorder nodes
+        model_data.node_list = graph.node_list();
+        for(auto& node : model_data.node_list) {
+            auto input = [&node](int i){
+                return node.input_name_list.at(i);
+            };
+            auto output = [&node](int i){
+                return node.output_name_list.at(i);
+            };
+            
+if(node.op_type == "Abs") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Add") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "AveragePool") {
+    
+assert(2 <= ndims_of(input(0)));
+
+    
+{
+    auto found = node.attribute_table.find("count_include_pad");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "count_include_pad", 0);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("kernel_shape");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: kernel_shape");
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("pads");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "pads", ints(2*(ndims_of(input(0))-2), 0));
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("strides");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "strides", ints(ndims_of(input(0))-2, 1));
+
+    }
+}
+
+    
+    {
+        
+auto count_include_pad = get<int>(node.attribute_table.at("count_include_pad"));
+
+
+auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+
+
+auto pads = get<ints>(node.attribute_table.at("pads"));
+
+
+auto strides = get<ints>(node.attribute_table.at("strides"));
+
+        
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(0)).at(1),
+        kernel_shape, strides, pads));
+
+    }
+}
+else
+
+
+if(node.op_type == "BatchNorm") {
+    
+    
+{
+    auto found = node.attribute_table.find("epsilon");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "epsilon", 1.e-05f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("momentum");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "momentum", 0.9f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("spatial");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "spatial", 1);
+
+    }
+}
+
+    
+    {
+        
+auto epsilon = get<float>(node.attribute_table.at("epsilon"));
+
+
+auto momentum = get<float>(node.attribute_table.at("momentum"));
+
+
+auto spatial = get<int>(node.attribute_table.at("spatial"));
+
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Concat") {
+    
+    
+{
+    auto found = node.attribute_table.find("axis");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: axis");
+
+    }
+}
+
+    
+    {
+        
+auto axis = get<int>(node.attribute_table.at("axis"));
+
+        
+auto output_dims = dims_of(input(0));
+for(int i = 1; i < node.input_name_list.size(); ++i) {
+    // TODO dim check
+    output_dims.at(axis) += dims_of(input(i)).at(axis);
+}
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+
+    }
+}
+else
+
+
+if(node.op_type == "Conv") {
+    
+auto kernel_ndims = ndims_of(input(1))-2;
+auto weights_shape = dims_of(input(1));
+auto kernel_shape = ints(weights_shape.begin()+2, weights_shape.end());
+
+    
+{
+    auto found = node.attribute_table.find("dilations");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "dilations", ints(kernel_ndims, 1));
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("group");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "group", 1);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("kernel_shape");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "kernel_shape", kernel_shape);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("pads");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "pads", ints(kernel_ndims*2, 0));
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("strides");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "strides", ints(kernel_ndims, 1));
+
+    }
+}
+
+    
+    {
+        
+auto dilations = get<ints>(node.attribute_table.at("dilations"));
+
+
+auto group = get<int>(node.attribute_table.at("group"));
+
+
+auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+
+
+auto pads = get<ints>(node.attribute_table.at("pads"));
+
+
+auto strides = get<ints>(node.attribute_table.at("strides"));
+
+        
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(1)).at(0),
+        kernel_shape, strides, pads));
+
+    }
+}
+else
+
+
+if(node.op_type == "ConvTranspose") {
+    
+auto kernel_ndims = ndims_of(input(1))-2;
+auto weights_shape = dims_of(input(1));
+auto kernel_shape = ints(weights_shape.begin()+2, weights_shape.end());
+
+    
+{
+    auto found = node.attribute_table.find("dilations");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: dilations");
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("group");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "group", 1);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("kernel_shape");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "kernel_shape", kernel_shape);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("output_padding");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: output_padding");
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("strides");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "strides", ints(kernel_ndims, 1));
+
+    }
+}
+
+    
+{
+    auto found = node.attribute_table.find("output_shape");
+    assert(!(found == node.attribute_table.end() &&
+       node.attribute_table.find("pads") == node.attribute_table.end()));
+    if(found != node.attribute_table.end()) {
+        auto output_shape = get<ints>(found->second);
+        /* [dim0_begin, dim1_begin, ... , dim0_end, dim1_end, ..., ...] */
+        ints pads(kernel_ndims*2, 0);
+        auto output_padding =
+            get<ints>(node.attribute_table.at("output_padding"));
+        auto strides = get<ints>(node.attribute_table.at("strides"));
+        auto input_profile = input_profile_table.at(input(0));
+        ints input_size(input_profile.dims().begin()+2,
+                        input_profile.dims().end());
+
+        for(int i = 0; i < kernel_ndims; ++i) {
+            auto total_padding = strides[i] * (input_size[i] - 1)
+                + output_padding[i] + kernel_shape[i] - output_shape[i];
+            pads[i] = total_padding - (total_padding/2);
+            pads[i+kernel_ndims] = (total_padding/2);
+        }
+
+        node.attribute_table["pads"] = pads;
+    }
+}
+
+    {
+        
+auto dilations = get<ints>(node.attribute_table.at("dilations"));
+
+
+auto group = get<int>(node.attribute_table.at("group"));
+
+
+auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+
+
+auto output_padding = get<ints>(node.attribute_table.at("output_padding"));
+
+
+auto strides = get<ints>(node.attribute_table.at("strides"));
+
+        
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims_for_conv_transpose(
+        dims_of(input(0)), dims_of(input(1)).at(0),
+        kernel_shape, strides, get<ints>(node.attribute_table.at("pads"))));
+
+    }
+}
+else
+
+
+if(node.op_type == "Elu") {
+    
+    
+{
+    auto found = node.attribute_table.find("alpha");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "alpha", 1.f);
+
+    }
+}
+
+    
+    {
+        
+auto alpha = get<float>(node.attribute_table.at("alpha"));
+
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "FC") {
+    
+    
+    
+    {
+        
+        
+auto output_dims = ints({dims_of(input(0)).at(0), dims_of(input(1)).at(0)});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
+
+    }
+}
+else
+
+
+if(node.op_type == "Gemm") {
+    
+    
+{
+    auto found = node.attribute_table.find("alpha");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "alpha", 1.f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("beta");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "beta", 1.f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("transA");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "transA", 0);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("transB");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "transB", 0);
+
+    }
+}
+
+    
+    {
+        
+auto alpha = get<float>(node.attribute_table.at("alpha"));
+
+
+auto beta = get<float>(node.attribute_table.at("beta"));
+
+
+auto transA = get<int>(node.attribute_table.at("transA"));
+
+
+auto transB = get<int>(node.attribute_table.at("transB"));
+
+        
+auto a_dims = dims_of(input(0));
+assert(a_dims.size() == 2);
+if(transA) {
+    std::swap(a_dims.at(0), a_dims.at(1));
+}
+
+auto b_dims = dims_of(input(1));
+assert(b_dims.size() == 2);
+if(transB) {
+    std::swap(b_dims.at(0), b_dims.at(1));
+}
+
+auto output_dims = ints({a_dims.at(0), b_dims.at(1)});
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+
+    }
+}
+else
+
+
+if(node.op_type == "LeakyRelu") {
+    
+    
+{
+    auto found = node.attribute_table.find("alpha");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "alpha", 0.01f);
+
+    }
+}
+
+    
+    {
+        
+auto alpha = get<float>(node.attribute_table.at("alpha"));
+
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "LRN") {
+    
+    
+{
+    auto found = node.attribute_table.find("alpha");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "alpha", 0.0001f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("beta");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "beta", 0.75f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("bias");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "bias", 1.0f);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("size");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: size");
+
+    }
+}
+
+    
+    {
+        
+auto alpha = get<float>(node.attribute_table.at("alpha"));
+
+
+auto beta = get<float>(node.attribute_table.at("beta"));
+
+
+auto bias = get<float>(node.attribute_table.at("bias"));
+
+
+auto size = get<float>(node.attribute_table.at("size"));
+
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "MaxPool") {
+    
+    
+{
+    auto found = node.attribute_table.find("kernel_shape");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: kernel_shape");
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("pads");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "pads", ints(2*(ndims_of(input(0))-2), 0));
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("storage_order");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "storage_order", 0);
+
+    }
+}
+
+
+{
+    auto found = node.attribute_table.find("strides");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "strides", ints(ndims_of(input(0))-2, 1));
+
+    }
+}
+
+    
+    {
+        
+auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+
+
+auto pads = get<ints>(node.attribute_table.at("pads"));
+
+
+auto storage_order = get<int>(node.attribute_table.at("storage_order"));
+
+
+auto strides = get<ints>(node.attribute_table.at("strides"));
+
+        
+add_variable_to_table(output(0), dtype_of(input(0)),
+    calc_2d_output_dims(
+        dims_of(input(0)), dims_of(input(0)).at(1),
+        kernel_shape, strides, pads));
+
+    }
+}
+else
+
+
+if(node.op_type == "Relu") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Softmax") {
+    
+    
+{
+    auto found = node.attribute_table.find("axis");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "axis", 1);
+
+    }
+}
+
+    
+    {
+        
+auto axis = get<int>(node.attribute_table.at("axis"));
+
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Sum") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Sqrt") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Tanh") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
+if(node.op_type == "Transpose") {
+    
+ints perm(ndims_of(input(0)));
+for(int i = 0; i < perm.size(); ++i) {{
+    perm.at(i) = perm.size()-i-1;
+}}
+
+    
+{
+    auto found = node.attribute_table.find("perm");
+    if(found == node.attribute_table.end()) {
+        
+node.attribute_table.emplace(
+    "perm", perm);
+
+    }
+}
+
+    
+    {
+        
+auto perm = get<ints>(node.attribute_table.at("perm"));
+
+        
+auto input_dims = dims_of(input(0));
+ints output_dims(input_dims.size());
+for(int i = 0; i < input_dims.size(); ++i) {
+    output_dims.at(i) = input_dims.at(perm.at(i));
+}
+add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+
+    }
+}
+else
+
+            
+{
+    throw unsupported_operator(node.op_type);
+}
+
+        }
+        return variable_profile_table;
+    }
+} // namespace menoh_impl
+
+#endif // MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
+
diff --git a/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
similarity index 100%
rename from gen_attribute_completion_and_shape_inference_hpp.py
rename to scripts/gen_attribute_completion_and_shape_inference_hpp.py
diff --git a/test/operator.cpp b/test/operator.cpp
index 53893ed..bef8ee3 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -199,8 +199,8 @@ namespace {
     // TEST_OP(mkldnn, test_conv_with_strides_padding, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_convtranspose, eps); // not found
     // TEST_OP(mkldnn, test_gemm_nobroadcast, eps);
-    TEST_OP(mkldnn, test_globalaveragepool, eps);
-    TEST_OP(mkldnn, test_globalmaxpool, eps);
+    //TEST_OP(mkldnn, test_globalaveragepool, eps);
+    //TEST_OP(mkldnn, test_globalmaxpool, eps);
     TEST_OP(mkldnn, test_maxpool_2d_default, eps);
     TEST_OP_SQUASH_DIMS(mkldnn, test_softmax_axis_1, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_sum_one_input, eps);

From a6cff7e44b5be6bf55ad9186f1dff46b0ef28b34 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 26 Sep 2018 21:54:27 +0900
Subject: [PATCH 156/321] add model_data_completion test

---
 test/model_data_completion.cpp | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)
 create mode 100644 test/model_data_completion.cpp

diff --git a/test/model_data_completion.cpp b/test/model_data_completion.cpp
new file mode 100644
index 0000000..f02a540
--- /dev/null
+++ b/test/model_data_completion.cpp
@@ -0,0 +1,29 @@
+#include <gtest/gtest.h>
+
+#include <menoh/model_completion.hpp>
+#include <menoh/model_data.hpp>
+
+#include "common.hpp"
+namespace {
+
+    class ModelDataCompletionTest : public ::testing::Test {};
+
+    TEST_F(ModelDataCompletionTest, completion) {
+        menoh_impl::model_data model_data;
+        model_data.node_list.push_back(
+          menoh_impl::node{"Conv", {"x", "w"}, {"y"}, {}});
+        std::unordered_map<std::string, menoh_impl::array_profile>
+          input_profile_table;
+        input_profile_table.emplace(
+          "w",
+          menoh_impl::array_profile(menoh_impl::dtype_t::float_, {1, 1, 3, 3}));
+        menoh_impl::complete_model_data(model_data, input_profile_table);
+        auto const& node = model_data.node_list.at(0);
+        auto found = node.attribute_table.find("kernel_shape");
+        ASSERT_NE(found, node.attribute_table.end());
+        menoh_impl::assert_eq_list(
+          menoh_impl::get<std::vector<int>>(found->second),
+          std::vector<int>({3, 3}));
+    }
+
+} // namespace

From 1384e4199c0bb707dcf5dbc80e14322b0acfc054 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 26 Sep 2018 23:25:57 +0900
Subject: [PATCH 157/321] add notification

---
 menoh/attribute_completion_and_shape_inference.hpp |  7 ++++---
 ...attribute_completion_and_shape_inference_hpp.py | 14 ++++++++------
 2 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 1a6db14..9c98fe8 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -1,9 +1,10 @@
 
 #ifndef MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
 #define MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
-
-#include <iostream>
-
+/*
+ * This file is generated by gen_attribute_completion_and_shape_inference_hpp.py
+ * Do NOT modify this file directly
+ */
 #include <algorithm>
 #include <cassert>
 #include <string>
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index dc46b12..8d7b9e3 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -1,3 +1,4 @@
+import os
 
 
 def make_completion_code(op_name,
@@ -67,9 +68,10 @@ def main():
     template = """
 #ifndef MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
 #define MENOH_ATTRIBUTE_COMPLETION_AND_SHAPE_INFERENCE_HPP
-
-#include <iostream>
-
+/*
+ * This file is generated by {script_name}
+ * Do NOT modify this file directly
+ */
 #include <algorithm>
 #include <cassert>
 #include <string>
@@ -144,7 +146,7 @@ def main():
             ("count_include_pad", "int", "0"),
             ("kernel_shape", "ints", None),
             ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
-            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"),  # WORKAROUND: None is correct
+            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"),  # WORKAROUND: None is correct # NOQA
         ], '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims(
@@ -281,7 +283,7 @@ def main():
             ("kernel_shape", "ints", None),
             ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
             ("storage_order", "int", "0"),
-            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"), # WORKAROUND: None is correct
+            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"), # WORKAROUND: None is correct # NOQA
         ], '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims(
@@ -309,7 +311,7 @@ def main():
     perm.at(i) = perm.size()-i-1;
 }}
 """))
-    print(template.format(code="\n".join(code_list), unsupported_operator='''
+    print(template.format(script_name=os.path.basename(__file__), code="\n".join(code_list), unsupported_operator='''
 {
     throw unsupported_operator(node.op_type);
 }

From 6b7e0dce2cdbd9e0e987575b088eb67b162ab92e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 19 Sep 2018 15:37:23 +0900
Subject: [PATCH 158/321] simplify generic backend operator

---
 .../backend/generic/generic_context.cpp       | 33 +++++++++++----
 .../backend/generic/generic_context.hpp       |  9 ++--
 .../backend/generic/operator/relu.hpp         | 41 +++++--------------
 .../model_core.cpp                            |  2 +-
 4 files changed, 42 insertions(+), 43 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 0488321..2c3f964 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -103,23 +103,40 @@ namespace menoh_impl {
                             assert(is_found_from_other_context);
                         } while(false);
                     }
+                    std::vector<array> output_list;
+                    for(auto const& output_name : node.output_name_list) {
+                        auto found = required_output_table.find(output_name);
+                        if(found == required_output_table.end()) {
+                            // allocate new array by using profile
+                            output_list.push_back(
+                              array(output_profile_table.at(output_name)));
+                        } else {
+                            // use already allocated array
+                            output_list.push_back(found->second);
+                        }
+                    }
+
                     procedure op_proc;
-                    std::vector<std::pair<std::string, array>> new_outputs;
                     try {
                         auto factory =
                           procedure_factory_table_.at(node.op_type);
-                        std::tie(op_proc, new_outputs) =
-                          factory.operator()(current_index, node_list,
-                                             input_list, required_output_table);
-                    } catch(...) { break; }
+                        op_proc =
+                          factory.operator()(node, input_list, output_list);
+                    } catch(std::exception const& e) {
+                        *logger << e.what() << std::endl;
+                        break;
+                    }
                     new_op_proc_list.push_back(op_proc);
                     procedure_list.insert(
                       procedure_list.end(),
                       std::make_move_iterator(new_copy_procedure_list.begin()),
                       std::make_move_iterator(new_copy_procedure_list.end()));
-                    variable_table_.insert(
-                      std::make_move_iterator(new_outputs.begin()),
-                      std::make_move_iterator(new_outputs.end()));
+
+                    assert(node.output_name_list.size() == output_list.size());
+                    for(int i = 0; i < node.output_name_list.size(); ++i) {
+                        variable_table_.emplace(node.output_name_list.at(i),
+                                                output_list.at(i));
+                    }
                 }
 
                 // when no nodes are processed
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
index 251e918..cdfda3f 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
@@ -45,10 +45,11 @@ namespace menoh_impl {
                     return variable_table_.at(name);
                 }
 
-                using procedure_factory = std::function<std::tuple<
-                  procedure, std::vector<std::pair<std::string, array>>>(
-                  int, std::vector<node> const&, std::vector<array> const&,
-                  std::unordered_map<std::string, array> const&)>;
+                using procedure_factory = std::function<procedure(
+                  node const&, // node
+                  std::vector<array> const&, // input list
+                  std::vector<array> const&  // output list
+                  )>;
                 optional<std::function<void()>>
                 try_to_get_input_from_common_table(
                   std::string const& input_name,
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
index 092f59e..98e258a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
@@ -1,46 +1,27 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
 
+#include <menoh/array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace generic_backend {
-            inline std::tuple<procedure,
-                              std::vector<std::pair<std::string, array>>>
-            make_relu(int node_index, std::vector<node> const& node_list,
-                      std::vector<array> const& input_list,
-                      std::unordered_map<std::string, array> const&
-                        required_output_table) {
+            inline procedure make_relu(node const& node,
+                                       std::vector<array> const& input_list,
+                                       std::vector<array> const& output_list) {
                 assert(input_list.size() == 1);
-                auto const& node = node_list.at(node_index);
+                assert(output_list.size() == 1);
 
-                auto const& x_arr = input_list.at(0);
-
-                auto found =
-                  required_output_table.find(node.output_name_list.at(0));
-                optional<array> output_opt;
-                if(found == required_output_table.end()) {
-                    output_opt = array(dtype_t::float_,
-                                       x_arr.dims()); // TODO check inplace-able
-                } else {
-                    output_opt =
-                      found->second; // output is required so not inplace-able
-                }
-
-                auto procedure = [x_arr, output = *output_opt]() {
-                    for(decltype(total_size(x_arr)) i = 0;
-                        i < total_size(x_arr); ++i) {
-                        fat(output, i) = std::max(fat(x_arr, i), 0.f);
+                auto procedure = [input = input_list.at(0),
+                                  output = output_list.at(0)]() {
+                    for(decltype(total_size(input)) i = 0;
+                        i < total_size(input); ++i) {
+                        fat(output, i) = std::max(fat(input, i), 0.f);
                     }
                 };
 
-                std::vector<std::pair<std::string, array>> outputs;
-                if(found == required_output_table.end()) {
-                    outputs.push_back(std::pair<std::string, array>(
-                      node.output_name_list.at(0), *output_opt));
-                }
-                return std::make_tuple(procedure, outputs);
+                return procedure;
             }
 
         } // namespace generic_backend
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index 273d607..027cfed 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -105,7 +105,7 @@ namespace menoh_impl {
                 }
                 // if any context can not process the node
                 if(!is_found) {
-                    *logger_ << "failed to interpret"
+                    *logger_ << "failed to interpret: no contexts can interpret"
                              << graph.node_list().at(current_index).op_type
                              << "with all context";
                     throw unsupported_operator(node.op_type);

From 465f1f1c44a727cefe3eda7893c1012b72e8b7cb Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 14:29:42 +0900
Subject: [PATCH 159/321] fix type int -> int32_t

---
 include/menoh/menoh.h | 2 +-
 menoh/menoh.cpp       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 5ec3a8a..f89f5e1 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -158,7 +158,7 @@ menoh_error_code MENOH_API menoh_model_data_add_attribute_float_to_current_node(
  */
 menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
-  const int* value);
+  const int32_t* value);
 /*! \brief Add a new float array attribute to latest added node in model_data
  *
  * \note Duplication of attribute_name is not allowed and it throws error.
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index ecc035d..9d832f0 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -188,7 +188,7 @@ menoh_error_code menoh_model_data_add_attribute_array_to_current_node(
 
 menoh_error_code MENOH_API menoh_model_data_add_attribute_ints_to_current_node(
   menoh_model_data_handle model_data, const char* attribute_name, int32_t size,
-  const int* value) {
+  const int32_t* value) {
     return menoh_model_data_add_attribute_array_to_current_node(
       model_data, attribute_name, size, value);
 }

From 854cbef2b571ce6ae2bc9d4526c30c202daf6de6 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 14:46:44 +0900
Subject: [PATCH 160/321] update onnx version

---
 external/onnx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/external/onnx b/external/onnx
index c7b6005..bae6333 160000
--- a/external/onnx
+++ b/external/onnx
@@ -1 +1 @@
-Subproject commit c7b60050ad6ae963bf2cc1d0eb3c32b07eb7eeed
+Subproject commit bae6333e149a59a3faa9c4d9c44974373dcf5256

From 0a4fdecc44e0f810e916acaae7b134de391c246d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 15:11:37 +0900
Subject: [PATCH 161/321] update onnx submodule and suported ONNX version

---
 include/menoh/menoh.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 5ec3a8a..a4629ba 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -11,7 +11,7 @@
 #define MENOH_API
 #endif
 
-#define MENOH_SUPPORTED_ONNX_OPSET_VERSION 7
+#define MENOH_SUPPORTED_ONNX_OPSET_VERSION 8
 
 #ifndef MENOH_ERROR_MESSAGE_MAX_LENGTH
 #define MENOH_ERROR_MESSAGE_MAX_LENGTH 1024

From 1fb970231acc5125660c00278968adcb9c237cef Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 15:34:12 +0900
Subject: [PATCH 162/321] fix error message

---
 menoh/mkldnn_with_generic_fallback/model_core.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index 027cfed..ad9b019 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -105,9 +105,9 @@ namespace menoh_impl {
                 }
                 // if any context can not process the node
                 if(!is_found) {
-                    *logger_ << "failed to interpret: no contexts can interpret"
-                             << graph.node_list().at(current_index).op_type
-                             << "with all context";
+                    *logger_
+                      << "failed to interpret: no contexts can interpret '"
+                      << node.op_type << "'";
                     throw unsupported_operator(node.op_type);
                 }
             }

From 3722edcc03e952487da9fa7ceb666ce45ce79412 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 17:00:31 +0900
Subject: [PATCH 163/321] rename complete_attribute_and_inference_shape ->
 complete_attribute_and_infer_shape

---
 menoh/attribute_completion_and_shape_inference.hpp          | 2 +-
 menoh/menoh.cpp                                             | 2 +-
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 9c98fe8..d7b07d9 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -14,7 +14,7 @@
 #include <menoh/model_data.hpp>
 
 namespace menoh_impl {
-    inline auto complete_attribute_and_inference_shape(
+    inline auto complete_attribute_and_infer_shape(
             model_data& model_data,
             std::unordered_map<std::string, array_profile> const&
                 input_profile_table) {
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 3065e9f..5e3bdb0 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -329,7 +329,7 @@ menoh_error_code menoh_build_variable_profile_table(
                               builder->input_name_and_profile_list.end());
 
         auto output_profile_table =
-          menoh_impl::complete_attribute_and_inference_shape(
+          menoh_impl::complete_attribute_and_infer_shape(
             model_data->model_data, input_profile_table);
 
         *dst_handle =
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 8d7b9e3..e0ddf31 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -81,7 +81,7 @@ def main():
 #include <menoh/model_data.hpp>
 
 namespace menoh_impl {{
-    inline auto complete_attribute_and_inference_shape(
+    inline auto complete_attribute_and_infer_shape(
             model_data& model_data,
             std::unordered_map<std::string, array_profile> const&
                 input_profile_table) {{

From 8c3b685cfe8f7d6a859debe047477a70f8aef428 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 28 Sep 2018 21:43:02 +0900
Subject: [PATCH 164/321] add check code if MaxPool has multiple outputs

when it has multiple outputs, mkldnn backend throws unsupported_operator error
---
 menoh/mkldnn/operator/pool.cpp | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/menoh/mkldnn/operator/pool.cpp b/menoh/mkldnn/operator/pool.cpp
index 18f7fcf..8b6e8b3 100644
--- a/menoh/mkldnn/operator/pool.cpp
+++ b/menoh/mkldnn/operator/pool.cpp
@@ -9,6 +9,8 @@
 #include <menoh/mkldnn/operator/common.hpp>
 #include <menoh/mkldnn/utility.hpp>
 
+#include <menoh/graph.hpp> // for unsupported_operator error
+
 namespace menoh_impl {
     namespace mkldnn_backend {
 
@@ -94,6 +96,9 @@ namespace menoh_impl {
             variable_memory_table,
           std::unordered_map<std::string, array> const& required_output_table,
           mkldnn::engine const& engine) {
+            if(node.output_name_list.size() != 1) {
+                throw unsupported_operator("MaxPool issuing multiple outputs");
+            }
             return make_pool_primitive<mkldnn::pooling_max>(
               node, variable_memory_table, required_output_table, engine);
         }

From 08289fcf5b99e470e11eb09669ec13a57a4f811c Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 1 Oct 2018 10:29:14 +0900
Subject: [PATCH 165/321] add cross building support for protobuf

---
 scripts/build-boost.sh    | 120 ++++++++++++++++++++++++++++++++++++++
 scripts/build-menoh.sh    |   4 +-
 scripts/build-protobuf.sh |  18 +++++-
 scripts/install-boost.sh  |  35 +++++++++++
 4 files changed, 174 insertions(+), 3 deletions(-)
 create mode 100644 scripts/build-boost.sh
 create mode 100644 scripts/install-boost.sh

diff --git a/scripts/build-boost.sh b/scripts/build-boost.sh
new file mode 100644
index 0000000..183247f
--- /dev/null
+++ b/scripts/build-boost.sh
@@ -0,0 +1,120 @@
+#!/bin/bash -e
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --version)
+            readonly ARG_VERSION="$2"
+            shift 2
+            ;;
+        --download-dir)
+            readonly ARG_DOWNLOAD_DIR="$2"
+            shift 2
+            ;;
+        --extract-dir)
+            readonly ARG_EXTRACT_DIR="$2"
+            shift 2
+            ;;
+        --build-dir)
+            readonly ARG_BUILD_DIR="$2"
+            shift 2
+            ;;
+        --stage-dir)
+            readonly ARG_STAGE_DIR="$2"
+            shift 2
+            ;;
+        --install-dir)
+            readonly ARG_INSTALL_DIR="$2"
+            shift 2
+            ;;
+        --toolset)
+            readonly ARG_TOOLSET="$2"
+            shift 2
+            ;;
+        --cxx)
+            readonly ARG_CXX_CMD="$2"
+            shift 2
+            ;;
+        --parallel)
+            readonly ARG_PARALLEL="$2"
+            shift 2
+            ;;
+        -*)
+            echo Unknown option \"$1\" 1>&2
+            exit
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
+test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
+
+# options that have default value
+test -n "${ARG_VERSION}" || readonly ARG_VERSION=1.64.0
+
+readonly LIBRARY_NAME=boost_$(echo ${ARG_VERSION} | sed -e 's/\./_/g') # e.g. boost_1_64_0
+readonly SOURCE_DIR="${ARG_EXTRACT_DIR}/${LIBRARY_NAME}"
+
+test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}/build"
+test -n "${ARG_STAGE_DIR}" || readonly ARG_STAGE_DIR="${SOURCE_DIR}/stage"
+test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
+test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
+
+# options for cross compiling
+if [ -n "${ARG_TOOLSET}" ]; then # e.g. gcc-arm
+    # requires a location of g++ command
+    test -n "${ARG_CXX_CMD}" || { echo "--cxx is not specified" 1>&2; exit 1; }
+
+    readonly USER_CONFIG_JAM="using $(echo ${ARG_TOOLSET} | sed -e 's/-/ : /') : ${ARG_CXX_CMD} ;"
+    readonly OPT_TOOLSET=toolset=${ARG_TOOLSET}
+fi
+
+# download (if it isn't cached)
+if [ ! -e "${SOURCE_DIR}/INSTALL" ]; then
+    echo -e "\e[33;1mDownloading libboost\e[0m"
+
+    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p "${ARG_DOWNLOAD_DIR}"
+
+    cd "${ARG_DOWNLOAD_DIR}"
+    if [ ! -e "${LIBRARY_NAME}.tar.gz" ]; then
+        download_dir="https://dl.bintray.com/boostorg/release/${ARG_VERSION}/source/${LIBRARY_NAME}.tar.gz"
+        curl -LO ${download_dir} # wget doesn't work for bintray with 403 errpr
+    fi
+    tar -zxf ${LIBRARY_NAME}.tar.gz -C "${ARG_EXTRACT_DIR}"
+
+    echo -e "\e[32;1mlibboost was successfully downloaded.\e[0m"
+else
+    echo -e "\e[32;1mlibboost has been downloaded.\e[0m"
+fi
+
+# build (if it isn't cached)
+if [ ! -e "${ARG_STAGE_DIR}/lib/libboost_system.a" ]; then
+    echo -e "\e[33;1mBuilding libprotobuf\e[0m"
+
+    cd "${SOURCE_DIR}"
+
+    # bootstrap
+    ./bootstrap.sh --prefix="${ARG_INSTALL_DIR}"
+
+    # configure options
+    if [ -n "${USER_CONFIG_JAM}" ]; then
+        echo "${USER_CONFIG_JAM}" > ${SOURCE_DIR}/user_config.jam
+        readonly OPT_USER_CONFIG_JAM=--user-config=${SOURCE_DIR}/user_config.jam
+    fi
+    echo "-j${ARG_PARALLEL} ${OPT_TOOLSET} ${OPT_USER_CONFIG_JAM} link=static cflags=-fPIC cxxflags=-fPIC --with-filesystem --with-test --with-log --with-program_options --build-dir=${ARG_BUILD_DIR} --stage-dir=${ARG_STAGE_DIR}" > b2_opts.txt
+
+    # run a build
+    ./b2 stage $(cat b2_opts.txt)
+
+    echo -e "\e[32;1mlibboost was successfully built.\e[0m"
+else
+    echo -e "\e[32;1mlibboost has been built.\e[0m"
+fi
diff --git a/scripts/build-menoh.sh b/scripts/build-menoh.sh
index 6f7f80b..38c4fed 100755
--- a/scripts/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -59,8 +59,8 @@ test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${ARG_SOURCE_DIR}/build"
 test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 
 if [ -n "${ARG_MKLDNN_DIR}" ]; then
-    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
-    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
+    readonly OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
+    readonly OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 
 test -n "${ARG_LINK_STATIC_LIBGCC}" || readonly ARG_LINK_STATIC_LIBGCC='OFF'
diff --git a/scripts/build-protobuf.sh b/scripts/build-protobuf.sh
index f694b8b..f1fdb34 100755
--- a/scripts/build-protobuf.sh
+++ b/scripts/build-protobuf.sh
@@ -27,6 +27,14 @@ while [[ $# != 0 ]]; do
             readonly ARG_INSTALL_DIR="$2"
             shift 2
             ;;
+        --host)
+            readonly ARG_HOST="$2"
+            shift 2
+            ;;
+        --with-protoc)
+            readonly ARG_WITH_PROTOC="$2"
+            shift 2
+            ;;
         --parallel)
             readonly ARG_PARALLEL="$2"
             shift 2
@@ -55,6 +63,14 @@ test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}"
 test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
 
+# options for cross compiling
+if [ -n "${ARG_HOST}" ]; then
+    readonly OPT_HOST=--host=${ARG_HOST}
+fi
+if [ -n "${ARG_WITH_PROTOC}" ]; then
+    readonly OPT_WITH_PROTOC=--with-protoc=${ARG_WITH_PROTOC}
+fi
+
 # download (if it isn't cached)
 if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
     echo -e "\e[33;1mDownloading libprotobuf\e[0m"
@@ -80,7 +96,7 @@ if [ ! -e "${ARG_BUILD_DIR}/src/libprotobuf.la" ]; then
     [ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
     cd "${ARG_BUILD_DIR}"
-    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS="-g -O2 -fPIC" CXXFLAGS="-g -O2 -fPIC"
+    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS="-g -O2 -fPIC" CXXFLAGS="-g -O2 -fPIC" "${OPT_HOST}" "${OPT_WITH_PROTOC}"
     make -j${ARG_PARALLEL}
 
     echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
diff --git a/scripts/install-boost.sh b/scripts/install-boost.sh
new file mode 100644
index 0000000..fdb3a13
--- /dev/null
+++ b/scripts/install-boost.sh
@@ -0,0 +1,35 @@
+#!/bin/bash -e
+
+# retrieve arguments
+while [[ $# != 0 ]]; do
+    case $1 in
+        --)
+            shift
+            break
+            ;;
+        --source-dir)
+            readonly ARG_SOURCE_DIR="$2"
+            shift 2
+            ;;
+        --dest-dir)
+            readonly ARG_DESTDIR="$2"
+            shift 2
+            ;;
+        -*)
+            echo Unknown option \"$1\" 1>&2
+            exit
+            ;;
+        *)
+            break
+            ;;
+    esac
+done
+
+# validate the arguments
+test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified" 1>&2; exit 1; }
+
+# install (always)
+echo -e "\e[33;1mInstalling libboost\e[0m"
+
+cd "${ARG_SOURCE_DIR}"
+./b2 install $(cat ${ARG_SOURCE_DIR}/b2_opts.txt)

From a28b4f31913243d5226285ec132dd2f738f53ffa Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 1 Oct 2018 17:34:07 +0900
Subject: [PATCH 166/321] switch to use libonnx directly

---
 CMakeLists.txt              | 42 ++++++++++++++++++++--------
 cmake/BuildProtobuf.cmake   | 44 +++++++++++++++++++++++++++++
 cmake/ConfigureMenoh.cmake  |  5 ++--
 cmake/GenerateOnnxSrc.cmake | 25 -----------------
 cmake/SetupProtobuf.cmake   | 56 -------------------------------------
 menoh/CMakeLists.txt        | 14 ----------
 test/CMakeLists.txt         |  8 ++----
 7 files changed, 80 insertions(+), 114 deletions(-)
 create mode 100644 cmake/BuildProtobuf.cmake
 delete mode 100644 cmake/GenerateOnnxSrc.cmake
 delete mode 100644 cmake/SetupProtobuf.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 751fe2f..a000058 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,8 +7,6 @@ set(MENOH_MINOR_VERSION 1)
 set(MENOH_PATCH_VERSION 0)
 
 # Options
-option(BUILD_SHARED_LIBS "Build shared libs" ON)
-
 option(USE_OLD_GLIBCXX_ABI "Generate binaries for the old libstdc++ ABI" OFF)
 option(LINK_STATIC_LIBPROTOBUF "Link static libprotobuf to libmenoh" OFF)
 
@@ -52,11 +50,33 @@ mark_as_advanced(DOWNLOAD_LOCATION)
 # Enable ExternalProject_Add
 include(ExternalProject)
 
-# Setup protobuf
-include(SetupProtobuf)
+# Setup protobuf (MUST run before building ONNX)
+if(LINK_STATIC_LIBPROTOBUF)
+    # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
+    # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
+    # build it by ourselves.
+    if(UNIX OR MINGW)
+        include(BuildProtobuf)
+    else()
+        message(FATAL_ERROR "LINK_STATIC_LIBPROTOBUF is supported only in UNIX-like environments")
+    endif()
+else()
+    include(FindProtobuf)
+    find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
+endif()
+
+include_directories(${PROTOBUF_INCLUDE_DIRS})
+
+# Build libonnx.a
+message(STATUS "Adding external/onnx")
+
+set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
+execute_process(COMMAND git submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
-# Generate source codes from ONNX protobuf schema
-include(GenerateOnnxSrc)
+# TODO: enable the following option when it is ready for migrating to onnx-ml
+#set(ONNX_ML 1)
+add_subdirectory(external/onnx) # Note: BUILD_SHARED_LIBS must be OFF in this place
+include_directories("${ONNX_INCLUDE_DIRS}")
 
 # Setup MKLDNN
 find_package(MKLDNN "0.14")
@@ -67,24 +87,24 @@ endif()
 include_directories("${MKLDNN_INCLUDE_DIR}")
 
 if(${ENABLE_TEST})
-    message(STATUS "# add_subdirectory\(test\)")
+    message(STATUS "Adding test")
     add_subdirectory(test)
 endif()
 
 if(${ENABLE_BENCHMARK})
-    message(STATUS "# add_subdirectory\(benchmark\)")
+    message(STATUS "Adding benchmark")
     add_subdirectory(benchmark)
 endif()
 
 if(${ENABLE_EXAMPLE})
-    message(STATUS "# add_subdirectory\(example\)")
+    message(STATUS "Adding example")
     add_subdirectory(example)
 endif()
 
-message(STATUS "# add_subdirectory\(menoh\)")
+message(STATUS "Adding menoh")
 add_subdirectory(menoh)
 
-message(STATUS "# add_subdirectory\(include\)")
+message(STATUS "Adding include")
 add_subdirectory(include)
 
 if(SHOW_ALL_VARIABLES)
diff --git a/cmake/BuildProtobuf.cmake b/cmake/BuildProtobuf.cmake
new file mode 100644
index 0000000..3822f96
--- /dev/null
+++ b/cmake/BuildProtobuf.cmake
@@ -0,0 +1,44 @@
+set(PROTOBUF_VERSION_STATIC "3.6.1")
+
+set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION_STATIC})
+set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_STATIC}/protobuf-cpp-${PROTOBUF_VERSION_STATIC}.tar.gz")
+set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
+
+# Requires `-fPIC` for linking with a shared library
+set(PROTOBUF_CFLAGS -fPIC)
+set(PROTOBUF_CXXFLAGS -fPIC)
+if(USE_OLD_GLIBCXX_ABI)
+    set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
+endif()
+
+ExternalProject_Add(Protobuf
+    PREFIX ${PROTOBUF_DIR}
+    URL ${PROTOBUF_URL}
+    URL_HASH ${PROTOBUF_HASH}
+    DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
+    BUILD_IN_SOURCE 1
+    CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER} ${PROTOBUF_DIR} ${PROTOBUF_CFLAGS} ${PROTOBUF_CXXFLAGS}
+    BUILD_COMMAND make -j4
+    INSTALL_COMMAND make install
+)
+
+set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
+set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
+
+# Mimic the behavior of `FindProtobuf` module
+# Use the old variable names to ensure backward compatibility
+set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
+set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIR})
+set(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY_STATIC}) # use the static library
+set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
+set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
+set(PROTOBUF_FOUND TRUE)
+
+add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
+# Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
+# not installed during executing `cmake`
+set_target_properties(protobuf::libprotobuf PROPERTIES
+    IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
+add_executable(protobuf::protoc IMPORTED)
+set_target_properties(protobuf::protoc PROPERTIES
+    IMPORTED_LOCATION "${PROTOBUF_PROTOC_EXECUTABLE}")
diff --git a/cmake/ConfigureMenoh.cmake b/cmake/ConfigureMenoh.cmake
index a2f956a..fbbe2f0 100644
--- a/cmake/ConfigureMenoh.cmake
+++ b/cmake/ConfigureMenoh.cmake
@@ -8,6 +8,9 @@ macro(menoh_link_libraries TARGET_NAME SCOPE)
         target_link_libraries(${TARGET_NAME} ${SCOPE} -static-libstdc++)
     endif()
 
+    target_link_libraries(${TARGET_NAME} ${SCOPE} ${PROTOBUF_LIBRARIES})
+    target_link_libraries(${TARGET_NAME} ${SCOPE} onnx)
+
     if(NOT ${SCOPE})
         # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
         # Note: change it to PRIVATE after building mkldnn itself
@@ -15,6 +18,4 @@ macro(menoh_link_libraries TARGET_NAME SCOPE)
     else()
         target_link_libraries(${TARGET_NAME} ${MKLDNN_LIBRARIES})
     endif()
-
-    target_link_libraries(${TARGET_NAME} ${SCOPE} ${PROTOBUF_LIBRARIES})
 endmacro()
diff --git a/cmake/GenerateOnnxSrc.cmake b/cmake/GenerateOnnxSrc.cmake
deleted file mode 100644
index 0c2d8b5..0000000
--- a/cmake/GenerateOnnxSrc.cmake
+++ /dev/null
@@ -1,25 +0,0 @@
-set(ONNX_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/onnx)
-
-if(NOT EXISTS "${ONNX_OUTPUT_DIR}")
-    file(MAKE_DIRECTORY "${ONNX_OUTPUT_DIR}")
-endif()
-
-set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
-execute_process(COMMAND git submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-
-set(ONNX_PROTO_HEADER ${ONNX_OUTPUT_DIR}/onnx/onnx.pb.h)
-set(ONNX_PROTO_SRC ${ONNX_OUTPUT_DIR}/onnx/onnx.pb.cc)
-
-set(ONNX_GENERATED_OUTPUTS ${ONNX_PROTO_HEADER} ${ONNX_PROTO_SRC})
-
-add_custom_target(gen_onnx_outputs DEPENDS ${ONNX_GENERATED_OUTPUTS})
-add_custom_command(
-    OUTPUT ${ONNX_GENERATED_OUTPUTS}
-    COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
-    ARGS -I ${ONNX_SRC_DIR} --cpp_out . ${ONNX_SRC_DIR}/onnx/onnx.proto
-    DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} ${ONNX_SRC_DIR}/onnx/onnx.proto
-    COMMENT "Generating ONNX source files"
-    WORKING_DIRECTORY ${ONNX_OUTPUT_DIR}
-    VERBATIM)
-
-include_directories(${ONNX_OUTPUT_DIR}) # for ONNX_PROTO_HEADER
diff --git a/cmake/SetupProtobuf.cmake b/cmake/SetupProtobuf.cmake
deleted file mode 100644
index 327edf4..0000000
--- a/cmake/SetupProtobuf.cmake
+++ /dev/null
@@ -1,56 +0,0 @@
-set(PROTOBUF_VERSION "2.6.1")
-
-if(LINK_STATIC_LIBPROTOBUF)
-    # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
-    # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
-    # build it by ourselves.
-
-    if(UNIX OR MINGW)
-        set(PROTOBUF_VERSION_STATIC "3.6.1")
-        set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION_STATIC})
-        set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_STATIC}/protobuf-cpp-${PROTOBUF_VERSION_STATIC}.tar.gz")
-        set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
-
-        # Requires `-fPIC` for linking with a shared library
-        set(PROTOBUF_CFLAGS -fPIC)
-        set(PROTOBUF_CXXFLAGS -fPIC)
-        if(USE_OLD_GLIBCXX_ABI)
-            set(PROTOBUF_CXXFLAGS "${PROTOBUF_CXXFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0")
-        endif()
-
-        ExternalProject_Add(Protobuf
-            PREFIX ${PROTOBUF_DIR}
-            URL ${PROTOBUF_URL}
-            URL_HASH ${PROTOBUF_HASH}
-            DOWNLOAD_DIR "${DOWNLOAD_LOCATION}"
-            BUILD_IN_SOURCE 1
-            CONFIGURE_COMMAND bash -ex ${CMAKE_MODULE_PATH}/configure-helper.sh ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER} ${PROTOBUF_DIR} ${PROTOBUF_CFLAGS} ${PROTOBUF_CXXFLAGS}
-            BUILD_COMMAND make -j4
-            INSTALL_COMMAND make install
-        )
-
-        set(PROTOBUF_LIBRARY_STATIC ${PROTOBUF_DIR}/lib/libprotobuf.a)
-        set(PROTOBUF_LIBRARY_SHARED ${PROTOBUF_DIR}/lib/libprotobuf.so)
-
-        # Mimic the behavior of `FindProtobuf` module
-        # Use the old variable names to ensure backward compatibility
-        set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_DIR}/include)
-        set(PROTOBUF_LIBRARY ${PROTOBUF_LIBRARY_STATIC}) # use the static library
-        set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
-        set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
-        set(PROTOBUF_FOUND TRUE)
-
-        add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
-        # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
-        # not installed during executing `cmake`
-        set_target_properties(protobuf::libprotobuf PROPERTIES
-            IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
-    else()
-        message(FATAL_ERROR "LINK_STATIC_LIBPROTOBUF is supported only in UNIX-like environments")
-    endif()
-else()
-    include(FindProtobuf)
-    find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
-endif()
-
-include_directories(${PROTOBUF_INCLUDE_DIR})
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 9bd995b..06e9f3a 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -2,13 +2,6 @@
 option(LINK_STATIC_LIBGCC "Link static libgcc to libmenoh" OFF)
 option(LINK_STATIC_LIBSTDCXX "Link static libstdc++ to libmenoh" OFF)
 
-if(NOT DEFINED ONNX_PROTO_SRC)
-    message(FATAL_ERROR "ONNX_PROTO_SRC is not found")
-endif()
-if(NOT DEFINED ONNX_PROTO_HEADER)
-    message(FATAL_ERROR "ONNX_PROTO_HEADER is not found")
-endif()
-
 # Note: The libraries can be static (.a) or shared (.so)
 if(NOT DEFINED MKLDNN_LIBRARIES)
     message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
@@ -21,10 +14,6 @@ file(GLOB_RECURSE SOURCES "." "*.cpp")
 
 # Create a object library for generating shared library
 add_library(menoh_objlib OBJECT ${SOURCES})
-
-add_dependencies(menoh_objlib gen_onnx_outputs)
-target_sources(menoh_objlib PRIVATE ${ONNX_PROTO_SRC})
-
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
 include(ConfigureMenoh)
@@ -43,9 +32,6 @@ menoh_link_libraries(menoh PRIVATE)
 add_library(menoh_test_target SHARED $<TARGET_OBJECTS:menoh_objlib>)
 menoh_link_libraries(menoh_test_target PRIVATE)
 
-set_source_files_properties(${ONNX_PROTO_SRC} PROPERTIES GENERATED TRUE)
-set_source_files_properties(${ONNX_PROTO_HEADER} PROPERTIES GENERATED TRUE)
-
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
     LIBRARY DESTINATION "lib"
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 04f9813..3085c5a 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,7 +3,7 @@ enable_testing()
 # GTest setup
 set(GTEST_DIR "lib/googletest")
 execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-message(STATUS "# add_subdirectory\(${GTEST_DIR}\)")
+message(STATUS "Adding_${GTEST_DIR}")
 add_subdirectory(${GTEST_DIR})
 
 # filesystem setup
@@ -25,11 +25,7 @@ add_executable(menoh_test
 
 )
 
-if(LINK_STATIC_LIBPROTOBUF)
-  target_link_libraries(menoh_test gtest_main menoh_test_target)
-else()
-  target_link_libraries(menoh_test gtest_main menoh_test_target ${PROTOBUF_LIBRARY})
-endif()
+target_link_libraries(menoh_test gtest_main menoh_test_target onnx_proto)
 
 if(UNIX AND NOT APPLE)
     set_property(

From 8d373ea59300b6d1e329cf3dab4bc74acc9f2e4f Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 1 Oct 2018 18:08:11 +0900
Subject: [PATCH 167/321] add PYTHON_EXECUTABLE option

---
 .travis/init-build-linux.sh | 4 +++-
 .travis/init-build-osx.sh   | 4 +++-
 scripts/build-menoh.sh      | 6 ++++++
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index a5e5f16..ae5f0db 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -78,12 +78,14 @@ function build_menoh() {
         docker_exec_script \
             "${PROJ_DIR}/scripts/build-menoh.sh" \
                 --build-type Release \
-                --source-dir "${PROJ_DIR}"
+                --source-dir "${PROJ_DIR}" \
+                --python-executable python3
     else
         docker_exec_script \
             "${PROJ_DIR}/scripts/build-menoh.sh" \
                 --build-type Release \
                 --source-dir "${PROJ_DIR}" \
+                --python-executable python3 \
                 --link-static-libgcc ON \
                 --link-static-libstdcxx ON \
                 --link-static-libprotobuf ON
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index c1228d8..afe593a 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -17,12 +17,14 @@ function build_menoh() {
     if [ "${LINK_STATIC}" != "true" ]; then
         bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
             --build-type Release \
-            --source-dir "${PROJ_DIR}"
+            --source-dir "${PROJ_DIR}" \
+            --python-executable python
     else
         # Does not set --link-static-libgcc and --link-static-libstdcxx in macOS
         bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
             --build-type Release \
             --source-dir "${PROJ_DIR}" \
+            --python-executable python \
             --link-static-libprotobuf ON
     fi
 }
diff --git a/scripts/build-menoh.sh b/scripts/build-menoh.sh
index 38c4fed..5184c4e 100755
--- a/scripts/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -29,6 +29,10 @@ while [[ $# != 0 ]]; do
             readonly ARG_MKLDNN_DIR="$2"
             shift 2
             ;;
+        --python-executable)
+            ARG_PYTHON_EXECUTABLE="$2"
+            shift 2
+            ;;
         --link-static-libgcc)
             readonly ARG_LINK_STATIC_LIBGCC="$2"
             shift 2
@@ -63,6 +67,7 @@ if [ -n "${ARG_MKLDNN_DIR}" ]; then
     readonly OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 
+test -n "${ARG_PYTHON_EXECUTABLE}" || readonly ARG_PYTHON_EXECUTABLE=python
 test -n "${ARG_LINK_STATIC_LIBGCC}" || readonly ARG_LINK_STATIC_LIBGCC='OFF'
 test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || readonly ARG_LINK_STATIC_LIBSTDCXX='OFF'
 test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || readonly ARG_LINK_STATIC_LIBPROTOBUF='OFF'
@@ -77,6 +82,7 @@ cmake \
     "-DCMAKE_INSTALL_PREFIX=${ARG_INSTALL_DIR}" \
     "${OPT_MKLDNN_INCLUDE_DIR}" \
     "${OPT_MKLDNN_LIBRARY}" \
+    -DPYTHON_EXECUTABLE=${ARG_PYTHON_EXECUTABLE} \
     -DLINK_STATIC_LIBGCC=${ARG_LINK_STATIC_LIBGCC} \
     -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
     -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \

From 2f1dfb216d45cafecf320b38ac99b555fc79771a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 1 Oct 2018 22:12:53 +0900
Subject: [PATCH 168/321] fix bug

---
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index e0ddf31..5913d0a 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -4,8 +4,8 @@
 def make_completion_code(op_name,
                          attribute_list=[],
                          shape_inference_code='''
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 ''',
                          preprocess="",
@@ -98,7 +98,7 @@ def main():
                     p.first,
                     array_profile(p.second.dtype(), p.second.dims())); }});
         auto profile_of = [&variable_profile_table](std::string const& name){{
-            assert(variable_profile_table.find(name) ==
+            assert(variable_profile_table.find(name) !=
                 variable_profile_table.end());
             return variable_profile_table.at(name);
         }};

From 5726b6785d77e42319d51bd72e2239ac63789fae Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 1 Oct 2018 22:13:14 +0900
Subject: [PATCH 169/321] generate attribute_completion_and_shape_inference.hpp

---
 ...tribute_completion_and_shape_inference.hpp | 46 +++++++++----------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index d7b07d9..dc20fd3 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -31,7 +31,7 @@ namespace menoh_impl {
                     p.first,
                     array_profile(p.second.dtype(), p.second.dims())); });
         auto profile_of = [&variable_profile_table](std::string const& name){
-            assert(variable_profile_table.find(name) ==
+            assert(variable_profile_table.find(name) !=
                 variable_profile_table.end());
             return variable_profile_table.at(name);
         };
@@ -70,8 +70,8 @@ if(node.op_type == "Abs") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -86,8 +86,8 @@ if(node.op_type == "Add") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -214,8 +214,8 @@ auto momentum = get<float>(node.attribute_table.at("momentum"));
 auto spatial = get<int>(node.attribute_table.at("spatial"));
 
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -474,8 +474,8 @@ node.attribute_table.emplace(
 auto alpha = get<float>(node.attribute_table.at("alpha"));
 
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -599,8 +599,8 @@ node.attribute_table.emplace(
 auto alpha = get<float>(node.attribute_table.at("alpha"));
 
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -668,8 +668,8 @@ auto bias = get<float>(node.attribute_table.at("bias"));
 auto size = get<float>(node.attribute_table.at("size"));
 
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -754,8 +754,8 @@ if(node.op_type == "Relu") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -782,8 +782,8 @@ node.attribute_table.emplace(
 auto axis = get<int>(node.attribute_table.at("axis"));
 
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -798,8 +798,8 @@ if(node.op_type == "Sum") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -814,8 +814,8 @@ if(node.op_type == "Sqrt") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
@@ -830,8 +830,8 @@ if(node.op_type == "Tanh") {
     {
         
         
-assert(node.input_name_list.size() == 1);
-assert(node.output_name_list.size() == 1);
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
 add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }

From 5bdf660dfd07a0c9f52596b3b5258a92da7d6ea2 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 1 Oct 2018 22:13:56 +0900
Subject: [PATCH 170/321] rename

---
 test/CMakeLists.txt                           |  2 +-
 ...tribute_completion_and_shape_inference.cpp | 65 +++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 test/attribute_completion_and_shape_inference.cpp

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 04f9813..7e197a1 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -21,8 +21,8 @@ add_executable(menoh_test
     operator.cpp
     mkldnn_with_generic_fallback_backend.cpp
     model_data.cpp
+    attribute_completion_and_shape_inference.cpp
     #vgg16.cpp
-
 )
 
 if(LINK_STATIC_LIBPROTOBUF)
diff --git a/test/attribute_completion_and_shape_inference.cpp b/test/attribute_completion_and_shape_inference.cpp
new file mode 100644
index 0000000..b998c75
--- /dev/null
+++ b/test/attribute_completion_and_shape_inference.cpp
@@ -0,0 +1,65 @@
+#include <gtest/gtest.h>
+
+#include <menoh/attribute_completion_and_shape_inference.hpp>
+#include <menoh/model_data.hpp>
+
+#include "common.hpp"
+namespace {
+
+    class AttributeCompletionAndShapeInferenceTest : public ::testing::Test {};
+
+    TEST_F(AttributeCompletionAndShapeInferenceTest, conv_completion) {
+        menoh_impl::model_data model_data;
+        model_data.node_list.push_back(
+          menoh_impl::node{"Conv", {"x", "w"}, {"y"}, {}});
+        std::unordered_map<std::string, menoh_impl::array_profile>
+          input_profile_table;
+        input_profile_table.emplace(
+          "x",
+          menoh_impl::array_profile(menoh_impl::dtype_t::float_, {1, 1, 3, 3}));
+        input_profile_table.emplace(
+          "w",
+          menoh_impl::array_profile(menoh_impl::dtype_t::float_, {1, 1, 3, 3}));
+        menoh_impl::complete_attribute_and_infer_shape(model_data,
+                                                       input_profile_table);
+        auto const& node = model_data.node_list.at(0);
+        auto found = node.attribute_table.find("kernel_shape");
+        ASSERT_NE(found, node.attribute_table.end());
+        menoh_impl::assert_eq_list(
+          menoh_impl::get<std::vector<int>>(found->second),
+          std::vector<int>({3, 3}));
+    }
+
+    TEST_F(AttributeCompletionAndShapeInferenceTest, sum_check) {
+        menoh_impl::model_data model_data;
+        model_data.node_list.push_back(
+          menoh_impl::node{"Sum", {"x0", "x1", "x2"}, {"y"}, {}});
+        std::unordered_map<std::string, menoh_impl::array_profile>
+          input_profile_table;
+        for(int i = 0; i < 3; ++i) {
+            input_profile_table.emplace(
+              "x" + std::to_string(i),
+              menoh_impl::array_profile(menoh_impl::dtype_t::float_,
+                                        {1, 1, 3, 3}));
+        }
+        ASSERT_NO_THROW(menoh_impl::complete_attribute_and_infer_shape(
+          model_data, input_profile_table));
+    }
+
+    TEST_F(AttributeCompletionAndShapeInferenceTest, add_check) {
+        menoh_impl::model_data model_data;
+        model_data.node_list.push_back(
+          menoh_impl::node{"Add", {"x0", "x1"}, {"y"}, {}});
+        std::unordered_map<std::string, menoh_impl::array_profile>
+          input_profile_table;
+        for(int i = 0; i < 2; ++i) {
+            input_profile_table.emplace(
+              "x" + std::to_string(i),
+              menoh_impl::array_profile(menoh_impl::dtype_t::float_,
+                                        {1, 1, 3, 3}));
+        }
+        ASSERT_NO_THROW(menoh_impl::complete_attribute_and_infer_shape(
+          model_data, input_profile_table));
+    }
+
+} // namespace

From 6a7413e24ac59c5fded4e85e32ec7341583b3742 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 2 Oct 2018 11:25:42 +0900
Subject: [PATCH 171/321] fix to link protobuf in test for shared library mode

---
 CMakeLists.txt             | 4 +++-
 cmake/ConfigureMenoh.cmake | 3 +--
 menoh/CMakeLists.txt       | 3 ---
 test/CMakeLists.txt        | 6 +++++-
 4 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a000058..4ed72f3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,7 +50,7 @@ mark_as_advanced(DOWNLOAD_LOCATION)
 # Enable ExternalProject_Add
 include(ExternalProject)
 
-# Setup protobuf (MUST run before building ONNX)
+# Setup protobuf (it is used in ONNX and Menoh)
 if(LINK_STATIC_LIBPROTOBUF)
     # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
     # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
@@ -61,6 +61,8 @@ if(LINK_STATIC_LIBPROTOBUF)
         message(FATAL_ERROR "LINK_STATIC_LIBPROTOBUF is supported only in UNIX-like environments")
     endif()
 else()
+    # Note: It may conflict with the loading mechanism in onnx's CMake configuration.
+    # See external/onnx/CMakeLists.txt for more details.
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
 endif()
diff --git a/cmake/ConfigureMenoh.cmake b/cmake/ConfigureMenoh.cmake
index fbbe2f0..1752799 100644
--- a/cmake/ConfigureMenoh.cmake
+++ b/cmake/ConfigureMenoh.cmake
@@ -8,8 +8,7 @@ macro(menoh_link_libraries TARGET_NAME SCOPE)
         target_link_libraries(${TARGET_NAME} ${SCOPE} -static-libstdc++)
     endif()
 
-    target_link_libraries(${TARGET_NAME} ${SCOPE} ${PROTOBUF_LIBRARIES})
-    target_link_libraries(${TARGET_NAME} ${SCOPE} onnx)
+    target_link_libraries(${TARGET_NAME} ${SCOPE} onnx) # onnx also contains protobuf
 
     if(NOT ${SCOPE})
         # PUBLIC will add transitive dependencies (`mklml_intel` and `iomp5`) to the link interface
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 06e9f3a..398d48f 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -6,9 +6,6 @@ option(LINK_STATIC_LIBSTDCXX "Link static libstdc++ to libmenoh" OFF)
 if(NOT DEFINED MKLDNN_LIBRARIES)
     message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
 endif()
-if(NOT DEFINED PROTOBUF_LIBRARIES)
-    message(FATAL_ERROR "PROTOBUF_LIBRARIES is not found")
-endif()
 
 file(GLOB_RECURSE SOURCES "." "*.cpp")
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 3085c5a..2ca5a7c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -25,7 +25,11 @@ add_executable(menoh_test
 
 )
 
-target_link_libraries(menoh_test gtest_main menoh_test_target onnx_proto)
+if(LINK_STATIC_LIBPROTOBUF)
+    target_link_libraries(menoh_test gtest_main menoh_test_target)
+else()
+    target_link_libraries(menoh_test gtest_main menoh_test_target ${PROTOBUF_LIBRARIES})
+endif()
 
 if(UNIX AND NOT APPLE)
     set_property(

From 8770abd750b9a8558c8b2c1be0899f51b2fe0ce9 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 2 Oct 2018 12:08:40 +0900
Subject: [PATCH 172/321] add explicit dependency to gen_onnx_proto

---
 appveyor.yml         | 2 +-
 menoh/CMakeLists.txt | 2 ++
 test/CMakeLists.txt  | 2 +-
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/appveyor.yml b/appveyor.yml
index 7c67464..9951f2c 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -72,7 +72,7 @@ build_script:
     cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
     make
   ) else (
-    cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DENABLE_TOOL=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&
+    cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&
     cmake --build . --config Release --target install
   )
 
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 398d48f..d420997 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -11,6 +11,8 @@ file(GLOB_RECURSE SOURCES "." "*.cpp")
 
 # Create a object library for generating shared library
 add_library(menoh_objlib OBJECT ${SOURCES})
+add_dependencies(menoh_objlib gen_onnx_proto) # custom target defined in onnx
+
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
 include(ConfigureMenoh)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2ca5a7c..2b9f9e4 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,7 +3,7 @@ enable_testing()
 # GTest setup
 set(GTEST_DIR "lib/googletest")
 execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-message(STATUS "Adding_${GTEST_DIR}")
+message(STATUS "Adding ${GTEST_DIR}")
 add_subdirectory(${GTEST_DIR})
 
 # filesystem setup

From 5c1a39a1e78c5d782ee773a4852fd9d5b613ac7b Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 2 Oct 2018 14:35:19 +0900
Subject: [PATCH 173/321] Update BUILDING.md

---
 BUILDING.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index eb6fea1..4dc0667 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -25,7 +25,7 @@ You also need to install the dependent libraries on your system:
 
 `protobuf` can be installed through most package managers instead of building it yourself. `mkl-dnn` package, unfortunatelly, is not available in many environments at the moment (except for `brew` in macOS).
 
-Note that you can use ProtoBuf either version 2 or 3, but, for example, if you build Menoh with `protoc` ver 3 you should use the binary with runtime ver 3.
+Note that you can use ProtoBuf either version 2 or 3, but the runtime version should be the same as `protoc` in your system.
 
 ### Debian/Ubuntu
 ```
@@ -86,7 +86,7 @@ pacman -S mingw-w64-x86_64-protobuf mingw-w64-x86_64-protobuf-c
 #### Installing MKL-DNN from binary package
 ```
 curl -omingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz -L https://github.com/pfnet-research/menoh/releases/download/v1.0.3/mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
-pacman -S --noconfirm mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
+pacman -U --noconfirm mingw-w64-x86_64-mkl-dnn-0.15-1-x86_64.pkg.tar.xz
 ```
 
 #### Installing MKL-DNN from source

From 823996917f09fee2788cd2f446488c8b2d1d41f8 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 2 Oct 2018 14:41:02 +0900
Subject: [PATCH 174/321] add `make`

---
 BUILDING.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/BUILDING.md b/BUILDING.md
index 4dc0667..c4ebe64 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -78,7 +78,7 @@ cd ../..
 ### Windows (MINGW)
 ```
 pacman -S mingw-w64-x86_64-toolchain
-pacman -S git
+pacman -S git make
 pacman -S mingw-w64-x86_64-cmake
 pacman -S mingw-w64-x86_64-protobuf mingw-w64-x86_64-protobuf-c
 ```

From 99a77bcca9a44c85382eaa84f3ba2b5817808895 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Tue, 2 Oct 2018 14:52:43 +0900
Subject: [PATCH 175/321] add PYTHON_EXECUTABLE option

---
 BUILDING.md | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/BUILDING.md b/BUILDING.md
index eb6fea1..a308f45 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -194,3 +194,12 @@ MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
   cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64
 make
 ```
+
+### Note
+
+#### Python command name
+Menoh requires `python` command to generate source codes at build time. Add `PYTHON_EXECUTABLE` option to `cmake` if you want to use `python` command with non-standard name (e.g. `python3`).
+
+```bash
+cmake -DPYTHON_EXECUTABLE=python3 ..
+```

From b478544997d9df77e57f7fa052e25b6e66118f46 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 2 Oct 2018 21:50:38 +0900
Subject: [PATCH 176/321] remove invalid assertion from generic context and
 convert assertion to error in mkldnn context

---
 .../backend/generic/generic_context.cpp       |   2 -
 .../backend/mkldnn/mkldnn_context.cpp         | 162 ++++++++++--------
 2 files changed, 88 insertions(+), 76 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 2c3f964..81a8210 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -55,8 +55,6 @@ namespace menoh_impl {
                               [&](auto const& table) {
                                   auto found = table.find(input_name);
                                   if(found != table.end()) {
-                                      assert(found->second.dims().size() == 2 ||
-                                             found->second.dims().size() == 4);
                                       input_list.push_back(found->second);
                                       return true;
                                   }
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 14ea6b8..975e0a6 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -1,6 +1,8 @@
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp>
 
+#include <menoh/graph.hpp> // for unsupported_operator error
+
 #include <menoh/mkldnn/utility.hpp>
 
 namespace menoh_impl {
@@ -37,86 +39,98 @@ namespace menoh_impl {
                     auto const& node = node_list.at(current_index);
                     std::vector<array> input_list;
                     std::vector<procedure> new_copy_procedure_list;
+                    std::vector<mkldnn::primitive> new_primitive_list;
+                    std::vector<std::pair<std::string, mkldnn::memory>>
+                      new_output_memory_list;
+                    std::vector<mkldnn::memory> new_temp_memory_list;
 
-                    for(auto const& input_name : node.input_name_list) {
-                        do {
-                            // search in self variable table
-                            auto found_from_variable_memory_table =
-                              variable_memory_table_.find(input_name);
-                            if(found_from_variable_memory_table !=
-                               variable_memory_table_.end()) {
-                                *logger << input_name
-                                        << " is found in self variable table"
-                                        << std::endl;
-                                input_list.push_back(
-                                  menoh_impl::mkldnn_backend::memory_to_array(
-                                    found_from_variable_memory_table->second));
-                                break;
-                            }
-
-                            // search in common parameter and input table
-                            auto found_from_common_table =
-                              [&](auto const& table) {
-                                  auto found = table.find(input_name);
-                                  if(found != table.end()) {
-                                      assert(found->second.dims().size() == 2 ||
-                                             found->second.dims().size() == 4);
-                                      input_list.push_back(found->second);
-                                      return true;
-                                  }
-                                  return false;
-                              };
-                            if(found_from_common_table(
-                                 common_parameter_table)) {
-                                *logger << input_name
-                                        << " is found in common parameter table"
-                                        << std::endl;
-                                break;
-                            }
-                            if(found_from_common_table(common_input_table)) {
-                                *logger << input_name
-                                        << " is found in common input table"
-                                        << std::endl;
-                                break;
-                            }
-
-                            // search in other contexts' variable table
-                            bool is_found_from_other_context = false;
-                            for(auto const& context_pair : context_list) {
-                                if(context_pair.first == context_name) {
-                                    continue; // skip self
+                    try {
+                        for(auto const& input_name : node.input_name_list) {
+                            do {
+                                // search in self variable table
+                                auto found_from_variable_memory_table =
+                                  variable_memory_table_.find(input_name);
+                                if(found_from_variable_memory_table !=
+                                   variable_memory_table_.end()) {
+                                    *logger
+                                      << input_name
+                                      << " is found in self variable table"
+                                      << std::endl;
+                                    input_list.push_back(
+                                      menoh_impl::mkldnn_backend::
+                                        memory_to_array(
+                                          found_from_variable_memory_table
+                                            ->second));
+                                    break;
                                 }
-                                auto found =
-                                  context_pair.second->try_to_get_variable(
-                                    input_name);
-                                if(found) {
+
+                                // search in common parameter and input table
+                                auto found_from_common_table = [&](auto const&
+                                                                     table) {
+                                    auto found = table.find(input_name);
+                                    if(found != table.end()) {
+                                        if(found->second.dims().size() != 2 &&
+                                           found->second.dims().size() != 4) {
+                                            throw unsupported_operator(
+                                              node.op_type +
+                                              " takes input which has ndims: " +
+                                              std::to_string(
+                                                found->second.dims().size()));
+                                        }
+                                        input_list.push_back(found->second);
+                                        return true;
+                                    }
+                                    return false;
+                                };
+                                if(found_from_common_table(
+                                     common_parameter_table)) {
+                                    *logger
+                                      << input_name
+                                      << " is found in common parameter table"
+                                      << std::endl;
+                                    break;
+                                }
+                                if(found_from_common_table(
+                                     common_input_table)) {
                                     *logger << input_name
-                                            << " is found in other context's "
-                                               "varibale table: "
-                                            << context_pair.first << std::endl;
-                                    procedure copy_proc; // copy from other
-                                                         // context to array
-                                    array arr;
-                                    std::tie(copy_proc, arr) = *found;
-                                    assert(arr.dims().size() == 2 ||
-                                           arr.dims().size() == 4);
-                                    new_copy_procedure_list.push_back(
-                                      copy_proc);
-                                    input_list.push_back(arr);
-                                    is_found_from_other_context = true;
+                                            << " is found in common input table"
+                                            << std::endl;
                                     break;
                                 }
-                            }
-                            assert(is_found_from_other_context);
-                        } while(false);
-                    }
 
-                    // make primitives and
-                    std::vector<mkldnn::primitive> new_primitive_list;
-                    std::vector<std::pair<std::string, mkldnn::memory>>
-                      new_output_memory_list;
-                    std::vector<mkldnn::memory> new_temp_memory_list;
-                    try {
+                                // search in other contexts' variable table
+                                bool is_found_from_other_context = false;
+                                for(auto const& context_pair : context_list) {
+                                    if(context_pair.first == context_name) {
+                                        continue; // skip self
+                                    }
+                                    auto found =
+                                      context_pair.second->try_to_get_variable(
+                                        input_name);
+                                    if(found) {
+                                        *logger
+                                          << input_name
+                                          << " is found in other context's "
+                                             "varibale table: "
+                                          << context_pair.first << std::endl;
+                                        procedure copy_proc; // copy from other
+                                                             // context to array
+                                        array arr;
+                                        std::tie(copy_proc, arr) = *found;
+                                        assert(arr.dims().size() == 2 ||
+                                               arr.dims().size() == 4);
+                                        new_copy_procedure_list.push_back(
+                                          copy_proc);
+                                        input_list.push_back(arr);
+                                        is_found_from_other_context = true;
+                                        break;
+                                    }
+                                }
+                                assert(is_found_from_other_context);
+                            } while(false);
+                        }
+
+                        // make primitives and
                         auto factory =
                           procedure_factory_table_.at(node.op_type);
                         std::tie(new_primitive_list, new_output_memory_list,

From 476ec3a7b133eda9bf7b030ba47577eddb9ed237 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 2 Oct 2018 21:51:51 +0900
Subject: [PATCH 177/321] add lines

---
 .../backend/mkldnn/mkldnn_context.cpp                           | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 975e0a6..dbadc61 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -139,9 +139,11 @@ namespace menoh_impl {
                                              input_list, required_output_table,
                                              engine_);
                     } catch(...) { break; }
+
                     primitive_list.insert(primitive_list.end(),
                                           new_primitive_list.begin(),
                                           new_primitive_list.end());
+
                     // add copy procedures
                     procedure_list.insert(
                       procedure_list.end(),

From 750ccfb83bd60d77c16485a6cec8306f69cac226 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 2 Oct 2018 22:03:04 +0900
Subject: [PATCH 178/321] remove model_data_completion test (it is moved to
 test/attribute_completion_and_shape_inference.cpp

---
 test/model_data_completion.cpp | 29 -----------------------------
 1 file changed, 29 deletions(-)
 delete mode 100644 test/model_data_completion.cpp

diff --git a/test/model_data_completion.cpp b/test/model_data_completion.cpp
deleted file mode 100644
index f02a540..0000000
--- a/test/model_data_completion.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <gtest/gtest.h>
-
-#include <menoh/model_completion.hpp>
-#include <menoh/model_data.hpp>
-
-#include "common.hpp"
-namespace {
-
-    class ModelDataCompletionTest : public ::testing::Test {};
-
-    TEST_F(ModelDataCompletionTest, completion) {
-        menoh_impl::model_data model_data;
-        model_data.node_list.push_back(
-          menoh_impl::node{"Conv", {"x", "w"}, {"y"}, {}});
-        std::unordered_map<std::string, menoh_impl::array_profile>
-          input_profile_table;
-        input_profile_table.emplace(
-          "w",
-          menoh_impl::array_profile(menoh_impl::dtype_t::float_, {1, 1, 3, 3}));
-        menoh_impl::complete_model_data(model_data, input_profile_table);
-        auto const& node = model_data.node_list.at(0);
-        auto found = node.attribute_table.find("kernel_shape");
-        ASSERT_NE(found, node.attribute_table.end());
-        menoh_impl::assert_eq_list(
-          menoh_impl::get<std::vector<int>>(found->second),
-          std::vector<int>({3, 3}));
-    }
-
-} // namespace

From db60d6695ee018467e195ae56a3b49011d41620a Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 3 Oct 2018 12:48:08 +0900
Subject: [PATCH 179/321] add a patch for CMake configuration in onnx

---
 CMakeLists.txt                            |   6 +-
 external/onnx-v1.3.0-patch_CMakeLists.txt | 565 ++++++++++++++++++++++
 menoh/CMakeLists.txt                      |   5 +
 test/CMakeLists.txt                       |   2 +
 4 files changed, 576 insertions(+), 2 deletions(-)
 create mode 100644 external/onnx-v1.3.0-patch_CMakeLists.txt

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ed72f3..6cce354 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -67,14 +67,16 @@ else()
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
 endif()
 
-include_directories(${PROTOBUF_INCLUDE_DIRS})
-
 # Build libonnx.a
 message(STATUS "Adding external/onnx")
 
 set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
 execute_process(COMMAND git submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
+# see https://github.com/onnx/onnx/pull/1466
+message(STATUS "Patching to external/onnx")
+configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/onnx/CMakeLists.txt COPYONLY)
+
 # TODO: enable the following option when it is ready for migrating to onnx-ml
 #set(ONNX_ML 1)
 add_subdirectory(external/onnx) # Note: BUILD_SHARED_LIBS must be OFF in this place
diff --git a/external/onnx-v1.3.0-patch_CMakeLists.txt b/external/onnx-v1.3.0-patch_CMakeLists.txt
new file mode 100644
index 0000000..23ec68b
--- /dev/null
+++ b/external/onnx-v1.3.0-patch_CMakeLists.txt
@@ -0,0 +1,565 @@
+# Minimum CMake required
+cmake_minimum_required(VERSION 3.1)
+include(cmake/Utils.cmake)
+# Set default build type
+if(NOT CMAKE_BUILD_TYPE)
+  message(STATUS "Build type not set - defaulting to Release")
+  set(
+    CMAKE_BUILD_TYPE "Release"
+    CACHE
+      STRING
+      "Choose the type of build from: Debug Release RelWithDebInfo MinSizeRel Coverage."
+    FORCE)
+endif()
+cmake_policy(SET CMP0063 NEW)
+
+# Project
+project(onnx C CXX)
+option(ONNX_BUILD_BENCHMARKS "Build ONNX micro-benchmarks" OFF)
+
+option(BUILD_ONNX_PYTHON "Build Python binaries" OFF)
+option(ONNX_GEN_PB_TYPE_STUBS "Generate protobuf python type stubs" ON)
+option(ONNX_WERROR "Build with Werror" OFF)
+option(ONNX_COVERAGE "Build with coverage instrumentation" OFF)
+option(ONNX_BUILD_TESTS "Build ONNX C++ APIs Tests" OFF)
+option(ONNX_USE_LITE_PROTO "Use lite protobuf instead of full." OFF)
+
+set(ONNX_NAMESPACE "onnx" CACHE STRING "onnx namespace")
+
+# Set C++11 as standard for the whole project
+if(NOT MSVC)
+  set(CMAKE_CXX_STANDARD 11)
+endif(NOT MSVC)
+
+set(ONNX_ROOT ${PROJECT_SOURCE_DIR})
+
+# Read ONNX version
+file(READ "${PROJECT_SOURCE_DIR}/VERSION_NUMBER" ONNX_VERSION)
+string(STRIP "${ONNX_VERSION}" ONNX_VERSION)
+
+if(NOT MSVC)
+  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
+  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
+  if(ONNX_COVERAGE)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
+  endif()
+endif()
+
+if(ONNX_BUILD_TESTS)
+  list(APPEND CMAKE_MODULE_PATH ${ONNX_ROOT}/cmake/external)
+  include(googletest)
+endif()
+
+if((ONNX_USE_LITE_PROTO AND TARGET protobuf::libprotobuf-lite) OR ((NOT ONNX_USE_LITE_PROTO) AND TARGET protobuf::libprotobuf))
+  # Sometimes we need to use protoc compiled for host architecture while linking
+  # libprotobuf against target architecture. See https://github.com/caffe2/caffe
+  # 2/blob/96f35ad75480b25c1a23d6e9e97bccae9f7a7f9c/cmake/ProtoBuf.cmake#L92-L99
+  if(EXISTS "${ONNX_CUSTOM_PROTOC_EXECUTABLE}")
+    message(STATUS "Using custom protoc executable")
+    set(ONNX_PROTOC_EXECUTABLE ${ONNX_CUSTOM_PROTOC_EXECUTABLE})
+  else()
+    set(ONNX_PROTOC_EXECUTABLE $<TARGET_FILE:protobuf::protoc>)
+  endif()
+else()
+  # Customized version of find Protobuf. We need to avoid situations mentioned
+  # in https://github.com/caffe2/caffe2/blob/b7d983f255ef5496474f1ea188edb5e0ac4
+  # 42761/cmake/ProtoBuf.cmake#L82-L92 The following section is stolen from
+  # cmake/ProtoBuf.cmake in Caffe2
+  find_program(Protobuf_PROTOC_EXECUTABLE
+               NAMES protoc
+               DOC "The Google Protocol Buffers Compiler")
+
+  # Only if protoc was found, seed the include directories and libraries. We
+  # assume that protoc is installed at PREFIX/bin. We use get_filename_component
+  # to resolve PREFIX.
+  if(Protobuf_PROTOC_EXECUTABLE)
+    set(ONNX_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
+    get_filename_component(_PROTOBUF_INSTALL_PREFIX
+                           ${Protobuf_PROTOC_EXECUTABLE} DIRECTORY)
+    get_filename_component(_PROTOBUF_INSTALL_PREFIX
+                           ${_PROTOBUF_INSTALL_PREFIX}/.. REALPATH)
+    find_library(Protobuf_PROTOC_LIBRARY
+                 NAMES protoc
+                 PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
+                 NO_DEFAULT_PATH)
+    if(ONNX_USE_LITE_PROTO)
+      find_library(Protobuf_LITE_LIBRARY
+        NAMES protobuf-lite
+        PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
+        NO_DEFAULT_PATH)
+    else(ONNX_USE_LITE_PROTO)
+      find_library(Protobuf_LIBRARY
+        NAMES protobuf
+        PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
+        NO_DEFAULT_PATH)
+    endif(ONNX_USE_LITE_PROTO)
+    find_path(Protobuf_INCLUDE_DIR google/protobuf/service.h
+              PATHS ${_PROTOBUF_INSTALL_PREFIX}/include
+              NO_DEFAULT_PATH)
+    find_package(Protobuf REQUIRED)
+  endif()
+endif()
+
+# Build the libraries with -fPIC
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+
+# function(RELATIVE_PROTOBUF_GENERATE_CPP SRCS HDRS ROOT_DIR) from https://githu
+# b.com/tensorflow/tensorflow/blob/d2c3b873c6f8ff999a2e4ee707a84ff00d9c15a5/tens
+# orflow/contrib/cmake/tf_core_framework.cmake to solve the problem that
+# customized dir can't be specified when calling PROTOBUF_GENERATE_CPP.
+function(RELATIVE_PROTOBUF_GENERATE_CPP NAME SRCS HDRS ROOT_DIR DEPEND)
+  if(NOT ARGN)
+    message(
+      SEND_ERROR
+        "Error: RELATIVE_PROTOBUF_GENERATE_CPP() called without any proto files"
+      )
+    return()
+  endif()
+
+  if(MSVC AND BUILD_SHARED_LIBS)
+    set(ONNX_DLLEXPORT_STR "dllexport_decl=ONNX_API:")
+  else()
+    set(ONNX_DLLEXPORT_STR "")
+  endif()
+
+  set(${SRCS})
+  set(${HDRS})
+
+  set(GEN_PROTO_PY ${ROOT_DIR}/onnx/gen_proto.py)
+  foreach(INFILE ${ARGN})
+    set(ABS_FILE ${ROOT_DIR}/${INFILE})
+    get_filename_component(FILE_DIR ${ABS_FILE} DIRECTORY)
+    get_filename_component(FILE_WE ${INFILE} NAME_WE)
+    if(ONNX_ML)
+      if(ONNX_NAMESPACE STREQUAL "onnx")
+        set(GENERATED_FILE_WE "${FILE_WE}-ml")
+      else()
+        set(GENERATED_FILE_WE "${FILE_WE}_${ONNX_NAMESPACE}-ml")
+      endif()
+    else()
+      if(ONNX_NAMESPACE STREQUAL "onnx")
+        set(GENERATED_FILE_WE "${FILE_WE}")
+      else()
+        set(GENERATED_FILE_WE "${FILE_WE}_${ONNX_NAMESPACE}")
+      endif()
+    endif()
+    file(RELATIVE_PATH REL_DIR ${ROOT_DIR} ${FILE_DIR})
+    set(OUTPUT_PROTO_DIR "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}")
+
+    set(OUTPUT_PB_HEADER "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.h")
+    set(OUTPUT_PB_SRC "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.cc")
+    set(GENERATED_PROTO "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.proto")
+    if(NOT (ONNX_NAMESPACE STREQUAL "onnx"))
+      # We need this dummy header generated by gen_proto.py when ONNX_NAMESPACE
+      # is not onnx
+      list(APPEND ${HDRS} "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.h")
+    endif()
+    list(APPEND ${SRCS} "${OUTPUT_PB_SRC}")
+    list(APPEND ${HDRS} "${OUTPUT_PB_HEADER}")
+
+    if(NOT EXISTS "${OUTPUT_PROTO_DIR}")
+      file(MAKE_DIRECTORY "${OUTPUT_PROTO_DIR}")
+    endif()
+
+    if("${PYTHON_EXECUTABLE}" STREQUAL "")
+      set(_python_exe "python")
+    else()
+      set(_python_exe "${PYTHON_EXECUTABLE}")
+    endif()
+    set(GEN_PROTO_ARGS
+        -p
+        "${ONNX_NAMESPACE}"
+        -o
+        "${OUTPUT_PROTO_DIR}"
+        "${FILE_WE}")
+    if(ONNX_ML)
+      list(APPEND GEN_PROTO_ARGS -m)
+    endif()
+    if(ONNX_USE_LITE_PROTO)
+      list(APPEND GEN_PROTO_ARGS -l)
+    endif()
+    add_custom_command(OUTPUT "${GENERATED_PROTO}"
+                       COMMAND "${_python_exe}" "${GEN_PROTO_PY}"
+                               ARGS ${GEN_PROTO_ARGS}
+                       DEPENDS ${INFILE}
+                       COMMENT "Running gen_proto.py on ${INFILE}"
+                       VERBATIM)
+
+    set(PROTOC_ARGS
+        ${GENERATED_PROTO}
+        -I
+        ${CMAKE_CURRENT_BINARY_DIR}
+        --cpp_out
+        ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
+    if(BUILD_ONNX_PYTHON)
+      list(APPEND PROTOC_ARGS --python_out
+                  ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
+      if(ONNX_GEN_PB_TYPE_STUBS)
+        # Haven't figured out how to generate mypy stubs on Windows yet
+        if(NOT WIN32)
+          # If onnx was packaged to pypi from Windows, protoc-gen-mypy.py is
+          # missing the +x flag. Add it.
+          execute_process(COMMAND chmod +x ${ROOT_DIR}/tools/protoc-gen-mypy.py)
+          set(PROTOC_MYPY_PLUGIN_FILE ${ROOT_DIR}/tools/protoc-gen-mypy.py)
+        else(NOT WIN32)
+          set(PROTOC_MYPY_PLUGIN_FILE ${ROOT_DIR}/tools/protoc-gen-mypy.bat)
+        endif()
+        list(APPEND PROTOC_ARGS
+                    --plugin
+                    protoc-gen-mypy=${PROTOC_MYPY_PLUGIN_FILE}
+                    --mypy_out
+                    ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
+      endif()
+    endif()
+    if(NOT ONNX_PROTOC_EXECUTABLE)
+      message(FATAL_ERROR "Protobuf compiler not found")
+    endif()
+    if(ONNX_PROTO_POST_BUILD_SCRIPT)
+      add_custom_command(
+        OUTPUT "${OUTPUT_PB_SRC}" "${OUTPUT_PB_HEADER}"
+        COMMAND ${ONNX_PROTOC_EXECUTABLE} ARGS ${PROTOC_ARGS}
+        COMMAND "${CMAKE_COMMAND}" -DFILENAME=${OUTPUT_PB_HEADER}
+                -DNAMESPACES=${ONNX_NAMESPACE} -P
+                ${ONNX_PROTO_POST_BUILD_SCRIPT}
+        COMMAND "${CMAKE_COMMAND}" -DFILENAME=${OUTPUT_PB_SRC}
+                -DNAMESPACES=${ONNX_NAMESPACE} -P
+                ${ONNX_PROTO_POST_BUILD_SCRIPT}
+        DEPENDS ${GENERATED_PROTO} ${DEPEND}
+        COMMENT "Running C++ protocol buffer compiler on ${GENERATED_PROTO}"
+        VERBATIM)
+    else()
+      add_custom_command(
+        OUTPUT "${OUTPUT_PB_SRC}" "${OUTPUT_PB_HEADER}"
+        COMMAND ${ONNX_PROTOC_EXECUTABLE} ARGS ${PROTOC_ARGS}
+        DEPENDS ${GENERATED_PROTO} ${DEPEND}
+        COMMENT "Running C++ protocol buffer compiler on ${GENERATED_PROTO}"
+        VERBATIM)
+    endif()
+    add_custom_target(${NAME} DEPENDS ${OUTPUT_PB_SRC} ${OUTPUT_PB_HEADER})
+  endforeach()
+
+  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
+  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
+  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
+endfunction()
+
+relative_protobuf_generate_cpp(gen_onnx_proto
+                               PROTO_SRCS
+                               PROTO_HDRS
+                               ${ONNX_ROOT}
+                               ""
+                               onnx/onnx.in.proto)
+relative_protobuf_generate_cpp(gen_onnx_operators_proto
+                               PROTO_SRCS2
+                               PROTO_HDRS2
+                               ${ONNX_ROOT}
+                               gen_onnx_proto
+                               onnx/onnx-operators.in.proto)
+list(APPEND PROTO_SRCS ${PROTO_SRCS2})
+list(APPEND PROTO_HDRS ${PROTO_HDRS2})
+
+file(GLOB_RECURSE onnx_src "${ONNX_ROOT}/onnx/*.h" "${ONNX_ROOT}/onnx/*.cc")
+file(GLOB_RECURSE onnx_gtests_src "${ONNX_ROOT}/onnx/test/cpp/*.h"
+                  "${ONNX_ROOT}/onnx/test/cpp/*.cc")
+list(REMOVE_ITEM onnx_src "${ONNX_ROOT}/onnx/cpp2py_export.cc")
+list(REMOVE_ITEM onnx_src ${onnx_gtests_src})
+
+add_library(onnx_proto ${PROTO_SRCS} ${PROTO_HDRS})
+target_include_directories(onnx_proto PUBLIC
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+  $<INSTALL_INTERFACE:include>
+  $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
+
+
+if(ONNX_USE_LITE_PROTO)
+  if(TARGET protobuf::libprotobuf-lite)
+    target_link_libraries(onnx_proto PUBLIC protobuf::libprotobuf-lite)
+  else()
+    target_link_libraries(onnx_proto PUBLIC ${PROTOBUF_LITE_LIBRARIES})
+  endif()
+else()
+  if(TARGET protobuf::libprotobuf)
+    target_link_libraries(onnx_proto PUBLIC protobuf::libprotobuf)
+  else()
+    target_link_libraries(onnx_proto PUBLIC ${PROTOBUF_LIBRARIES})
+  endif()
+endif()
+add_onnx_global_defines(onnx_proto)
+
+add_library(onnx ${onnx_src})
+target_include_directories(onnx PUBLIC
+  $<BUILD_INTERFACE:${ONNX_ROOT}>
+  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+  $<INSTALL_INTERFACE:include>)
+target_link_libraries(onnx PUBLIC onnx_proto)
+add_onnx_global_defines(onnx)
+
+if(BUILD_ONNX_PYTHON)
+  if("${PY_EXT_SUFFIX}" STREQUAL "")
+    if(MSVC)
+      set(PY_EXT_SUFFIX ".pyd")
+    else()
+      set(PY_EXT_SUFFIX ".so")
+    endif()
+  endif()
+
+  add_library(onnx_cpp2py_export MODULE "${ONNX_ROOT}/onnx/cpp2py_export.cc")
+  set_target_properties(onnx_cpp2py_export PROPERTIES PREFIX "")
+  set_target_properties(onnx_cpp2py_export
+                        PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
+  set_target_properties(onnx_cpp2py_export PROPERTIES SUFFIX ${PY_EXT_SUFFIX})
+  set_target_properties(onnx_cpp2py_export
+                        PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+  target_include_directories(onnx_cpp2py_export PRIVATE
+                             $<BUILD_INTERFACE:${ONNX_ROOT}>
+                             $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+                             $<INSTALL_INTERFACE:include>
+                             ${PYTHON_INCLUDE_DIR})
+
+  # pybind11 is a header only lib
+  find_package(pybind11 2.2)
+  if(pybind11_FOUND)
+    target_include_directories(onnx_cpp2py_export PUBLIC
+      ${pybind11_INCLUDE_DIRS})
+  else()
+    if(EXISTS ${ONNX_ROOT}/third_party/pybind11/include/pybind11/pybind11.h)
+      target_include_directories(onnx_cpp2py_export PUBLIC
+        ${ONNX_ROOT}/third_party/pybind11/include)
+    else()
+      message(FATAL_ERROR "cannot find pybind")
+    endif()
+  endif()
+
+  if(APPLE)
+    set_target_properties(onnx_cpp2py_export
+                          PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
+    target_link_libraries(onnx_cpp2py_export
+                          PRIVATE -Wl,-force_load,$<TARGET_FILE:onnx>)
+  elseif(MSVC)
+    # In MSVC, we will add whole archive in default
+    target_link_libraries(onnx_cpp2py_export
+                          PRIVATE -WHOLEARCHIVE:$<TARGET_FILE:onnx>)
+  else()
+    # Assume everything else is like gcc
+    target_link_libraries(onnx_cpp2py_export
+                          PRIVATE "-Wl,--whole-archive" $<TARGET_FILE:onnx>
+                                  "-Wl,--no-whole-archive")
+  endif()
+
+  target_link_libraries(onnx_cpp2py_export PRIVATE onnx)
+
+  if(MSVC)
+    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+      set(MP_FLAG "-Xclang" "-fopenmp")
+      set(EXTRA_FLAGS
+          "-Wno-implicit-function-declaration"
+          "-Wno-undefined-inline"
+          "-Wno-incompatible-pointer-types"
+          "-Wno-dllexport-explicit-instantiation-decl"
+          "-Wno-microsoft-unqualified-friend"
+          "-Wno-absolute-value"
+          "-Wno-unused-variable"
+          "-Wno-writable-strings"
+          "-Qunused-arguments")
+    else()
+      set(MP_FLAG "/MP")
+      set(EXTRA_FLAGS "")
+    endif()
+    find_package(PythonInterp ${PY_VERSION} REQUIRED)
+    find_package(PythonLibs ${PY_VERSION} REQUIRED)
+    target_link_libraries(onnx_cpp2py_export PRIVATE ${PYTHON_LIBRARIES})
+    target_compile_options(onnx_cpp2py_export
+                           PRIVATE ${MP_FLAG}
+                                   /WX
+                                   /wd4800 # disable warning type' : forcing
+                                           # value to bool 'true' or 'false'
+                                           # (performance warning)
+                                   /wd4503 # identifier' : decorated name length
+                                           # exceeded, name was truncated
+                                   /wd4146 # unary minus operator applied to
+                                           # unsigned type, result still
+                                           # unsigned from include\google\protob
+                                           # uf\wire_format_lite.h
+                                   ${EXTRA_FLAGS})
+    target_compile_options(onnx_cpp2py_export PRIVATE /MT)
+    add_onnx_global_defines(onnx_cpp2py_export)
+  endif()
+endif()
+
+if(ONNX_BUILD_BENCHMARKS)
+  if(NOT TARGET benchmark)
+    # We will not need to test benchmark lib itself.
+    set(BENCHMARK_ENABLE_TESTING OFF
+        CACHE BOOL "Disable benchmark testing as we don't need it.")
+    # We will not need to install benchmark since we link it statically.
+    set(BENCHMARK_ENABLE_INSTALL OFF
+        CACHE BOOL
+              "Disable benchmark install to avoid overwriting vendor install.")
+    add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/benchmark)
+  endif()
+
+  add_executable(protobuf-bench tools/protobuf-bench.cc)
+  target_include_directories(protobuf-bench PUBLIC
+    $<BUILD_INTERFACE:${ONNX_ROOT}>
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
+    $<INSTALL_INTERFACE:include>
+    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
+  target_link_libraries(protobuf-bench onnx_proto benchmark)
+endif()
+
+# Export include directories
+set(ONNX_INCLUDE_DIRS "${ONNX_ROOT}" "${CMAKE_CURRENT_BINARY_DIR}")
+get_directory_property(hasParent PARENT_DIRECTORY)
+if(hasParent)
+  set(ONNX_INCLUDE_DIRS ${ONNX_INCLUDE_DIRS} PARENT_SCOPE)
+endif()
+
+if(MSVC)
+  target_compile_options(onnx_proto
+                         PRIVATE ${MP_FLAG}
+                                 /WX
+                                 /wd4800 # disable warning type' : forcing value
+                                         # to bool 'true' or 'false'
+                                         # (performance warning)
+                                 /wd4503 # identifier' : decorated name length
+                                         # exceeded, name was truncated
+                                 /wd4146 # unary minus operator applied to
+                                         # unsigned type, result still unsigned:
+                                         # include\google\protobuf\wire_format_l
+                                         # ite.h
+                                 ${EXTRA_FLAGS})
+  target_compile_options(onnx
+                         PRIVATE ${MP_FLAG}
+                                 /WX
+                                 /wd4800 # disable warning type' : forcing value
+                                         # to bool 'true' or 'false'
+                                         # (performance warning)
+                                 /wd4503 # identifier' : decorated name length
+                                         # exceeded, name was truncated
+                                 /wd4146 # unary minus operator applied to
+                                         # unsigned type, result still unsigned
+                                 ${EXTRA_FLAGS})
+  add_msvc_runtime_flag(onnx_proto)
+  add_msvc_runtime_flag(onnx)
+  set(onnx_static_library_flags
+      -IGNORE:4221 # LNK4221: This object file does not define any previously
+                   # undefined public symbols, so it will not be used by any
+                   # link operation that consumes this library
+      )
+  set_target_properties(onnx
+                        PROPERTIES STATIC_LIBRARY_FLAGS
+                                   "${onnx_static_library_flags}")
+elseif(APPLE)
+
+else()
+  if(${ONNX_WERROR})
+    target_compile_options(onnx PRIVATE -Werror=sign-compare -Werror=conversion)
+  endif()
+endif()
+
+if(APPLE)
+  set_target_properties(onnx PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
+endif()
+
+# ---[ ONNX Interface for Framework Integratin (ONNXIFI)
+add_library(onnxifi INTERFACE)
+target_include_directories(onnxifi INTERFACE
+  $<BUILD_INTERFACE:${ONNX_ROOT}>
+  $<INSTALL_INTERFACE:include>)
+
+# ---[ ONNXIFI loader
+add_library(onnxifi_loader STATIC onnx/onnxifi_loader.c)
+target_include_directories(onnxifi_loader PUBLIC
+  $<BUILD_INTERFACE:${ONNX_ROOT}>
+  $<INSTALL_INTERFACE:include>)
+# Users of ONNX backend API would compile it with their toolchain, so it is
+# implemented in standard C89 for maximum compatibility
+set_target_properties(onnxifi_loader
+                      PROPERTIES C_STANDARD
+                                 90
+                                 C_EXTENSIONS
+                                 NO)
+target_link_libraries(onnxifi_loader PUBLIC onnxifi ${CMAKE_DL_LIBS})
+if(MSVC)
+  add_msvc_runtime_flag(onnxifi_loader)
+endif()
+
+if (NOT ANDROID AND NOT IOS)
+  # ---[ ONNXIFI wrapper
+  add_library(onnxifi_wrapper MODULE onnx/onnxifi_wrapper.c)
+  target_include_directories(onnxifi_wrapper PRIVATE
+    $<BUILD_INTERFACE:${ONNX_ROOT}>
+    $<INSTALL_INTERFACE:include>)
+  set_target_properties(onnxifi_wrapper PROPERTIES
+    C_STANDARD 99
+    C_EXTENSIONS NO
+    OUTPUT_NAME "onnxifi"
+    POSITION_INDEPENDENT_CODE YES)
+  target_link_libraries(onnxifi_wrapper PRIVATE onnxifi_loader onnxifi)
+  if(DEFINED ONNXIFI_SEARCH_DIR)
+    target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_SEARCH_DIR=\"${ONNXIFI_SEARCH_DIR}\"")
+  endif()
+  if(WIN32)
+    if(MSVC)
+      target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_PUBLIC=__declspec(dllexport)")
+    else()
+      target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_PUBLIC=__attribute__((__dllexport__))")
+    endif()
+  endif()
+  if(APPLE)
+    # By default CMake would use .so suffix on Mac
+    set_target_properties(onnxifi_wrapper PROPERTIES SUFFIX ".dylib")
+  endif()
+endif()
+
+# ---[ ONNXIFI dummy backend
+add_library(onnxifi_dummy SHARED onnx/onnxifi_dummy.c)
+target_include_directories(onnxifi_dummy PRIVATE
+  $<BUILD_INTERFACE:${ONNX_ROOT}>
+  $<INSTALL_INTERFACE:include>)
+target_link_libraries(onnxifi_dummy PUBLIC onnxifi ${CMAKE_DL_LIBS})
+target_compile_definitions(onnxifi_dummy PRIVATE ONNXIFI_BUILD_LIBRARY=TRUE)
+if(MSVC)
+  add_msvc_runtime_flag(onnxifi_dummy)
+endif()
+
+install(DIRECTORY ${ONNX_ROOT}/onnx
+        DESTINATION include
+        FILES_MATCHING
+        PATTERN "*.h")
+install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
+        DESTINATION include
+        FILES_MATCHING
+        PATTERN "*.h")
+
+configure_file(
+  ${PROJECT_SOURCE_DIR}/cmake/ONNXConfigVersion.cmake.in
+  ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
+  @ONLY)
+configure_file(
+  ${PROJECT_SOURCE_DIR}/cmake/ONNXConfig.cmake.in
+  ${PROJECT_BINARY_DIR}/ONNXConfig.cmake
+  @ONLY)
+install(FILES
+  ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
+  ${PROJECT_BINARY_DIR}/ONNXConfig.cmake
+  DESTINATION share/cmake/ONNX
+  COMPONENT dev)
+install(EXPORT ONNXTargets DESTINATION share/cmake/ONNX)
+install(TARGETS
+  onnx onnx_proto
+  onnxifi onnxifi_dummy onnxifi_loader
+  EXPORT ONNXTargets DESTINATION lib)
+
+if(NOT ANDROID AND NOT IOS)
+  install(TARGETS onnxifi_wrapper
+    EXPORT ONNXTargets DESTINATION lib)
+endif()
+
+if(ONNX_BUILD_TESTS)
+  include(${ONNX_ROOT}/cmake/unittest.cmake)
+endif()
+
+include(cmake/summary.cmake)
+onnx_print_configuration_summary()
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index d420997..a4fe9e0 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -3,6 +3,9 @@ option(LINK_STATIC_LIBGCC "Link static libgcc to libmenoh" OFF)
 option(LINK_STATIC_LIBSTDCXX "Link static libstdc++ to libmenoh" OFF)
 
 # Note: The libraries can be static (.a) or shared (.so)
+if(NOT DEFINED PROTOBUF_INCLUDE_DIRS)
+    message(FATAL_ERROR "PROTOBUF_INCLUDE_DIRS is not found")
+endif()
 if(NOT DEFINED MKLDNN_LIBRARIES)
     message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
 endif()
@@ -11,7 +14,9 @@ file(GLOB_RECURSE SOURCES "." "*.cpp")
 
 # Create a object library for generating shared library
 add_library(menoh_objlib OBJECT ${SOURCES})
+
 add_dependencies(menoh_objlib gen_onnx_proto) # custom target defined in onnx
+target_include_directories(menoh_objlib PUBLIC $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
 
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f118d7f..96c18ff 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -25,6 +25,8 @@ add_executable(menoh_test
     #vgg16.cpp
 )
 
+target_include_directories(menoh_test PUBLIC $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
+
 if(LINK_STATIC_LIBPROTOBUF)
     target_link_libraries(menoh_test gtest_main menoh_test_target)
 else()

From 7ce597e4232066bd511efa703c851fe2fce54921 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 3 Oct 2018 15:11:50 +0900
Subject: [PATCH 180/321] add EXCLUDE_FROM_ALL to external projects

---
 CMakeLists.txt      | 2 +-
 test/CMakeLists.txt | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6cce354..6aa884e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -79,7 +79,7 @@ configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/
 
 # TODO: enable the following option when it is ready for migrating to onnx-ml
 #set(ONNX_ML 1)
-add_subdirectory(external/onnx) # Note: BUILD_SHARED_LIBS must be OFF in this place
+add_subdirectory(external/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
 include_directories("${ONNX_INCLUDE_DIRS}")
 
 # Setup MKLDNN
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 96c18ff..866092c 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -4,7 +4,7 @@ enable_testing()
 set(GTEST_DIR "lib/googletest")
 execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 message(STATUS "Adding ${GTEST_DIR}")
-add_subdirectory(${GTEST_DIR})
+add_subdirectory(${GTEST_DIR} EXCLUDE_FROM_ALL)
 
 # filesystem setup
 set(FILESYSTEM_DIR "lib/filesystem")

From 9d91a14f3c24d9d9333d7f2bcfb9fba327b20842 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 3 Oct 2018 15:16:08 +0900
Subject: [PATCH 181/321] add ignore=dirty option to external/onnx

---
 .gitmodules | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.gitmodules b/.gitmodules
index 17edb59..056710b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,7 @@
 [submodule "external/onnx"]
 	path = external/onnx
-	url = https://github.com/onnx/onnx
+	url = https://github.com/onnx/onnx.git
+        ignore = dirty
 [submodule "test/lib/googletest"]
 	path = test/lib/googletest
 	url = https://github.com/google/googletest.git

From 6a0fb845f599a282fc3d0b2cc9ed242d639313f0 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Wed, 3 Oct 2018 17:54:37 +0900
Subject: [PATCH 182/321] update BUILDING.md

---
 BUILDING.md | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index a308f45..19d8c63 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -53,10 +53,9 @@ Download and unzip https://github.com/protocolbuffers/protobuf/releases/download
 
 ```
 cd protobuf-3.6.1/cmake
-mdir build
+mkdir build
 cd build
 cmake .. -G "Visual Studio 14" -A x64 -Dprotobuf_MSVC_STATIC_RUNTIME=OFF -Dprotobuf_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
-cmake --build . --config Debug --target install
 cmake --build . --config Release --target install
 cd ../../..
 ```
@@ -67,10 +66,9 @@ git clone https://github.com/intel/mkl-dnn.git
 cd mkl-dnn/scripts
 .\prepare_mkl.bat
 cd ..
-mdir build
+mkdir build
 cd build
 cmake .. -G "Visual Studio 14 Win64"  -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir)
-cmake --build . --config Debug --target install
 cmake --build . --config Release --target install
 cd ../..
 ```
@@ -177,10 +175,9 @@ Please replace `(CMake_Install_Dir)` in the following with your working director
 ```
 git clone https://github.com/pfnet-research/menoh.git
 cd menoh
-mdir build
+mkdir build
 cd build
-cmake .. -G "Visual Studio 14 Win64" -DCMAKE_PREFIX_PATH=CMake_Install_Dir) -DCMAKE_INSTALL_PREFIX=CMake_Install_Dir) -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DENABLE_TOOL=OFF
-cmake --build . --config Debug --target install
+cmake .. -G "Visual Studio 14 Win64" -DCMAKE_PREFIX_PATH=(CMake_Install_Dir) -DCMAKE_INSTALL_PREFIX=(CMake_Install_Dir) -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF
 cmake --build . --config Release --target install
 ```
 

From ef8a0431c96714689742d4ec152921a2c5907739 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 4 Oct 2018 15:29:37 +0900
Subject: [PATCH 183/321] issue log when error occured on mkldnn context

---
 .../backend/mkldnn/mkldnn_context.cpp                        | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index dbadc61..c4f0d57 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -138,7 +138,10 @@ namespace menoh_impl {
                           factory.operator()(current_index, node_list,
                                              input_list, required_output_table,
                                              engine_);
-                    } catch(...) { break; }
+                    } catch(std::exception const& e) {
+                        *logger << e.what() << std::endl;
+                        break;
+                    }
 
                     primitive_list.insert(primitive_list.end(),
                                           new_primitive_list.begin(),

From e0599a94b49c904c19a84c922ee258946299ac5a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 4 Oct 2018 17:25:02 +0900
Subject: [PATCH 184/321] fix shape inference for 4d input given to Gemm

---
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 5913d0a..2d45bc5 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -74,6 +74,7 @@ def main():
  */
 #include <algorithm>
 #include <cassert>
+#include <numeric> // for accumulate
 #include <string>
 #include <unordered_map>
 
@@ -255,6 +256,11 @@ def main():
             ("transB", "int", "0"),
         ], '''
 auto a_dims = dims_of(input(0));
+if(ndims_of(input(0)) != 2) {
+    int feature_size = std::accumulate(
+        a_dims.begin()+1, a_dims.end(), 1, std::multiplies<int>());
+    a_dims = ints({a_dims.at(0), feature_size});
+}
 assert(a_dims.size() == 2);
 if(transA) {
     std::swap(a_dims.at(0), a_dims.at(1));

From 3c99ed67dbb757e417a45603c99360bae010d8dd Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 4 Oct 2018 17:31:06 +0900
Subject: [PATCH 185/321] remove invalid dimension checking

---
 .../backend/mkldnn/mkldnn_context.cpp                  | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index c4f0d57..6cfa2e3 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -69,14 +69,6 @@ namespace menoh_impl {
                                                                      table) {
                                     auto found = table.find(input_name);
                                     if(found != table.end()) {
-                                        if(found->second.dims().size() != 2 &&
-                                           found->second.dims().size() != 4) {
-                                            throw unsupported_operator(
-                                              node.op_type +
-                                              " takes input which has ndims: " +
-                                              std::to_string(
-                                                found->second.dims().size()));
-                                        }
                                         input_list.push_back(found->second);
                                         return true;
                                     }
@@ -117,8 +109,6 @@ namespace menoh_impl {
                                                              // context to array
                                         array arr;
                                         std::tie(copy_proc, arr) = *found;
-                                        assert(arr.dims().size() == 2 ||
-                                               arr.dims().size() == 4);
                                         new_copy_procedure_list.push_back(
                                           copy_proc);
                                         input_list.push_back(arr);

From 3e1ac6764e884fdb96b7a26d8f265a2afa030aec Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 4 Oct 2018 17:31:21 +0900
Subject: [PATCH 186/321] generate shape_inference

---
 menoh/attribute_completion_and_shape_inference.hpp | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index dc20fd3..ba5588c 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -7,6 +7,7 @@
  */
 #include <algorithm>
 #include <cassert>
+#include <numeric> // for accumulate
 #include <string>
 #include <unordered_map>
 
@@ -561,6 +562,11 @@ auto transB = get<int>(node.attribute_table.at("transB"));
 
         
 auto a_dims = dims_of(input(0));
+if(ndims_of(input(0)) != 2) {
+    int feature_size = std::accumulate(
+        a_dims.begin()+1, a_dims.end(), 1, std::multiplies<int>());
+    a_dims = ints({a_dims.at(0), feature_size});
+}
 assert(a_dims.size() == 2);
 if(transA) {
     std::swap(a_dims.at(0), a_dims.at(1));

From c1573ed1084f4a6be12921b3e0766e9fbdf50ab7 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Thu, 4 Oct 2018 19:41:30 +0900
Subject: [PATCH 187/321] fix some environment specific bugs

---
 external/cmdline.h  | 6 +++++-
 test/CMakeLists.txt | 6 ++++++
 test/lib/googletest | 2 +-
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/external/cmdline.h b/external/cmdline.h
index f498b66..f6b3b9b 100644
--- a/external/cmdline.h
+++ b/external/cmdline.h
@@ -39,8 +39,12 @@
 
 #ifdef _MSC_VER
 #define NOMINMAX
-#include <DbgHelp.h>
+/*
+  You must include Windows.h before DbgHelp.h.
+  See https://stackoverflow.com/a/43283926/1014818 for more details.
+*/
 #include <Windows.h>
+#include <DbgHelp.h>
 #else
 #include <cxxabi.h>
 #endif
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 866092c..6224acb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -3,7 +3,13 @@ enable_testing()
 # GTest setup
 set(GTEST_DIR "lib/googletest")
 execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
 message(STATUS "Adding ${GTEST_DIR}")
+
+# Prevent overriding the parent project's compiler/linker settings on Windows
+# See https://github.com/google/googletest/blob/master/googletest/README.md#visual-studio-dynamic-vs-static-runtimes
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+
 add_subdirectory(${GTEST_DIR} EXCLUDE_FROM_ALL)
 
 # filesystem setup
diff --git a/test/lib/googletest b/test/lib/googletest
index ba96d0b..2fe3bd9 160000
--- a/test/lib/googletest
+++ b/test/lib/googletest
@@ -1 +1 @@
-Subproject commit ba96d0b1161f540656efdaed035b3c062b60e006
+Subproject commit 2fe3bd994b3189899d93f1d5a881e725e046fdc2

From 38f65a8433e11edef039ecba47404264ed96936d Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 5 Oct 2018 14:02:13 +0900
Subject: [PATCH 188/321] Revert "add cross building support for protobuf"

This reverts commit 08289fcf5b99e470e11eb09669ec13a57a4f811c.
---
 scripts/build-boost.sh    | 120 --------------------------------------
 scripts/build-menoh.sh    |   4 +-
 scripts/build-protobuf.sh |  18 +-----
 scripts/install-boost.sh  |  35 -----------
 4 files changed, 3 insertions(+), 174 deletions(-)
 delete mode 100644 scripts/build-boost.sh
 delete mode 100644 scripts/install-boost.sh

diff --git a/scripts/build-boost.sh b/scripts/build-boost.sh
deleted file mode 100644
index 183247f..0000000
--- a/scripts/build-boost.sh
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/bin/bash -e
-
-# retrieve arguments
-while [[ $# != 0 ]]; do
-    case $1 in
-        --)
-            shift
-            break
-            ;;
-        --version)
-            readonly ARG_VERSION="$2"
-            shift 2
-            ;;
-        --download-dir)
-            readonly ARG_DOWNLOAD_DIR="$2"
-            shift 2
-            ;;
-        --extract-dir)
-            readonly ARG_EXTRACT_DIR="$2"
-            shift 2
-            ;;
-        --build-dir)
-            readonly ARG_BUILD_DIR="$2"
-            shift 2
-            ;;
-        --stage-dir)
-            readonly ARG_STAGE_DIR="$2"
-            shift 2
-            ;;
-        --install-dir)
-            readonly ARG_INSTALL_DIR="$2"
-            shift 2
-            ;;
-        --toolset)
-            readonly ARG_TOOLSET="$2"
-            shift 2
-            ;;
-        --cxx)
-            readonly ARG_CXX_CMD="$2"
-            shift 2
-            ;;
-        --parallel)
-            readonly ARG_PARALLEL="$2"
-            shift 2
-            ;;
-        -*)
-            echo Unknown option \"$1\" 1>&2
-            exit
-            ;;
-        *)
-            break
-            ;;
-    esac
-done
-
-# validate the arguments
-test -n "${ARG_DOWNLOAD_DIR}" || { echo "--download-dir is not specified" 1>&2; exit 1; }
-test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; exit 1; }
-
-# options that have default value
-test -n "${ARG_VERSION}" || readonly ARG_VERSION=1.64.0
-
-readonly LIBRARY_NAME=boost_$(echo ${ARG_VERSION} | sed -e 's/\./_/g') # e.g. boost_1_64_0
-readonly SOURCE_DIR="${ARG_EXTRACT_DIR}/${LIBRARY_NAME}"
-
-test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}/build"
-test -n "${ARG_STAGE_DIR}" || readonly ARG_STAGE_DIR="${SOURCE_DIR}/stage"
-test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
-test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
-
-# options for cross compiling
-if [ -n "${ARG_TOOLSET}" ]; then # e.g. gcc-arm
-    # requires a location of g++ command
-    test -n "${ARG_CXX_CMD}" || { echo "--cxx is not specified" 1>&2; exit 1; }
-
-    readonly USER_CONFIG_JAM="using $(echo ${ARG_TOOLSET} | sed -e 's/-/ : /') : ${ARG_CXX_CMD} ;"
-    readonly OPT_TOOLSET=toolset=${ARG_TOOLSET}
-fi
-
-# download (if it isn't cached)
-if [ ! -e "${SOURCE_DIR}/INSTALL" ]; then
-    echo -e "\e[33;1mDownloading libboost\e[0m"
-
-    [ -d "${ARG_DOWNLOAD_DIR}" ] || mkdir -p "${ARG_DOWNLOAD_DIR}"
-
-    cd "${ARG_DOWNLOAD_DIR}"
-    if [ ! -e "${LIBRARY_NAME}.tar.gz" ]; then
-        download_dir="https://dl.bintray.com/boostorg/release/${ARG_VERSION}/source/${LIBRARY_NAME}.tar.gz"
-        curl -LO ${download_dir} # wget doesn't work for bintray with 403 errpr
-    fi
-    tar -zxf ${LIBRARY_NAME}.tar.gz -C "${ARG_EXTRACT_DIR}"
-
-    echo -e "\e[32;1mlibboost was successfully downloaded.\e[0m"
-else
-    echo -e "\e[32;1mlibboost has been downloaded.\e[0m"
-fi
-
-# build (if it isn't cached)
-if [ ! -e "${ARG_STAGE_DIR}/lib/libboost_system.a" ]; then
-    echo -e "\e[33;1mBuilding libprotobuf\e[0m"
-
-    cd "${SOURCE_DIR}"
-
-    # bootstrap
-    ./bootstrap.sh --prefix="${ARG_INSTALL_DIR}"
-
-    # configure options
-    if [ -n "${USER_CONFIG_JAM}" ]; then
-        echo "${USER_CONFIG_JAM}" > ${SOURCE_DIR}/user_config.jam
-        readonly OPT_USER_CONFIG_JAM=--user-config=${SOURCE_DIR}/user_config.jam
-    fi
-    echo "-j${ARG_PARALLEL} ${OPT_TOOLSET} ${OPT_USER_CONFIG_JAM} link=static cflags=-fPIC cxxflags=-fPIC --with-filesystem --with-test --with-log --with-program_options --build-dir=${ARG_BUILD_DIR} --stage-dir=${ARG_STAGE_DIR}" > b2_opts.txt
-
-    # run a build
-    ./b2 stage $(cat b2_opts.txt)
-
-    echo -e "\e[32;1mlibboost was successfully built.\e[0m"
-else
-    echo -e "\e[32;1mlibboost has been built.\e[0m"
-fi
diff --git a/scripts/build-menoh.sh b/scripts/build-menoh.sh
index 5184c4e..5740377 100755
--- a/scripts/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -63,8 +63,8 @@ test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${ARG_SOURCE_DIR}/build"
 test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 
 if [ -n "${ARG_MKLDNN_DIR}" ]; then
-    readonly OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
-    readonly OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
+    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
+    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 
 test -n "${ARG_PYTHON_EXECUTABLE}" || readonly ARG_PYTHON_EXECUTABLE=python
diff --git a/scripts/build-protobuf.sh b/scripts/build-protobuf.sh
index f1fdb34..f694b8b 100755
--- a/scripts/build-protobuf.sh
+++ b/scripts/build-protobuf.sh
@@ -27,14 +27,6 @@ while [[ $# != 0 ]]; do
             readonly ARG_INSTALL_DIR="$2"
             shift 2
             ;;
-        --host)
-            readonly ARG_HOST="$2"
-            shift 2
-            ;;
-        --with-protoc)
-            readonly ARG_WITH_PROTOC="$2"
-            shift 2
-            ;;
         --parallel)
             readonly ARG_PARALLEL="$2"
             shift 2
@@ -63,14 +55,6 @@ test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}"
 test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 test -n "${ARG_PARALLEL}" || readonly ARG_PARALLEL=1
 
-# options for cross compiling
-if [ -n "${ARG_HOST}" ]; then
-    readonly OPT_HOST=--host=${ARG_HOST}
-fi
-if [ -n "${ARG_WITH_PROTOC}" ]; then
-    readonly OPT_WITH_PROTOC=--with-protoc=${ARG_WITH_PROTOC}
-fi
-
 # download (if it isn't cached)
 if [ ! -e "${SOURCE_DIR}/LICENSE" ]; then
     echo -e "\e[33;1mDownloading libprotobuf\e[0m"
@@ -96,7 +80,7 @@ if [ ! -e "${ARG_BUILD_DIR}/src/libprotobuf.la" ]; then
     [ -d "${ARG_BUILD_DIR}" ] || mkdir -p "${ARG_BUILD_DIR}"
 
     cd "${ARG_BUILD_DIR}"
-    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS="-g -O2 -fPIC" CXXFLAGS="-g -O2 -fPIC" "${OPT_HOST}" "${OPT_WITH_PROTOC}"
+    "${SOURCE_DIR}/configure" --prefix="${ARG_INSTALL_DIR}" CFLAGS="-g -O2 -fPIC" CXXFLAGS="-g -O2 -fPIC"
     make -j${ARG_PARALLEL}
 
     echo -e "\e[32;1mlibprotobuf was successfully built.\e[0m"
diff --git a/scripts/install-boost.sh b/scripts/install-boost.sh
deleted file mode 100644
index fdb3a13..0000000
--- a/scripts/install-boost.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash -e
-
-# retrieve arguments
-while [[ $# != 0 ]]; do
-    case $1 in
-        --)
-            shift
-            break
-            ;;
-        --source-dir)
-            readonly ARG_SOURCE_DIR="$2"
-            shift 2
-            ;;
-        --dest-dir)
-            readonly ARG_DESTDIR="$2"
-            shift 2
-            ;;
-        -*)
-            echo Unknown option \"$1\" 1>&2
-            exit
-            ;;
-        *)
-            break
-            ;;
-    esac
-done
-
-# validate the arguments
-test -n "${ARG_SOURCE_DIR}" || { echo "--source-dir is not specified" 1>&2; exit 1; }
-
-# install (always)
-echo -e "\e[33;1mInstalling libboost\e[0m"
-
-cd "${ARG_SOURCE_DIR}"
-./b2 install $(cat ${ARG_SOURCE_DIR}/b2_opts.txt)

From 8e8e487d97c8056699ba8f2f149606a2565b671e Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 5 Oct 2018 14:06:38 +0900
Subject: [PATCH 189/321] fix an indent

---
 .gitmodules | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitmodules b/.gitmodules
index 056710b..19ec233 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,7 @@
 [submodule "external/onnx"]
 	path = external/onnx
 	url = https://github.com/onnx/onnx.git
-        ignore = dirty
+	ignore = dirty
 [submodule "test/lib/googletest"]
 	path = test/lib/googletest
 	url = https://github.com/google/googletest.git

From 2d0d5f42ae189f46ddc1b69c31ce8103767b742c Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 5 Oct 2018 14:59:50 +0900
Subject: [PATCH 190/321] add python to prerequisites

---
 BUILDING.md | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/BUILDING.md b/BUILDING.md
index 19d8c63..492fb45 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -5,18 +5,25 @@ You need to install [prerequisites](#prerequisites) for your platform before [bu
 To build Menoh, you require the following toolchains:
 
 Unix:
-- CMake 3.1 or later
 - GCC 4.9 or later
+- CMake 3.1 or later
+- Python 2.7 or later
 
 macOS (OSX):
 - XCode
 - [Homebrew](https://brew.sh/)
+- CMake 3.1 or later
+- Python 2.7 or later
 
 Windows:
 - Visual Studio 2015
+- CMake 3.1 or later
+- Python 2.7 or later
 
 Windows (MINGW):
 - [MSYS2](http://www.msys2.org/)
+- CMake 3.1 or later
+- Python 2.7 or later
 
 You also need to install the dependent libraries on your system:
 

From 55aa2620a2c152ff7ff49dbfb77c6f6e394bf659 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 11:29:25 +0900
Subject: [PATCH 191/321] add maybe_unused (static_cast<void>()) workaround for
 attributes

---
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 2d45bc5..4df84fd 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -38,6 +38,7 @@ def make_completion_code(op_name,
 
         attribute_definition = '''
 auto {attr_name} = get<{attr_type}>(node.attribute_table.at("{attr_name}"));
+static_cast<void>({attr_name}); // maybe unused
 '''.format(attr_name=attr_name, attr_type=attr_type)
         attribute_definition_list.append(attribute_definition)
     # end for

From 7a0745736580931e3faaee99ed95c97e39bf5308 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 11:33:05 +0900
Subject: [PATCH 192/321] fix comparison of signed and unsigned int

---
 ...n_attribute_completion_and_shape_inference_hpp.py | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 4df84fd..8bbeed7 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -125,10 +125,10 @@ def main():
         auto graph = make_graph(model_data.node_list); // FIXME reorder nodes
         model_data.node_list = graph.node_list();
         for(auto& node : model_data.node_list) {{
-            auto input = [&node](int i){{
+            auto input = [&node](auto i){{
                 return node.input_name_list.at(i);
             }};
-            auto output = [&node](int i){{
+            auto output = [&node](auto i){{
                 return node.output_name_list.at(i);
             }};
             {code}
@@ -168,7 +168,7 @@ def main():
             ("axis", "int", None),
         ], '''
 auto output_dims = dims_of(input(0));
-for(int i = 1; i < node.input_name_list.size(); ++i) {
+for(unsigned int i = 1; i < node.input_name_list.size(); ++i) {
     // TODO dim check
     output_dims.at(axis) += dims_of(input(i)).at(axis);
 }
@@ -231,7 +231,7 @@ def main():
         ints input_size(input_profile.dims().begin()+2,
                         input_profile.dims().end());
 
-        for(int i = 0; i < kernel_ndims; ++i) {
+        for(unsigned int i = 0; i < kernel_ndims; ++i) {
             auto total_padding = strides[i] * (input_size[i] - 1)
                 + output_padding[i] + kernel_shape[i] - output_shape[i];
             pads[i] = total_padding - (total_padding/2);
@@ -308,13 +308,13 @@ def main():
         ], '''
 auto input_dims = dims_of(input(0));
 ints output_dims(input_dims.size());
-for(int i = 0; i < input_dims.size(); ++i) {
+for(unsigned int i = 0; i < input_dims.size(); ++i) {
     output_dims.at(i) = input_dims.at(perm.at(i));
 }
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 ''', preprocess="""
 ints perm(ndims_of(input(0)));
-for(int i = 0; i < perm.size(); ++i) {{
+for(unsigned int i = 0; i < perm.size(); ++i) {{
     perm.at(i) = perm.size()-i-1;
 }}
 """))

From 44a74db0b2ba7d28744ce659fa644b905c3e60d2 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 13:27:39 +0900
Subject: [PATCH 193/321] stop to use deprecated API in examples

---
 example/general_cnn_example_in_cpp.cpp | 2 +-
 example/vgg16_example_in_c.c           | 8 ++++----
 example/vgg16_example_in_cpp.cpp       | 4 ++--
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index 2148582..fdc320b 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -114,7 +114,7 @@ int main(int argc, char** argv) {
     menoh::variable_profile_table_builder vpt_builder;
     vpt_builder.add_input_profile(conv1_1_in_name, menoh::dtype_t::float_,
                                   {batch_size, channel_num, height, width});
-    vpt_builder.add_output_profile(softmax_out_name, menoh::dtype_t::float_);
+    vpt_builder.add_output_name(softmax_out_name);
 
     // Build variable_profile_table and get variable dims (if needed)
     auto vpt = vpt_builder.build_variable_profile_table(model_data);
diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index 762acec..423b4fd 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -33,10 +33,10 @@ int main() {
     ERROR_CHECK(menoh_variable_profile_table_builder_add_input_profile(
       vpt_builder, conv1_1_in_name, menoh_dtype_float, 4, input_dims));
 
-    ERROR_CHECK(menoh_variable_profile_table_builder_add_output_profile(
-      vpt_builder, fc6_out_name, menoh_dtype_float));
-    ERROR_CHECK(menoh_variable_profile_table_builder_add_output_profile(
-      vpt_builder, softmax_out_name, menoh_dtype_float));
+    ERROR_CHECK(menoh_variable_profile_table_builder_add_output_name(
+      vpt_builder, fc6_out_name));
+    ERROR_CHECK(menoh_variable_profile_table_builder_add_output_name(
+      vpt_builder, softmax_out_name));
 
     menoh_variable_profile_table_handle variable_profile_table;
     ERROR_CHECK(menoh_build_variable_profile_table(vpt_builder, model_data,
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index 3fad1c7..3d39ef9 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -110,8 +110,8 @@ int main(int argc, char** argv) {
     menoh::variable_profile_table_builder vpt_builder;
     vpt_builder.add_input_profile(conv1_1_in_name, menoh::dtype_t::float_,
                                   {batch_size, channel_num, height, width});
-    vpt_builder.add_output_profile(fc6_out_name, menoh::dtype_t::float_);
-    vpt_builder.add_output_profile(softmax_out_name, menoh::dtype_t::float_);
+    vpt_builder.add_output_name(fc6_out_name);
+    vpt_builder.add_output_name(softmax_out_name);
 
     // Build variable_profile_table and get variable dims (if needed)
     auto vpt = vpt_builder.build_variable_profile_table(model_data);

From 29cab9b7ed4fbc668e4b4011adf519232eaf523a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 13:41:45 +0900
Subject: [PATCH 194/321] remove unused parameter

---
 menoh/menoh.cpp                                                 | 2 +-
 .../backend/generic/operator/relu.hpp                           | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index f6193eb..d46467e 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -304,7 +304,7 @@ menoh_error_code menoh_variable_profile_table_builder_add_output_name(
  */
 menoh_error_code menoh_variable_profile_table_builder_add_output_profile(
   menoh_variable_profile_table_builder_handle builder, const char* name,
-  menoh_dtype dtype) {
+  menoh_dtype) {
     return menoh_variable_profile_table_builder_add_output_name(builder, name);
 }
 
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
index 98e258a..b5d278a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
@@ -7,7 +7,7 @@
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace generic_backend {
-            inline procedure make_relu(node const& node,
+            inline procedure make_relu(node const&,
                                        std::vector<array> const& input_list,
                                        std::vector<array> const& output_list) {
                 assert(input_list.size() == 1);

From 34638d1ad189b357d5d7e41505efd6ec248ff0ee Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 13:43:51 +0900
Subject: [PATCH 195/321] remove comparison of signed and unsigned int

---
 .../backend/generic/generic_context.cpp                    | 7 +++++--
 .../backend/mkldnn/mkldnn_context.cpp                      | 3 ++-
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 81a8210..78c3603 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -30,7 +30,8 @@ namespace menoh_impl {
 
                 std::vector<procedure> new_op_proc_list;
 
-                for(; current_index < node_list.size(); ++current_index) {
+                for(; current_index < static_cast<int>(node_list.size());
+                    ++current_index) {
                     auto const& node = node_list.at(current_index);
                     std::vector<array> input_list;
                     std::vector<procedure> new_copy_procedure_list;
@@ -131,7 +132,9 @@ namespace menoh_impl {
                       std::make_move_iterator(new_copy_procedure_list.end()));
 
                     assert(node.output_name_list.size() == output_list.size());
-                    for(int i = 0; i < node.output_name_list.size(); ++i) {
+                    for(int i = 0;
+                        i < static_cast<int>(node.output_name_list.size());
+                        ++i) {
                         variable_table_.emplace(node.output_name_list.at(i),
                                                 output_list.at(i));
                     }
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 6cfa2e3..d88a00c 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -35,7 +35,8 @@ namespace menoh_impl {
 
                 std::vector<mkldnn::primitive> primitive_list;
 
-                for(; current_index < node_list.size(); ++current_index) {
+                for(; current_index < static_cast<int>(node_list.size());
+                    ++current_index) {
                     auto const& node = node_list.at(current_index);
                     std::vector<array> input_list;
                     std::vector<procedure> new_copy_procedure_list;

From 6c9c64c83ad888d50dd8b6ab3d06cc151d74fdad Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 3 Oct 2018 13:44:21 +0900
Subject: [PATCH 196/321] generate attribute_completion_and_shape_inference

---
 ...tribute_completion_and_shape_inference.hpp | 46 ++++++++++++++++---
 1 file changed, 40 insertions(+), 6 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index ba5588c..ec1f2b1 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -57,10 +57,10 @@ namespace menoh_impl {
         auto graph = make_graph(model_data.node_list); // FIXME reorder nodes
         model_data.node_list = graph.node_list();
         for(auto& node : model_data.node_list) {
-            auto input = [&node](int i){
+            auto input = [&node](auto i){
                 return node.input_name_list.at(i);
             };
-            auto output = [&node](int i){
+            auto output = [&node](auto i){
                 return node.output_name_list.at(i);
             };
             
@@ -147,15 +147,19 @@ node.attribute_table.emplace(
     {
         
 auto count_include_pad = get<int>(node.attribute_table.at("count_include_pad"));
+static_cast<void>(count_include_pad); // maybe unused
 
 
 auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+static_cast<void>(kernel_shape); // maybe unused
 
 
 auto pads = get<ints>(node.attribute_table.at("pads"));
+static_cast<void>(pads); // maybe unused
 
 
 auto strides = get<ints>(node.attribute_table.at("strides"));
+static_cast<void>(strides); // maybe unused
 
         
 add_variable_to_table(output(0), dtype_of(input(0)),
@@ -207,12 +211,15 @@ node.attribute_table.emplace(
     {
         
 auto epsilon = get<float>(node.attribute_table.at("epsilon"));
+static_cast<void>(epsilon); // maybe unused
 
 
 auto momentum = get<float>(node.attribute_table.at("momentum"));
+static_cast<void>(momentum); // maybe unused
 
 
 auto spatial = get<int>(node.attribute_table.at("spatial"));
+static_cast<void>(spatial); // maybe unused
 
         
 assert(node.input_name_list.size() > 0);
@@ -240,10 +247,11 @@ assert(!"attribute not found: axis");
     {
         
 auto axis = get<int>(node.attribute_table.at("axis"));
+static_cast<void>(axis); // maybe unused
 
         
 auto output_dims = dims_of(input(0));
-for(int i = 1; i < node.input_name_list.size(); ++i) {
+for(unsigned int i = 1; i < node.input_name_list.size(); ++i) {
     // TODO dim check
     output_dims.at(axis) += dims_of(input(i)).at(axis);
 }
@@ -319,18 +327,23 @@ node.attribute_table.emplace(
     {
         
 auto dilations = get<ints>(node.attribute_table.at("dilations"));
+static_cast<void>(dilations); // maybe unused
 
 
 auto group = get<int>(node.attribute_table.at("group"));
+static_cast<void>(group); // maybe unused
 
 
 auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+static_cast<void>(kernel_shape); // maybe unused
 
 
 auto pads = get<ints>(node.attribute_table.at("pads"));
+static_cast<void>(pads); // maybe unused
 
 
 auto strides = get<ints>(node.attribute_table.at("strides"));
+static_cast<void>(strides); // maybe unused
 
         
 add_variable_to_table(output(0), dtype_of(input(0)),
@@ -418,7 +431,7 @@ node.attribute_table.emplace(
         ints input_size(input_profile.dims().begin()+2,
                         input_profile.dims().end());
 
-        for(int i = 0; i < kernel_ndims; ++i) {
+        for(unsigned int i = 0; i < kernel_ndims; ++i) {
             auto total_padding = strides[i] * (input_size[i] - 1)
                 + output_padding[i] + kernel_shape[i] - output_shape[i];
             pads[i] = total_padding - (total_padding/2);
@@ -432,18 +445,23 @@ node.attribute_table.emplace(
     {
         
 auto dilations = get<ints>(node.attribute_table.at("dilations"));
+static_cast<void>(dilations); // maybe unused
 
 
 auto group = get<int>(node.attribute_table.at("group"));
+static_cast<void>(group); // maybe unused
 
 
 auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+static_cast<void>(kernel_shape); // maybe unused
 
 
 auto output_padding = get<ints>(node.attribute_table.at("output_padding"));
+static_cast<void>(output_padding); // maybe unused
 
 
 auto strides = get<ints>(node.attribute_table.at("strides"));
+static_cast<void>(strides); // maybe unused
 
         
 add_variable_to_table(output(0), dtype_of(input(0)),
@@ -473,6 +491,7 @@ node.attribute_table.emplace(
     {
         
 auto alpha = get<float>(node.attribute_table.at("alpha"));
+static_cast<void>(alpha); // maybe unused
 
         
 assert(node.input_name_list.size() > 0);
@@ -550,15 +569,19 @@ node.attribute_table.emplace(
     {
         
 auto alpha = get<float>(node.attribute_table.at("alpha"));
+static_cast<void>(alpha); // maybe unused
 
 
 auto beta = get<float>(node.attribute_table.at("beta"));
+static_cast<void>(beta); // maybe unused
 
 
 auto transA = get<int>(node.attribute_table.at("transA"));
+static_cast<void>(transA); // maybe unused
 
 
 auto transB = get<int>(node.attribute_table.at("transB"));
+static_cast<void>(transB); // maybe unused
 
         
 auto a_dims = dims_of(input(0));
@@ -603,6 +626,7 @@ node.attribute_table.emplace(
     {
         
 auto alpha = get<float>(node.attribute_table.at("alpha"));
+static_cast<void>(alpha); // maybe unused
 
         
 assert(node.input_name_list.size() > 0);
@@ -663,15 +687,19 @@ assert(!"attribute not found: size");
     {
         
 auto alpha = get<float>(node.attribute_table.at("alpha"));
+static_cast<void>(alpha); // maybe unused
 
 
 auto beta = get<float>(node.attribute_table.at("beta"));
+static_cast<void>(beta); // maybe unused
 
 
 auto bias = get<float>(node.attribute_table.at("bias"));
+static_cast<void>(bias); // maybe unused
 
 
 auto size = get<float>(node.attribute_table.at("size"));
+static_cast<void>(size); // maybe unused
 
         
 assert(node.input_name_list.size() > 0);
@@ -732,15 +760,19 @@ node.attribute_table.emplace(
     {
         
 auto kernel_shape = get<ints>(node.attribute_table.at("kernel_shape"));
+static_cast<void>(kernel_shape); // maybe unused
 
 
 auto pads = get<ints>(node.attribute_table.at("pads"));
+static_cast<void>(pads); // maybe unused
 
 
 auto storage_order = get<int>(node.attribute_table.at("storage_order"));
+static_cast<void>(storage_order); // maybe unused
 
 
 auto strides = get<ints>(node.attribute_table.at("strides"));
+static_cast<void>(strides); // maybe unused
 
         
 add_variable_to_table(output(0), dtype_of(input(0)),
@@ -786,6 +818,7 @@ node.attribute_table.emplace(
     {
         
 auto axis = get<int>(node.attribute_table.at("axis"));
+static_cast<void>(axis); // maybe unused
 
         
 assert(node.input_name_list.size() > 0);
@@ -848,7 +881,7 @@ else
 if(node.op_type == "Transpose") {
     
 ints perm(ndims_of(input(0)));
-for(int i = 0; i < perm.size(); ++i) {{
+for(unsigned int i = 0; i < perm.size(); ++i) {{
     perm.at(i) = perm.size()-i-1;
 }}
 
@@ -867,11 +900,12 @@ node.attribute_table.emplace(
     {
         
 auto perm = get<ints>(node.attribute_table.at("perm"));
+static_cast<void>(perm); // maybe unused
 
         
 auto input_dims = dims_of(input(0));
 ints output_dims(input_dims.size());
-for(int i = 0; i < input_dims.size(); ++i) {
+for(unsigned int i = 0; i < input_dims.size(); ++i) {
     output_dims.at(i) = input_dims.at(perm.at(i));
 }
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);

From 4d5ba1863e502e0b23b7e81661a9432b633f1278 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 9 Oct 2018 14:36:47 +0900
Subject: [PATCH 197/321] fix

---
 .../backend/mkldnn/mkldnn_context.cpp                       | 1 +
 test/backend.hpp                                            | 6 +++---
 test/common.hpp                                             | 2 +-
 test/mkldnn_with_generic_fallback_backend.cpp               | 1 -
 test/operator.cpp                                           | 5 +++--
 5 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index d88a00c..26277c5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -30,6 +30,7 @@ namespace menoh_impl {
                 std::pair<std::string, std::unique_ptr<context>>> const&
                 context_list,
               logger_handle logger) {
+                static_cast<void>(output_profile_table); // maybe unused
                 auto first_node_index = current_index;
                 std::vector<procedure> procedure_list;
 
diff --git a/test/backend.hpp b/test/backend.hpp
index f16c150..64e433c 100644
--- a/test/backend.hpp
+++ b/test/backend.hpp
@@ -91,7 +91,7 @@ namespace menoh {
         menoh::model_data model_data;
         model_data.add_new_node("Add");
         std::vector<std::pair<std::string, std::string>> inputs;
-        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+        for(unsigned int i = 0; i < input_filename_list.size(); ++i) {
             auto const& filename = input_filename_list.at(i);
             inputs.push_back({"input" + std::to_string(i), filename});
         }
@@ -123,7 +123,7 @@ namespace menoh {
         model_data.add_new_node("Concat");
         model_data.add_attribute_int_to_current_node("axis", axis);
         std::vector<std::pair<std::string, std::string>> inputs;
-        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+        for(unsigned int i = 0; i < input_filename_list.size(); ++i) {
             auto const& filename = input_filename_list.at(i);
             inputs.push_back({"input" + std::to_string(i), filename});
         }
@@ -228,7 +228,7 @@ namespace menoh {
         menoh::model_data model_data;
         model_data.add_new_node("Sum");
         std::vector<std::pair<std::string, std::string>> inputs;
-        for(int32_t i = 0; i < input_filename_list.size(); ++i) {
+        for(unsigned int i = 0; i < input_filename_list.size(); ++i) {
             auto const& filename = input_filename_list.at(i);
             inputs.push_back({"input" + std::to_string(i), filename});
         }
diff --git a/test/common.hpp b/test/common.hpp
index 3fb29a8..a8578cf 100644
--- a/test/common.hpp
+++ b/test/common.hpp
@@ -55,7 +55,7 @@ namespace menoh_impl {
             return false;
         }
         auto size = total_size(lhs);
-        for(auto i = 0; i < size; ++i) {
+        for(unsigned int i = 0; i < size; ++i) {
             float l = *(static_cast<float*>(lhs.data()) + i);
             float r = *(static_cast<float*>(rhs.data()) + i);
             if(!(l - eps < r && r < l + eps)) {
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index 58540ce..3815e07 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -109,7 +109,6 @@ namespace menoh {
             std::vector<float> true_output_data;
             std::tie(std::ignore, output_dims, true_output_data) =
               menoh_impl::load_np_array(true_output_filename);
-            dtype_t dtype = dtype_t::float_; // TODO other dtype
             if(output_name == "relu_out") {
                 std::transform(true_output_data.begin(), true_output_data.end(),
                                true_output_data.begin(),
diff --git a/test/operator.cpp b/test/operator.cpp
index bef8ee3..cbeaa89 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -110,7 +110,7 @@ namespace {
                                                   input.dims);
                 }
                 for(auto const& output : true_output_list) {
-                    vpt_builder.add_output_profile(output.name, output.dtype);
+                    vpt_builder.add_output_name(output.name);
                 }
                 auto onnx_model_filename = parent_dir_path / "model.onnx";
                 auto model_data =
@@ -135,9 +135,10 @@ namespace {
                 auto static_cast_to_float_ptr = [](auto p) {
                     return static_cast<float*>(static_cast<void*>(p));
                 };
-                for(int output_index = 0;
+                for(unsigned int output_index = 0;
                     output_index < true_output_list.size(); ++output_index) {
                     auto const& input = input_list.front();
+                    static_cast<void>(input); // maybe unused
                     auto const& output = output_list.at(output_index);
                     auto const& true_output = true_output_list.at(output_index);
                     auto total_size = std::accumulate(true_output.dims.begin(),

From cb6ce696572993d4a826dc776f7f3ec6798a74fa Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 9 Oct 2018 15:54:40 +0900
Subject: [PATCH 198/321] add dimension check for gemm

---
 menoh/attribute_completion_and_shape_inference.hpp          | 6 ++++++
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 6 ++++++
 2 files changed, 12 insertions(+)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index ba5588c..f36ebe6 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -578,6 +578,12 @@ if(transB) {
     std::swap(b_dims.at(0), b_dims.at(1));
 }
 
+if(a_dims.at(1) != b_dims.at(0)) {
+    throw dimension_mismatch(
+        node.op_type, input(0), "trans(A)[1] and trans(B)[0])",
+        std::to_string(a_dims.at(1)), std::to_string(b_dims.at(0)));
+}
+
 auto output_dims = ints({a_dims.at(0), b_dims.at(1)});
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 2d45bc5..1e0368f 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -272,6 +272,12 @@ def main():
     std::swap(b_dims.at(0), b_dims.at(1));
 }
 
+if(a_dims.at(1) != b_dims.at(0)) {
+    throw dimension_mismatch(
+        node.op_type, input(0), "trans(A)[1] and trans(B)[0])",
+        std::to_string(a_dims.at(1)), std::to_string(b_dims.at(0)));
+}
+
 auto output_dims = ints({a_dims.at(0), b_dims.at(1)});
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 '''))

From 765497e943040ca47e5939718428494b09f102f1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 9 Oct 2018 20:00:03 +0900
Subject: [PATCH 199/321] add factory check

---
 .../backend/generic/generic_context.cpp                   | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 78c3603..7fee2d7 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -117,8 +117,12 @@ namespace menoh_impl {
 
                     procedure op_proc;
                     try {
-                        auto factory =
-                          procedure_factory_table_.at(node.op_type);
+                        auto found =
+                          procedure_factory_table_.find(node.op_type);
+                        if(found == procedure_factory_table_.end()) {
+                            throw std::runtime_error("factory not found for: " + node.op_type);
+                        }
+                        auto factory = found->second;
                         op_proc =
                           factory.operator()(node, input_list, output_list);
                     } catch(std::exception const& e) {

From 5109210c31bf47f11ef8b90f7622098f4543ee35 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 9 Oct 2018 20:56:16 +0900
Subject: [PATCH 200/321] update document

---
 docs/Doxyfile         | 6 +++---
 include/menoh/menoh.h | 6 +++++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/docs/Doxyfile b/docs/Doxyfile
index bb2984c..104c1e7 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -2052,7 +2052,7 @@ ENABLE_PREPROCESSING   = YES
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-MACRO_EXPANSION        = NO
+MACRO_EXPANSION        = YES
 
 # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
 # the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -2060,7 +2060,7 @@ MACRO_EXPANSION        = NO
 # The default value is: NO.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-EXPAND_ONLY_PREDEF     = NO
+EXPAND_ONLY_PREDEF     = YES
 
 # If the SEARCH_INCLUDES tag is set to YES, the include files in the
 # INCLUDE_PATH will be searched if a #include is found.
@@ -2092,7 +2092,7 @@ INCLUDE_FILE_PATTERNS  =
 # recursively expanded use the := operator instead of the = operator.
 # This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
 
-PREDEFINED             = 
+PREDEFINED             = "MENOH_DEPRECATED_ATTRIBUTE(x)=\deprecated"
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
 # tag can be used to specify a list of macro names that should be expanded. The
diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index e8375c1..953962f 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -200,6 +200,7 @@ void MENOH_API menoh_delete_variable_profile_table_builder(
 /*! \brief Add input profile
  *
  * Input profile contains name, dtype and dims.
+ * \note Users can free dims buffer after calling this function.
  */
 menoh_error_code MENOH_API
 menoh_variable_profile_table_builder_add_input_profile(
@@ -210,6 +211,7 @@ menoh_variable_profile_table_builder_add_input_profile(
  *
  * Input profile contains name, dtype and dims (num, size). This 2D input is
  * conventional batched 1D inputs.
+ * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_input_profile() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_input_profile() instead")
@@ -223,6 +225,7 @@ menoh_variable_profile_table_builder_add_input_profile_dims_2(
  * Input profile contains name, dtype and dims (num, channel, height, width).
  * This 4D input is conventional batched image inputs. Image input is
  * 3D(channel, height, width).
+ * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_input_profile() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_input_profile() instead")
@@ -240,10 +243,11 @@ menoh_variable_profile_table_builder_add_input_profile_dims_4(
 menoh_error_code MENOH_API menoh_variable_profile_table_builder_add_output_name(
   menoh_variable_profile_table_builder_handle builder, const char* name);
 
-/*! \brief [DEPRECATED] Add output profile
+/*! \brief Add output profile
  *
  * Output profile contains name and dtype. Its dims are calculated automatically
  * when calling of menoh_build_variable_profile_table.
+ * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_output_name() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_output_name() instead. "

From 30a42fa03286fbf699be0ff9d1b00fa88d4fe7cc Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 12 Oct 2018 13:05:43 +0900
Subject: [PATCH 201/321] input_not_found exception and output_not_found
 exception are added

when building vpt, invalid input name causes input_not_found error.
invalid output name causes output_not_found error.
---
 include/menoh/menoh.h                         |  6 +++
 ...tribute_completion_and_shape_inference.hpp |  7 ++-
 menoh/menoh.cpp                               | 44 ++++++++++++++++++-
 ...bute_completion_and_shape_inference_hpp.py |  7 ++-
 4 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index e8375c1..03a1441 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -79,6 +79,8 @@ enum menoh_error_code_constant {
     menoh_error_code_same_named_parameter_already_exist,
     menoh_error_code_same_named_attribute_already_exist,
     menoh_error_code_invalid_backend_config_error,
+    menoh_error_code_input_not_found_error,
+    menoh_error_code_output_not_found_error,
 };
 typedef int32_t menoh_error_code;
 /*! \brief Users can get detailed message about last error.
@@ -264,6 +266,10 @@ typedef struct menoh_variable_profile_table*
   menoh_variable_profile_table_handle;
 
 /*! \brief Factory function for variable_profile_table
+ *
+ * \note this function throws menoh_input_not_found_error when no nodes have given input name.
+ * \note this function throws menoh_output_not_found_error when no nodes have given output name.
+ * \note this function throws menoh_variable_not_found_error when needed variable for model execution does not exist.
  */
 menoh_error_code MENOH_API menoh_build_variable_profile_table(
   const menoh_variable_profile_table_builder_handle builder,
diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 3297ba3..452afd7 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -13,6 +13,7 @@
 
 #include <menoh/array.hpp>
 #include <menoh/model_data.hpp>
+#include <menoh/utility.hpp>
 
 namespace menoh_impl {
     inline auto complete_attribute_and_infer_shape(
@@ -32,8 +33,10 @@ namespace menoh_impl {
                     p.first,
                     array_profile(p.second.dtype(), p.second.dims())); });
         auto profile_of = [&variable_profile_table](std::string const& name){
-            assert(variable_profile_table.find(name) !=
-                variable_profile_table.end());
+            if(variable_profile_table.find(name) ==
+                variable_profile_table.end()) {
+                throw variable_not_found(name);
+            }
             return variable_profile_table.at(name);
         };
         auto dims_of = [&variable_profile_table, profile_of](
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index d46467e..0f06a58 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -50,6 +50,21 @@ namespace menoh_impl {
 
 #undef MENOH_ERROR_MESSAGE_MAX_LENGTH
 
+namespace menoh_impl {
+    class input_not_found : public exception {
+    public:
+        input_not_found(std::string const& input_name)
+          : exception(menoh_error_code_input_not_found_error,
+                      "menoh input not found error: " + input_name) {}
+    };
+    class output_not_found : public exception {
+    public:
+        output_not_found(std::string const& output_name)
+          : exception(menoh_error_code_output_not_found_error,
+                      "menoh output not found error: " + output_name) {}
+    };
+} // namespace menoh_impl
+
 const char* menoh_get_last_error_message() {
     return menoh_impl::get_error_message_singleton().data();
 }
@@ -328,9 +343,34 @@ menoh_error_code menoh_build_variable_profile_table(
           input_profile_table(builder->input_name_and_profile_list.begin(),
                               builder->input_name_and_profile_list.end());
 
+        std::set<std::string> given_input_name_set;
+        for(auto const& p : input_profile_table) {
+            given_input_name_set.insert(p.first);
+        }
+        std::set<std::string> model_input_name_set;
+        for(auto const& node : model_data->model_data.node_list) {
+            model_input_name_set.insert(node.input_name_list.begin(),
+                                        node.input_name_list.end());
+        }
+        std::vector<std::string> diff;
+        std::set_difference(
+          given_input_name_set.begin(), given_input_name_set.end(),
+          model_input_name_set.begin(), model_input_name_set.end(),
+          std::back_inserter(diff));
+        if(!diff.empty()) {
+            throw menoh_impl::input_not_found(diff.front());
+        }
+
         auto output_profile_table =
-          menoh_impl::complete_attribute_and_infer_shape(
-            model_data->model_data, input_profile_table);
+          menoh_impl::complete_attribute_and_infer_shape(model_data->model_data,
+                                                         input_profile_table);
+
+        for(auto const& output_name : builder->required_output_name_list) {
+            if(output_profile_table.find(output_name) ==
+               output_profile_table.end()) {
+                throw menoh_impl::output_not_found(output_name);
+            }
+        }
 
         *dst_handle =
           std::make_unique<menoh_variable_profile_table>(
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 8c06800..18861f5 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -81,6 +81,7 @@ def main():
 
 #include <menoh/array.hpp>
 #include <menoh/model_data.hpp>
+#include <menoh/utility.hpp>
 
 namespace menoh_impl {{
     inline auto complete_attribute_and_infer_shape(
@@ -100,8 +101,10 @@ def main():
                     p.first,
                     array_profile(p.second.dtype(), p.second.dims())); }});
         auto profile_of = [&variable_profile_table](std::string const& name){{
-            assert(variable_profile_table.find(name) !=
-                variable_profile_table.end());
+            if(variable_profile_table.find(name) ==
+                variable_profile_table.end()) {{
+                throw variable_not_found(name);
+            }}
             return variable_profile_table.at(name);
         }};
         auto dims_of = [&variable_profile_table, profile_of](

From e68728215a7e84215026895547f6dd868b516f02 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 12 Oct 2018 16:50:16 +0900
Subject: [PATCH 202/321] update version in readme

---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 03663ac..0427c44 100644
--- a/README.md
+++ b/README.md
@@ -40,9 +40,9 @@ This codebase contains C API and C++ API.
 - For macOS user, [Homebrew tap repository](https://github.com/pfnet-research/homebrew-menoh) is available.
 - For Ubuntu user, binary packages are available.
     ```
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_menoh_1.0.3-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.0.3/ubuntu1604_menoh-dev_1.0.3-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh_1.0.3-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh-dev_1.0.3-1_amd64.deb
     $ sudo apt install ./ubuntu1604_*_amd64.deb
     ```
     If you are using Ubuntu 18.04, please replace `1604` with `1804`.

From 42b8273fca070d1a4d1a3a8e60d70ce5053ef3ce Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Fri, 12 Oct 2018 19:11:07 +0900
Subject: [PATCH 203/321] fix version in readme

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 0427c44..d449458 100644
--- a/README.md
+++ b/README.md
@@ -41,8 +41,8 @@ This codebase contains C API and C++ API.
 - For Ubuntu user, binary packages are available.
     ```
     $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh_1.0.3-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh-dev_1.0.3-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh_1.1.0-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh-dev_1.1.0-1_amd64.deb
     $ sudo apt install ./ubuntu1604_*_amd64.deb
     ```
     If you are using Ubuntu 18.04, please replace `1604` with `1804`.

From cc7b2cedea63cf158705d408e58bc09add57e4ad Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 6 Oct 2018 21:15:15 +0900
Subject: [PATCH 204/321] implement gemm and memory_cache

---
 .../backend/mkldnn/memory_cache.cpp           | 103 ++++++++++
 .../backend/mkldnn/memory_cache.hpp           | 100 ++++++++++
 .../backend/mkldnn/memory_conversion.cpp      | 156 +++++++++++++++
 .../backend/mkldnn/memory_conversion.hpp      |  55 ++++++
 .../backend/mkldnn/mkldnn_context.cpp         | 172 +++++++++++------
 .../backend/mkldnn/mkldnn_context.hpp         |  78 ++++----
 .../backend/mkldnn/operator/gemm.hpp          | 179 ++++++++----------
 7 files changed, 636 insertions(+), 207 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
new file mode 100644
index 0000000..6b02a7f
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
@@ -0,0 +1,103 @@
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <numeric> // for accumulate
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            std::tuple<mkldnn::memory, optional<mkldnn::primitive>>
+            memory_cache::get_memory(std::vector<int> const& dims,
+                                     mkldnn::memory::format format) {
+                {
+                    // search matched memory
+                    auto found = std::find_if(
+                      cached_memory_list_.begin(), cached_memory_list_.end(),
+                      [&dims, format](auto const& m) {
+                          return extract_dims(m) == dims &&
+                                 extract_format(m) == format;
+                      });
+
+                    // when found
+                    if(found != cached_memory_list_.end()) {
+                        return std::make_tuple(*found, nullopt);
+                    }
+                }
+
+                if(original_array_ &&
+                   (ndims_to_data_memory_format(dims.size()) == format ||
+                    ndims_to_weight_memory_format(dims.size()) == format)) {
+                    mkldnn::memory new_memory(
+                      {{{dims},
+                        dtype_to_mkldnn_memory_data_type(
+                          original_array_->dtype()),
+                        format},
+                       engine()},
+                      const_cast<void*>(original_array_->data()));
+                    add_cached_memory(new_memory);
+                    return std::make_tuple(new_memory, nullopt);
+                }
+
+                // when not found matched memory
+                {
+                    // search same dims and format type (data or weight)
+                    // memory
+                    auto found = std::find_if(
+                      cached_memory_list_.begin(), cached_memory_list_.end(),
+                      [&dims, format](auto const& m) {
+                          return extract_dims(m) == dims &&
+                                 is_data_format(extract_format(m)) ==
+                                   is_data_format(format);
+                      });
+
+                    // when found same dims and format type memory
+                    if(found != cached_memory_list_.end()) {
+                        auto const& found_memory = *found;
+                        assert(dims == extract_dims(found_memory));
+                        mkldnn::memory new_memory(
+                          {{{dims}, extract_data_type(found_memory), format},
+                           engine()});
+                        add_cached_memory(new_memory);
+                        auto reorder_primitive =
+                          mkldnn::reorder(found_memory, new_memory);
+                        return std::make_tuple(new_memory, reorder_primitive);
+                    }
+                }
+
+                if(!original_array_) {
+                    throw std::runtime_error("not found valid array or memory");
+                }
+
+                // when not found same dims and format type memory
+                assert(original_array_);
+                assert(total_size(*original_array_) ==
+                       std::accumulate(dims.begin(), dims.end(), 1,
+                                       std::multiplies<int>()));
+
+                auto original_dtype =
+                  dtype_to_mkldnn_memory_data_type(original_array_->dtype());
+                mkldnn::memory base_memory(
+                  {{{dims},
+                    original_dtype,
+                    is_data_format(format)
+                      ? ndims_to_data_memory_format(dims.size())
+                      : ndims_to_weight_memory_format(dims.size())},
+                   engine()},
+                  const_cast<void*>(original_array_->data()));
+                std::cout << "jjj" << std::endl;
+                add_cached_memory(base_memory);
+
+                mkldnn::memory new_memory(
+                  {{{dims}, original_dtype, format}, engine()});
+                add_cached_memory(new_memory);
+
+                auto reorder_primitive =
+                  mkldnn::reorder(base_memory, new_memory);
+                return std::make_tuple(new_memory, reorder_primitive);
+            } // namespace mkldnn_backend
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
new file mode 100644
index 0000000..ab28e19
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
@@ -0,0 +1,100 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
+
+#include <tuple>
+#include <numeric>
+
+#include <menoh/array.hpp>
+#include <menoh/optional.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            class memory_cache {
+            public:
+                memory_cache() = default;
+
+                memory_cache(array const& arr, mkldnn::engine const& engine)
+                  : original_array_(arr), engine_(engine) {}
+                memory_cache(mkldnn::memory const& mem)
+                  : cached_memory_list_({mem}),
+                    engine_(mem.get_primitive_desc().get_engine()) {}
+
+                mkldnn::memory::data_type dtype() const {
+                    if(original_array_) {
+                        return dtype_to_mkldnn_memory_data_type(
+                          original_array_->dtype());
+                    }
+                    assert(!cached_memory_list_.empty());
+                    return extract_data_type(cached_memory_list_.front());
+                }
+
+                std::vector<int> dims() const {
+                    if(original_array_) {
+                        return original_array_->dims();
+                    }
+                    assert(!cached_memory_list_.empty());
+                    return extract_dims(cached_memory_list_.front());
+                }
+
+                mkldnn::engine engine() const { return *engine_; }
+
+                std::tuple<mkldnn::memory, optional<mkldnn::primitive>>
+                get_memory(std::vector<int> const& dims,
+                           mkldnn::memory::format format);
+
+                void add_cached_memory(mkldnn::memory const& added_memory) {
+                    // check format is different
+                    // MEMO: dims may be different (eg FC's weight for 4d input
+                    // and 2d input)
+                    if(original_array_) {
+                        auto mdims = extract_dims(added_memory);
+                        assert(total_size(*original_array_) ==
+                               std::accumulate(mdims.begin(), mdims.end(), 1,
+                                               std::multiplies<int>()));
+                    }
+                    for(auto const& cached_memory : cached_memory_list_) {
+                        assert(extract_format(cached_memory) !=
+                               extract_format(added_memory));
+                    }
+
+                    cached_memory_list_.push_back(added_memory);
+                }
+
+            private:
+                optional<array> original_array_ = nullopt;
+                std::vector<mkldnn::memory> cached_memory_list_;
+                optional<mkldnn::engine> engine_;
+            };
+
+            mkldnn::memory inline get_memory(
+              memory_cache& mem_cache, std::vector<int> const& dims,
+              mkldnn::memory::format format,
+              std::vector<mkldnn::primitive>& primitives) {
+                optional<mkldnn::memory> mem;
+                optional<mkldnn::primitive> reorder_primitive;
+                std::tie(mem, reorder_primitive) =
+                  mem_cache.get_memory(dims, format);
+                if(reorder_primitive) {
+                    primitives.push_back(*reorder_primitive);
+                }
+                return *mem;
+            }
+
+            mkldnn::memory inline get_memory(
+              memory_cache& mem_cache, mkldnn::memory::format format,
+              std::vector<mkldnn::primitive>& primitives) {
+                return get_memory(mem_cache, mem_cache.dims(), format,
+                                  primitives);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
new file mode 100644
index 0000000..cb18f6c
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
@@ -0,0 +1,156 @@
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            bool is_data_format(mkldnn::memory::format format) {
+                std::vector<mkldnn::memory::format> data_memory_formats(
+                  {mkldnn::memory::format::x, //
+                   mkldnn::memory::format::nc,
+                   // mkldnn::memory::format::ncw,
+                   // mkldnn::memory::format::nwc,
+                   // mkldnn::memory::format::nCw16c,
+                   mkldnn::memory::format::nchw,
+                   // mkldnn::memory::format::nhwc,
+                   mkldnn::memory::format::chwn,
+                   // mkldnn::memory::format::nCw8c,
+                   mkldnn::memory::format::nChw8c,
+                   mkldnn::memory::format::nChw16c,
+                   mkldnn::memory::format::ncdhw, //
+                   mkldnn::memory::format::ndhwc,
+                   // mkldnn::memory::format::nCdhw8c,
+                   mkldnn::memory::format::nCdhw16c});
+                return std::find(data_memory_formats.begin(),
+                                 data_memory_formats.end(),
+                                 format) != data_memory_formats.end();
+            }
+
+            std::vector<int> extract_dims(mkldnn::memory const& m) {
+                auto const& d = m.get_primitive_desc().desc().data;
+                return std::vector<int>(d.dims, d.dims + d.ndims);
+            }
+
+            mkldnn::memory::format extract_format(mkldnn::memory const& m) {
+                auto const& d = m.get_primitive_desc().desc().data;
+                return static_cast<mkldnn::memory::format>(d.format);
+            }
+
+            mkldnn::memory::data_type
+            extract_data_type(mkldnn::memory const& m) {
+                auto const& d = m.get_primitive_desc().desc().data;
+                return static_cast<mkldnn::memory::data_type>(d.data_type);
+            }
+
+            mkldnn::memory::data_type
+            dtype_to_mkldnn_memory_data_type(dtype_t dtype) {
+                if(dtype == dtype_t::float_) {
+                    return mkldnn::memory::data_type::f32;
+                }
+                throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
+            }
+
+            dtype_t mkldnn_memory_data_type_to_dtype(
+              mkldnn::memory::data_type mem_data_type) {
+                if(mem_data_type == mkldnn::memory::data_type::f32) {
+                    return dtype_t::float_;
+                }
+                throw invalid_dtype(
+                  std::to_string(static_cast<int>(mem_data_type)));
+            }
+
+            mkldnn::memory::format ndims_to_data_memory_format(int ndims) {
+                if(ndims == 1) {
+                    return mkldnn::memory::format::x;
+                }
+                if(ndims == 2) {
+                    return mkldnn::memory::format::nc;
+                }
+                /*
+                if(ndims == 3) {
+                    return mkldnn::memory::format::ncw;
+                }
+                */
+                if(ndims == 4) {
+                    return mkldnn::memory::format::nchw;
+                }
+                throw std::runtime_error("ndims_to_data_memory_format: invalid ndims: " + std::to_string(ndims));
+            }
+
+            mkldnn::memory::format ndims_to_weight_memory_format(int ndims) {
+                if(ndims == 1) {
+                    return mkldnn::memory::format::x;
+                }
+                if(ndims == 2) {
+                    return mkldnn::memory::format::oi;
+                }
+                /*
+                if(ndims == 3) {
+                    return mkldnn::memory::format::oiw;
+                }
+                */
+                if(ndims == 4) {
+                    return mkldnn::memory::format::oihw;
+                }
+                throw std::runtime_error("ndims_to_weight_memory_format: invalid ndims" + std::to_string(ndims));
+            }
+
+            mkldnn::memory array_to_memory(array const& arr,
+                                           std::vector<int> const& dims,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine) {
+                return mkldnn::memory(
+                  {{{dims},
+                    dtype_to_mkldnn_memory_data_type(arr.dtype()),
+                    format},
+                   engine},
+                  const_cast<void*>(arr.data()));
+            }
+
+            mkldnn::memory array_to_memory(array const& arr,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine) {
+                return array_to_memory(arr, arr.dims(), format, engine);
+            }
+
+            mkldnn::memory array_to_data_memory(array const& arr,
+                                                mkldnn::engine const& engine) {
+                return array_to_memory(
+                  arr, arr.dims(),
+                  ndims_to_data_memory_format(arr.dims().size()), engine);
+            }
+
+            array memory_to_array(mkldnn::memory const& mem) {
+                assert(extract_format(mem) == mkldnn::memory::format::x ||
+                       extract_format(mem) == mkldnn::memory::format::nc ||
+                       // extract_format(mem) == mkldnn::memory::format::ncw ||
+                       extract_format(mem) == mkldnn::memory::format::nchw);
+                return array(
+                  mkldnn_memory_data_type_to_dtype(
+                    static_cast<mkldnn::memory::data_type>(
+                      mem.get_primitive_desc().desc().data.data_type)),
+                  extract_dims(mem), mem.get_data_handle());
+            }
+
+            mkldnn::memory
+            make_memory_from_array_profile(array_profile const& profile,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine) {
+                return mkldnn::memory(
+                  {{{profile.dims()},
+                    dtype_to_mkldnn_memory_data_type(profile.dtype()),
+                    format},
+                   engine});
+            }
+
+            mkldnn::memory
+            make_data_memory_from_array_profile(array_profile const& profile,
+                                                mkldnn::engine const& engine) {
+                return make_memory_from_array_profile(
+                  profile, ndims_to_data_memory_format(profile.dims().size()),
+                  engine);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp
new file mode 100644
index 0000000..9d6d2a2
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp
@@ -0,0 +1,55 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
+
+#include <menoh/array.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            bool is_data_format(mkldnn::memory::format format);
+
+            std::vector<int> extract_dims(mkldnn::memory const& m);
+            mkldnn::memory::format extract_format(mkldnn::memory const& m);
+            mkldnn::memory::data_type
+            extract_data_type(mkldnn::memory const& m);
+
+            mkldnn::memory::data_type
+            dtype_to_mkldnn_memory_data_type(dtype_t dtype);
+
+            dtype_t mkldnn_memory_data_type_to_dtype(
+              mkldnn::memory::data_type mem_data_type);
+
+            mkldnn::memory::format ndims_to_data_memory_format(int ndims);
+            mkldnn::memory::format ndims_to_weight_memory_format(int ndims);
+
+            mkldnn::memory array_to_memory(array const& arr,
+                                           std::vector<int> const& dims,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine);
+
+            mkldnn::memory array_to_memory(array const& arr,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine);
+
+            mkldnn::memory array_to_data_memory(array const& arr,
+                                                mkldnn::engine const& engine);
+
+            array memory_to_array(mkldnn::memory const& mem);
+
+            mkldnn::memory
+            make_memory_from_array_profile(array_profile const& profile,
+                                           mkldnn::memory::format format,
+                                           mkldnn::engine const& engine);
+
+            mkldnn::memory
+            make_data_memory_from_array_profile(array_profile const& profile,
+                                                mkldnn::engine const& engine);
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 26277c5..0e122ac 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -1,10 +1,9 @@
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp>
 
 #include <menoh/graph.hpp> // for unsupported_operator error
 
-#include <menoh/mkldnn/utility.hpp>
-
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
@@ -31,6 +30,7 @@ namespace menoh_impl {
                 context_list,
               logger_handle logger) {
                 static_cast<void>(output_profile_table); // maybe unused
+
                 auto first_node_index = current_index;
                 std::vector<procedure> procedure_list;
 
@@ -39,61 +39,81 @@ namespace menoh_impl {
                 for(; current_index < static_cast<int>(node_list.size());
                     ++current_index) {
                     auto const& node = node_list.at(current_index);
-                    std::vector<array> input_list;
+
                     std::vector<procedure> new_copy_procedure_list;
                     std::vector<mkldnn::primitive> new_primitive_list;
-                    std::vector<std::pair<std::string, mkldnn::memory>>
-                      new_output_memory_list;
-                    std::vector<mkldnn::memory> new_temp_memory_list;
+                    std::vector<std::pair<std::string, memory_cache>>
+                      new_named_output_memory_cache_list;
 
                     try {
+                        std::vector<std::reference_wrapper<memory_cache>>
+                          input_memory_cache_list;
                         for(auto const& input_name : node.input_name_list) {
                             do {
-                                // search in self variable table
-                                auto found_from_variable_memory_table =
-                                  variable_memory_table_.find(input_name);
-                                if(found_from_variable_memory_table !=
-                                   variable_memory_table_.end()) {
-                                    *logger
-                                      << input_name
-                                      << " is found in self variable table"
-                                      << std::endl;
-                                    input_list.push_back(
-                                      menoh_impl::mkldnn_backend::
-                                        memory_to_array(
-                                          found_from_variable_memory_table
-                                            ->second));
-                                    break;
+                                // search in common parameter table
+                                {
+                                    auto found =
+                                      common_parameter_table.find(input_name);
+                                    if(found != common_parameter_table.end()) {
+                                        *logger << input_name
+                                                << " is found from self common "
+                                                   "parameter table"
+                                                << std::endl;
+                                        auto result_pair =
+                                          variable_memory_cache_table_.emplace(
+                                            input_name,
+                                            memory_cache(found->second,
+                                                         engine_));
+                                        assert(
+                                          result_pair.second &&
+                                          "alredy same named variable exist");
+                                        input_memory_cache_list.push_back(
+                                          std::ref(result_pair.first->second));
+                                        break;
+                                    }
                                 }
 
-                                // search in common parameter and input table
-                                auto found_from_common_table = [&](auto const&
-                                                                     table) {
-                                    auto found = table.find(input_name);
-                                    if(found != table.end()) {
-                                        input_list.push_back(found->second);
-                                        return true;
+                                // search in self variable table
+                                {
+                                    auto found =
+                                      variable_memory_cache_table_.find(
+                                        input_name);
+                                    if(found !=
+                                       variable_memory_cache_table_.end()) {
+                                        *logger << input_name
+                                                << " is found from self "
+                                                   "variable table"
+                                                << std::endl;
+                                        input_memory_cache_list.push_back(
+                                          found->second);
+                                        break;
                                     }
-                                    return false;
-                                };
-                                if(found_from_common_table(
-                                     common_parameter_table)) {
-                                    *logger
-                                      << input_name
-                                      << " is found in common parameter table"
-                                      << std::endl;
-                                    break;
                                 }
-                                if(found_from_common_table(
-                                     common_input_table)) {
-                                    *logger << input_name
-                                            << " is found in common input table"
-                                            << std::endl;
-                                    break;
+
+                                // search in common input table
+                                {
+                                    auto found =
+                                      common_input_table.find(input_name);
+                                    if(found != common_input_table.end()) {
+                                        *logger << input_name
+                                                << " is found from self common "
+                                                   "input table"
+                                                << std::endl;
+                                        auto result_pair =
+                                          variable_memory_cache_table_.emplace(
+                                            input_name,
+                                            memory_cache(found->second,
+                                                         engine_));
+                                        assert(
+                                          result_pair.second &&
+                                          "alredy same named variable exist");
+                                        input_memory_cache_list.push_back(
+                                          std::ref(result_pair.first->second));
+                                        break;
+                                    }
                                 }
 
                                 // search in other contexts' variable table
-                                bool is_found_from_other_context = false;
                                 for(auto const& context_pair : context_list) {
                                     if(context_pair.first == context_name) {
                                         continue; // skip self
@@ -113,23 +133,55 @@ namespace menoh_impl {
                                         std::tie(copy_proc, arr) = *found;
                                         new_copy_procedure_list.push_back(
                                           copy_proc);
-                                        input_list.push_back(arr);
-                                        is_found_from_other_context = true;
+                                        auto result_pair =
+                                          variable_memory_cache_table_.emplace(
+                                            input_name,
+                                            memory_cache(arr, engine_));
+                                        assert(
+                                          result_pair.second &&
+                                          "alredy same named variable exist");
+                                        input_memory_cache_list.push_back(
+                                          std::ref(result_pair.first->second));
                                         break;
                                     }
                                 }
-                                assert(is_found_from_other_context);
+                                assert(!"never come here");
                             } while(false);
                         }
 
-                        // make primitives and
-                        auto factory =
-                          procedure_factory_table_.at(node.op_type);
-                        std::tie(new_primitive_list, new_output_memory_list,
-                                 new_temp_memory_list) =
-                          factory.operator()(current_index, node_list,
-                                             input_list, required_output_table,
-                                             engine_);
+                        std::vector<mkldnn::memory> output_memory_list;
+                        for(auto const& output_name : node.output_name_list) {
+                            auto found =
+                              required_output_table.find(output_name);
+                            assert(
+                              variable_memory_cache_table_.find(output_name) ==
+                                variable_memory_cache_table_.end() &&
+                              "variable have not already exist");
+                            if(found == required_output_table.end()) {
+                                // not required output
+                                // add `any` format memory
+                                output_memory_list.push_back(
+                                  make_memory_from_array_profile(
+                                    output_profile_table.at(output_name),
+                                    mkldnn::memory::format::any, engine_));
+                            } else {
+                                // required output
+                                output_memory_list.push_back(
+                                  array_to_data_memory(found->second, engine_));
+                            }
+                        }
+
+                        auto found =
+                          procedure_factory_table_.find(node.op_type);
+                        if(found == procedure_factory_table_.end()) {
+                            throw std::runtime_error("factory not found for: " +
+                                                     node.op_type);
+                        }
+                        auto factory = found->second;
+                        std::tie(new_primitive_list,
+                                 new_named_output_memory_cache_list) =
+                          factory.operator()(node, input_memory_cache_list,
+                                             output_memory_list, engine_);
                     } catch(std::exception const& e) {
                         *logger << e.what() << std::endl;
                         break;
@@ -146,13 +198,9 @@ namespace menoh_impl {
                       std::make_move_iterator(new_copy_procedure_list.end()));
 
                     // update context
-                    variable_memory_table_.insert(
-                      std::make_move_iterator(new_output_memory_list.begin()),
-                      std::make_move_iterator(new_output_memory_list.end()));
-                    temp_memory_list_.insert(
-                      temp_memory_list_.end(),
-                      std::make_move_iterator(new_temp_memory_list.begin()),
-                      std::make_move_iterator(new_temp_memory_list.end()));
+                    variable_memory_cache_table_.insert(
+                      new_named_output_memory_cache_list.begin(),
+                      new_named_output_memory_cache_list.end());
                 }
 
                 // when no nodes are processed
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
index 493095b..6f35207 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -5,6 +5,7 @@
 #include <menoh/mkldnn/utility.hpp>
 #include <menoh/model_core.hpp>
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
 #include <menoh/mkldnn_with_generic_fallback/context.hpp>
 
 #include <mkldnn.hpp>
@@ -20,42 +21,30 @@ namespace menoh_impl {
             private:
                 virtual optional<std::tuple<procedure, array>>
                 do_try_to_get_variable(std::string const& name) override {
-                    auto found = variable_memory_table_.find(name);
-                    if(found == variable_memory_table_.end()) {
+                    auto found = variable_memory_cache_table_.find(name);
+                    if(found == variable_memory_cache_table_.end()) {
                         return nullopt;
                     }
-                    auto dims =
-                      ::menoh_impl::mkldnn_backend::extract_dims(found->second);
-                    auto variable_memory = found->second; // mutable
-                    procedure copy_proc(nullptr);         // mutable
-                    if(dims.size() == 4) {
-                        auto format = static_cast<mkldnn::memory::format>(
-                          found->second.get_primitive_desc()
-                            .desc()
-                            .data.format);
-                        if(format != mkldnn::memory::nchw) {
-                            auto data_type =
-                              static_cast<mkldnn::memory::data_type>(
-                                found->second.get_primitive_desc()
-                                  .desc()
-                                  .data.data_type);
-                            variable_memory = mkldnn::memory(
-                              {{dims, data_type, mkldnn::memory::format::nchw},
-                               engine_});
-                            temp_memory_list_.push_back(variable_memory);
-                            std::vector<mkldnn::primitive> primitives(
-                              {mkldnn::reorder(found->second,
-                                               variable_memory)});
-                            copy_proc = [primitives]() {
-                                mkldnn::stream(mkldnn::stream::kind::eager)
-                                  .submit(primitives)
-                                  .wait();
-                            };
-                        }
-                    }
+                    auto& variable_memory_cache = found->second;
+                    std::vector<mkldnn::primitive> primitives;
+                    auto variable_memory =
+                      get_memory(variable_memory_cache,
+                                 ndims_to_data_memory_format(
+                                   variable_memory_cache.dims().size()),
+                                 primitives);
+                    procedure copy_proc =
+                      primitives.empty()
+                        ? procedure(nullptr)
+                        : procedure([primitives] {
+                              mkldnn::stream(mkldnn::stream::kind::eager)
+                                .submit(primitives)
+                                .wait();
+                          });
                     return std::make_tuple(
-                      copy_proc, array(dtype_t::float_, dims,
-                                       found->second.get_data_handle()));
+                      copy_proc, array(mkldnn_memory_data_type_to_dtype(
+                                         extract_data_type(variable_memory)),
+                                       extract_dims(variable_memory),
+                                       variable_memory.get_data_handle()));
                 }
 
                 virtual optional<std::tuple<std::vector<procedure>, int>>
@@ -78,21 +67,22 @@ namespace menoh_impl {
                 // for specialized optimization across backends
                 virtual any
                 do_take_variable_handle(std::string const& name) override {
-                    return variable_memory_table_.at(name);
+                    return variable_memory_cache_table_.at(name);
                 }
 
-                using procedure_factory = std::function<std::tuple<
-                  std::vector<mkldnn::primitive>,
-                  std::vector<std::pair<std::string, mkldnn::memory>>,
-                  std::vector<mkldnn::memory>>(
-                  int, std::vector<node> const&, std::vector<array> const&,
-                  std::unordered_map<std::string, array> const&,
-                  mkldnn::engine const&)>;
+                using procedure_factory = std::function<
+                  std::tuple<std::vector<mkldnn::primitive>,
+                             std::vector<std::pair<std::string, memory_cache>>>(
+                    node const&,
+                    std::vector<std::reference_wrapper<
+                      memory_cache>> const&, // input_memory_cache_list
+                    std::vector<mkldnn::memory> const&, // output_memory_list
+                    mkldnn::engine const&               // engine
+                    )>;
 
                 mkldnn::engine engine_{mkldnn::engine::kind::cpu, 0}; // TODO
-                std::unordered_map<std::string, mkldnn::memory>
-                  variable_memory_table_;
-                std::vector<mkldnn::memory> temp_memory_list_;
+                std::unordered_map<std::string, memory_cache>
+                  variable_memory_cache_table_;
                 std::unordered_map<std::string, procedure_factory>
                   procedure_factory_table_;
             };
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index a006d92..81e793d 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -1,28 +1,26 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<
-              std::vector<mkldnn::primitive>,
-              std::vector<std::pair<std::string, mkldnn::memory>>,
-              std::vector<mkldnn::memory>>
-            make_gemm(int node_index, std::vector<node> const& node_list,
-                      std::vector<array> const& input_list,
-                      std::unordered_map<std::string, array> const&
-                        required_output_table,
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_gemm(node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
                       mkldnn::engine const& engine) {
 
-                using namespace menoh_impl::mkldnn_backend;
                 std::vector<mkldnn::primitive> primitives;
-                std::unordered_map<std::string, array> output_table;
                 std::vector<mkldnn::memory> temp_memory_list;
                 std::vector<array> owned_array_list;
 
-                auto node = node_list.at(node_index);
-
                 auto alpha = optional_attribute_float(node, "alpha", 1.f);
                 if(alpha != 1) {
                     throw failed_to_configure_operator(
@@ -53,57 +51,51 @@ namespace menoh_impl {
                         std::to_string(alpha));
                 }
 
-                auto input_dims = input_list.at(0).dims();
-                auto input_format =
-                  (input_dims.size() == 2 ? mkldnn::memory::format::nc
-                                          : mkldnn::memory::format::nchw);
-                auto input_memory =
-                  array_to_memory(input_list.at(0), input_format, engine);
-                temp_memory_list.push_back(input_memory);
-
-                auto const& weight_arr = input_list.at(1);
-                auto weight_dims = weight_arr.dims();
-                auto weight_format =
-                  (input_dims.size() == 2 ? mkldnn::memory::format::oi
-                                          : mkldnn::memory::format::oihw);
-                if(weight_format == mkldnn::memory::format::oihw) {
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+
+                memory_cache& weight_memory_cache =
+                  input_memory_cache_list.at(1);
+                auto weight_dims = weight_memory_cache.dims(); // mutable
+                assert(weight_dims.size() == 2);
+                if(input_dims.size() != 2) {
                     weight_dims = std::vector<int>{weight_dims.front()};
                     weight_dims.insert(weight_dims.end(),
                                        input_dims.begin() + 1,
                                        input_dims.end());
                 }
-                auto weight_memory = array_to_memory(weight_arr, weight_dims,
-                                                     weight_format, engine);
-                temp_memory_list.push_back(weight_memory);
-
-                auto bias_arr = input_list.at(2);
-                auto bias_memory =
-                  array_to_memory(bias_arr, mkldnn::memory::format::x, engine);
-                temp_memory_list.push_back(bias_memory);
-
-                auto bias_dims = input_list.at(2).dims();
-                int output_size = weight_arr.dims()[0];
-                if(output_size != bias_dims[0]) {
+
+                memory_cache& bias_memory_cache = input_memory_cache_list.at(2);
+                auto bias_dims = bias_memory_cache.dims();
+                int output_size = weight_dims.at(0);
+                if(output_size != bias_dims.at(0)) {
                     throw failed_to_configure_operator(
                       node.op_type, node.output_name_list.at(0),
                       "dims[0] of input C must be equal to dims[0] of "
                       "input B: "
                       "broadcast is not supported yet");
                 }
-                mkldnn::memory::dims output_dims{input_dims[0], output_size};
 
-                auto const& output_name = node.output_name_list.at(0);
-
-                auto gemm_input_md = mkldnn::memory::desc(
-                  {input_dims}, mkldnn::memory::data_type::f32,
-                  mkldnn::memory::format::any);
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+                assert(output_dims.at(0) == input_dims.at(0) &&
+                       "invalid shape inference");
+                assert(output_dims.at(1) == output_size &&
+                       "invalid shape inference");
+                auto gemm_input_md =
+                  mkldnn::memory::desc({input_dims}, input_memory_cache.dtype(),
+                                       mkldnn::memory::format::any);
                 auto gemm_weight_md = mkldnn::memory::desc(
-                  {weight_dims}, mkldnn::memory::data_type::f32,
+                  {weight_dims}, weight_memory_cache.dtype(),
                   mkldnn::memory::format::any);
                 auto gemm_output_md = mkldnn::memory::desc(
-                  {output_dims}, mkldnn::memory::data_type::f32,
+                  {output_dims}, extract_data_type(output_memory),
                   mkldnn::memory::format::any);
 
+                auto bias_memory = get_memory(
+                  bias_memory_cache, mkldnn::memory::format::x, primitives);
+
                 mkldnn::inner_product_forward::desc gemm_desc(
                   mkldnn::prop_kind::forward_inference, gemm_input_md,
                   gemm_weight_md, bias_memory.get_primitive_desc().desc(),
@@ -111,71 +103,56 @@ namespace menoh_impl {
                 auto gemm_pd = mkldnn::inner_product_forward::primitive_desc(
                   gemm_desc, engine);
 
-                auto gemm_input_memory = input_memory;
-                if(mkldnn::memory::primitive_desc(
-                     gemm_pd.src_primitive_desc()) !=
-                   input_memory.get_primitive_desc()) {
-                    gemm_input_memory =
-                      mkldnn::memory(gemm_pd.src_primitive_desc());
-                    temp_memory_list.push_back(gemm_input_memory);
-                    primitives.push_back(
-                      mkldnn::reorder(input_memory, gemm_input_memory));
-                }
-
-                auto gemm_weight_memory = weight_memory;
-                if(mkldnn::memory::primitive_desc(
-                     gemm_pd.weights_primitive_desc()) !=
-                   weight_memory.get_primitive_desc()) {
-                    gemm_weight_memory =
-                      mkldnn::memory(gemm_pd.weights_primitive_desc());
-                    temp_memory_list.push_back(gemm_weight_memory);
-                    primitives.push_back(
-                      mkldnn::reorder(weight_memory, gemm_weight_memory));
-                }
-
-                auto output_format = mkldnn::memory::format::nc;
-                std::vector<std::pair<std::string, array>>
-                  output_name_and_arr_list;
-                menoh_impl::optional<mkldnn::memory> output_memory_opt;
-                auto found = required_output_table.find(output_name);
-                if(found != required_output_table.end()) {
-                    std::string name;
-                    array output_array;
-                    std::tie(name, output_array) = *found;
-                    output_memory_opt =
-                      array_to_memory(output_array, output_format, engine);
-                }
-
-                auto output_pd = gemm_pd.dst_primitive_desc();
-                auto op_output_memory =
-                  output_memory_opt.value_or(mkldnn::memory(output_pd));
-                if(output_memory_opt &&
-                   mkldnn::memory::primitive_desc(output_pd) !=
-                     output_memory_opt->get_primitive_desc()) {
-                    op_output_memory = mkldnn::memory(output_pd);
-                    temp_memory_list.push_back(*output_memory_opt);
+                auto input_memory = get_memory(
+                  input_memory_cache,
+                  extract_format(gemm_pd.src_primitive_desc()), primitives);
+                auto weight_memory = get_memory(
+                  weight_memory_cache, weight_dims,
+                  extract_format(gemm_pd.weights_primitive_desc()), primitives);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) ==
+                     extract_format(gemm_pd.dst_primitive_desc())) {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(gemm_pd.dst_primitive_desc())},
+                       engine},
+                      output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(gemm_pd.dst_primitive_desc())},
+                       engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
                 }
 
                 primitives.push_back(mkldnn::inner_product_forward(
-                  gemm_pd, gemm_input_memory, gemm_weight_memory, bias_memory,
-                  op_output_memory));
+                  gemm_pd, input_memory, weight_memory, bias_memory,
+                  *op_output_memory));
 
-                if(output_memory_opt &&
-                   op_output_memory != *output_memory_opt) {
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) !=
+                     extract_format(gemm_pd.dst_primitive_desc())) {
                     primitives.push_back(
-                      mkldnn::reorder(op_output_memory, *output_memory_opt));
+                      mkldnn::reorder(*op_output_memory, output_memory));
                 }
 
-                std::vector<std::pair<std::string, mkldnn::memory>>
-                  output_memory_list;
-                output_memory_list.emplace_back(output_name, op_output_memory);
-
-                return std::make_tuple(primitives, output_memory_list,
-                                       temp_memory_list);
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list({std::make_pair(
+                    node.output_name_list.at(0), output_memory_cache)});
+                return std::make_tuple(primitives, output_memory_cache_list);
             }
 
         } // namespace mkldnn_backend
-    } // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP

From 32e3b16af2f9d53f57c3021b40b92faa785562c7 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 13 Oct 2018 22:25:18 +0900
Subject: [PATCH 205/321] remove useless lines

---
 .../backend/mkldnn/memory_cache.cpp           | 31 ++++++++++++++++---
 .../backend/mkldnn/memory_cache.hpp           |  4 ++-
 .../backend/mkldnn/operator/gemm.hpp          |  2 --
 3 files changed, 30 insertions(+), 7 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
index 6b02a7f..64ea0f7 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
@@ -2,8 +2,6 @@
 
 #include <numeric> // for accumulate
 
-#include <iostream>
-
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
@@ -86,7 +84,6 @@ namespace menoh_impl {
                       : ndims_to_weight_memory_format(dims.size())},
                    engine()},
                   const_cast<void*>(original_array_->data()));
-                std::cout << "jjj" << std::endl;
                 add_cached_memory(base_memory);
 
                 mkldnn::memory new_memory(
@@ -96,7 +93,33 @@ namespace menoh_impl {
                 auto reorder_primitive =
                   mkldnn::reorder(base_memory, new_memory);
                 return std::make_tuple(new_memory, reorder_primitive);
-            } // namespace mkldnn_backend
+            }
+
+            mkldnn::memory
+            memory_cache::get_data_memory() {
+                auto found =
+                  std::find_if(cached_memory_list_.begin(),
+                               cached_memory_list_.end(), [](auto const& m) {
+                                   return is_data_format(extract_format(m));
+                               });
+
+                // when found data format type memory
+                if(found != cached_memory_list_.end()) {
+                    return *found;
+                }
+
+                assert(original_array_);
+                auto original_dtype =
+                  dtype_to_mkldnn_memory_data_type(original_array_->dtype());
+                mkldnn::memory base_memory(
+                  {{{dims()},
+                    original_dtype,
+                    ndims_to_data_memory_format(dims().size())},
+                   engine()},
+                  const_cast<void*>(original_array_->data()));
+                add_cached_memory(base_memory);
+                return base_memory;
+            }
 
         } // namespace mkldnn_backend
     }     // namespace mkldnn_with_generic_fallback_backend
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
index ab28e19..9758bb3 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
@@ -1,8 +1,8 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
 
-#include <tuple>
 #include <numeric>
+#include <tuple>
 
 #include <menoh/array.hpp>
 #include <menoh/optional.hpp>
@@ -48,6 +48,8 @@ namespace menoh_impl {
                 get_memory(std::vector<int> const& dims,
                            mkldnn::memory::format format);
 
+                mkldnn::memory get_data_memory();
+
                 void add_cached_memory(mkldnn::memory const& added_memory) {
                     // check format is different
                     // MEMO: dims may be different (eg FC's weight for 4d input
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index 81e793d..669f60a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -18,8 +18,6 @@ namespace menoh_impl {
                       mkldnn::engine const& engine) {
 
                 std::vector<mkldnn::primitive> primitives;
-                std::vector<mkldnn::memory> temp_memory_list;
-                std::vector<array> owned_array_list;
 
                 auto alpha = optional_attribute_float(node, "alpha", 1.f);
                 if(alpha != 1) {

From 979f65335f0a5a889c40a36445c3df2934ca6e47 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 15 Oct 2018 11:43:45 +0900
Subject: [PATCH 206/321] add dependencies to the `Protobuf` external project

---
 cmake/BuildProtobuf.cmake | 7 ++++++-
 scripts/build-menoh.sh    | 4 ++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/cmake/BuildProtobuf.cmake b/cmake/BuildProtobuf.cmake
index 163411c..9c49922 100644
--- a/cmake/BuildProtobuf.cmake
+++ b/cmake/BuildProtobuf.cmake
@@ -1,8 +1,8 @@
 set(PROTOBUF_VERSION_STATIC "3.6.1")
+set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
 
 set(PROTOBUF_DIR ${CMAKE_CURRENT_BINARY_DIR}/protobuf-${PROTOBUF_VERSION_STATIC})
 set(PROTOBUF_URL "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION_STATIC}/protobuf-cpp-${PROTOBUF_VERSION_STATIC}.tar.gz")
-set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
 
 # Requires `-fPIC` for linking with a shared library
 set(PROTOBUF_CFLAGS "-g -O2 -fPIC")
@@ -34,11 +34,16 @@ set(PROTOBUF_LIBRARIES ${PROTOBUF_LIBRARY})
 set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_DIR}/bin/protoc)
 set(PROTOBUF_FOUND TRUE)
 
+# configure protobuf::libprotobuf
 add_library(protobuf::libprotobuf UNKNOWN IMPORTED)
 # Note: INTERFACE_INCLUDE_DIRECTORIES can't set in this place because include/ is
 # not installed during executing `cmake`
 set_target_properties(protobuf::libprotobuf PROPERTIES
     IMPORTED_LOCATION "${PROTOBUF_LIBRARY_STATIC}")
+add_dependencies(protobuf::libprotobuf Protobuf)
+
+# configure protobuf::protoc
 add_executable(protobuf::protoc IMPORTED)
 set_target_properties(protobuf::protoc PROPERTIES
     IMPORTED_LOCATION "${PROTOBUF_PROTOC_EXECUTABLE}")
+add_dependencies(protobuf::protoc Protobuf)
diff --git a/scripts/build-menoh.sh b/scripts/build-menoh.sh
index 5740377..5184c4e 100755
--- a/scripts/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -63,8 +63,8 @@ test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${ARG_SOURCE_DIR}/build"
 test -n "${ARG_INSTALL_DIR}" || readonly ARG_INSTALL_DIR=/usr/local
 
 if [ -n "${ARG_MKLDNN_DIR}" ]; then
-    OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
-    OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
+    readonly OPT_MKLDNN_INCLUDE_DIR=-DMKLDNN_INCLUDE_DIR=${ARG_MKLDNN_DIR}/include
+    readonly OPT_MKLDNN_LIBRARY=-DMKLDNN_LIBRARY=${ARG_MKLDNN_DIR}/lib/libmkldnn.so
 fi
 
 test -n "${ARG_PYTHON_EXECUTABLE}" || readonly ARG_PYTHON_EXECUTABLE=python

From 786e5f1849559b35589731924e4b04b9d3c9325e Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Mon, 15 Oct 2018 11:56:08 +0900
Subject: [PATCH 207/321] build only master branch on appveyor

---
 appveyor.yml | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/appveyor.yml b/appveyor.yml
index 9951f2c..7f330f4 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,3 +1,7 @@
+branches:
+  only:
+    - master
+
 cache:
 - c:\protobuf-3.6.0-msvc
 

From 3472cc2073c0f6eaac91b4b1482b545af12071c8 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 16 Oct 2018 20:39:46 +0900
Subject: [PATCH 208/321] BatchNorm -> BatchNormalization

---
 menoh/attribute_completion_and_shape_inference.hpp          | 2 +-
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 452afd7..29a6e7b 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -175,7 +175,7 @@ add_variable_to_table(output(0), dtype_of(input(0)),
 else
 
 
-if(node.op_type == "BatchNorm") {
+if(node.op_type == "BatchNormalization") {
     
     
 {
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 18861f5..aa5b677 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -161,7 +161,7 @@ def main():
 assert(2 <= ndims_of(input(0)));
 '''))
     code_list.append(
-        make_completion_code("BatchNorm", [
+        make_completion_code("BatchNormalization", [
             ("epsilon", "float", "1.e-05f"),
             ("momentum", "float", "0.9f"),
             ("spatial", "int", "1"),

From 5e27e38f16d9e8662d738466e2d06d0b4fc94a8a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 16 Oct 2018 22:34:34 +0900
Subject: [PATCH 209/321] update version 1.1.0 -> 1.1.1

---
 CMakeLists.txt | 2 +-
 README.md      | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6aa884e..b4b3346 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,7 +4,7 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 set(MENOH_MAJOR_VERSION 1)
 set(MENOH_MINOR_VERSION 1)
-set(MENOH_PATCH_VERSION 0)
+set(MENOH_PATCH_VERSION 1)
 
 # Options
 option(USE_OLD_GLIBCXX_ABI "Generate binaries for the old libstdc++ ABI" OFF)
diff --git a/README.md b/README.md
index d449458..7370afd 100644
--- a/README.md
+++ b/README.md
@@ -40,9 +40,9 @@ This codebase contains C API and C++ API.
 - For macOS user, [Homebrew tap repository](https://github.com/pfnet-research/homebrew-menoh) is available.
 - For Ubuntu user, binary packages are available.
     ```
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh_1.1.0-1_amd64.deb
-    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.0/ubuntu1604_menoh-dev_1.1.0-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.1/ubuntu1604_mkl-dnn_0.16-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.1/ubuntu1604_menoh_1.1.1-1_amd64.deb
+    $ curl -LO https://github.com/pfnet-research/menoh/releases/download/v1.1.1/ubuntu1604_menoh-dev_1.1.1-1_amd64.deb
     $ sudo apt install ./ubuntu1604_*_amd64.deb
     ```
     If you are using Ubuntu 18.04, please replace `1604` with `1804`.

From 402e90fbfa55cfe6be84257a8dad02c04009ce7e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 16 Oct 2018 22:40:09 +0900
Subject: [PATCH 210/321] add space

---
 menoh/model_core.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/model_core.hpp b/menoh/model_core.hpp
index de8e4fd..ea378d3 100644
--- a/menoh/model_core.hpp
+++ b/menoh/model_core.hpp
@@ -26,7 +26,7 @@ namespace menoh_impl {
                                std::string const& dims_size)
           : exception(menoh_error_code_unsupported_input_dims,
                       "menoh unsupported input dims error: " + name +
-                        "has dims size: " + dims_size) {}
+                        " has dims size: " + dims_size) {}
     };
 
     class backend_error : public exception {

From ed76ef376d8267f03513dd217742725710862854 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 17 Oct 2018 10:27:50 +0900
Subject: [PATCH 211/321] Fix MINGW build instruction in BUILDING.md

---
 BUILDING.md | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/BUILDING.md b/BUILDING.md
index 6d0915f..9452ce9 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -193,10 +193,12 @@ cmake --build . --config Release --target install
 ```
 git clone https://github.com/pfnet-research/menoh.git
 cd menoh
-mkdir -p build && cd build
+mkdir -p build
+cd build
 MSYS2_ARG_CONV_EXCL="-DCMAKE_INSTALL_PREFIX=" \
-  cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64
+  cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX=/mingw64 ..
 make
+make install
 ```
 
 ### Note

From 1982d002c4a525b03168bed690b319072cb4fba9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 17 Oct 2018 14:27:40 +0900
Subject: [PATCH 212/321] fix typo alredy -> already

---
 .../backend/mkldnn/mkldnn_context.cpp                       | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 0e122ac..f94fc13 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -66,7 +66,7 @@ namespace menoh_impl {
                                                          engine_));
                                         assert(
                                           result_pair.second &&
-                                          "alredy same named variable exist");
+                                          "already same named variable exist");
                                         input_memory_cache_list.push_back(
                                           std::ref(result_pair.first->second));
                                         break;
@@ -106,7 +106,7 @@ namespace menoh_impl {
                                                          engine_));
                                         assert(
                                           result_pair.second &&
-                                          "alredy same named variable exist");
+                                          "already same named variable exist");
                                         input_memory_cache_list.push_back(
                                           std::ref(result_pair.first->second));
                                         break;
@@ -139,7 +139,7 @@ namespace menoh_impl {
                                             memory_cache(arr, engine_));
                                         assert(
                                           result_pair.second &&
-                                          "alredy same named variable exist");
+                                          "already same named variable exist");
                                         input_memory_cache_list.push_back(
                                           std::ref(result_pair.first->second));
                                         break;

From c184a5f7e1a06b39e99d1e0f148685ae6adb8aaf Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 19 Oct 2018 21:31:42 +0900
Subject: [PATCH 213/321] add virtual destructor to context (issue151)

---
 menoh/mkldnn_with_generic_fallback/context.hpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/menoh/mkldnn_with_generic_fallback/context.hpp b/menoh/mkldnn_with_generic_fallback/context.hpp
index de56e1f..98c4b48 100644
--- a/menoh/mkldnn_with_generic_fallback/context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/context.hpp
@@ -16,6 +16,8 @@ namespace menoh_impl {
 
         class context {
         public:
+            virtual ~context() = 0;
+
             optional<std::tuple<procedure, array>>
             try_to_get_variable(std::string const& name) {
                 return do_try_to_get_variable(name);
@@ -70,6 +72,7 @@ namespace menoh_impl {
             // for specialized optimization across backends
             virtual any do_take_variable_handle(std::string const& name) = 0;
         };
+        inline context::~context(){}
 
     } // namespace mkldnn_with_generic_fallback_backend
 } // namespace menoh_impl

From 08761182e11e07c31565cde9e5f1f71b90d6763f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 20 Oct 2018 10:14:48 +0900
Subject: [PATCH 214/321] refactor

---
 .../backend/mkldnn/formatted_array.hpp        | 54 +++++++++++
 .../backend/mkldnn/memory_cache.hpp           |  2 +-
 .../backend/mkldnn/mkldnn_context.cpp         | 46 ++++++---
 .../backend/mkldnn/mkldnn_context.hpp         | 25 ++---
 .../backend/mkldnn/operator/gemm.hpp          | 95 +++++++------------
 .../mkldnn/operator/output_management.hpp     | 65 +++++++++++++
 .../backend/mkldnn/procedure_factory.hpp      | 43 +++++++++
 7 files changed, 241 insertions(+), 89 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp
new file mode 100644
index 0000000..22bfcfe
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp
@@ -0,0 +1,54 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
+
+#include <menoh/array.hpp>
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            class formatted_array {
+            public:
+                formatted_array() = default;
+
+                formatted_array(mkldnn::memory::format format, array const& arr)
+                  : format_(format), array_(arr) {}
+
+                mkldnn::memory make_memory(mkldnn::memory::format format,
+                                           mkldnn::engine const& engine) const {
+                    return mkldnn::memory(
+                      {{{array_.dims()},
+                        dtype_to_mkldnn_memory_data_type(array_.dtype()),
+                        format},
+                       engine},
+                      const_cast<void*>(array_.data()));
+                }
+
+                mkldnn::memory::format format() const { return format_; }
+                menoh_impl::array array() const { return array_; }
+
+            private:
+                mkldnn::memory::format format_;
+                menoh_impl::array array_;
+            };
+
+            inline bool is_format_any(formatted_array const& farr) {
+                return farr.format() == mkldnn::memory::format::any;
+            }
+
+            inline mkldnn::memory
+            make_memory(formatted_array const& farr,
+                        mkldnn::engine const& engine) {
+                assert(farr.format() != mkldnn::memory::format::any);
+                return farr.make_memory(farr.format(), engine);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
index 9758bb3..f94c540 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
@@ -25,7 +25,7 @@ namespace menoh_impl {
                   : cached_memory_list_({mem}),
                     engine_(mem.get_primitive_desc().get_engine()) {}
 
-                mkldnn::memory::data_type dtype() const {
+                mkldnn::memory::data_type data_type() const {
                     if(original_array_) {
                         return dtype_to_mkldnn_memory_data_type(
                           original_array_->dtype());
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f94fc13..23205dd 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -42,8 +42,9 @@ namespace menoh_impl {
 
                     std::vector<procedure> new_copy_procedure_list;
                     std::vector<mkldnn::primitive> new_primitive_list;
+                    std::vector<memory_cache> new_output_memory_cache_list;
                     std::vector<std::pair<std::string, memory_cache>>
-                      new_named_output_memory_cache_list;
+                      new_named_temp_memory_cache_list;
 
                     try {
                         std::vector<std::reference_wrapper<memory_cache>>
@@ -149,7 +150,8 @@ namespace menoh_impl {
                             } while(false);
                         }
 
-                        std::vector<mkldnn::memory> output_memory_list;
+                        std::vector<formatted_array>
+                          output_formatted_array_list;
                         for(auto const& output_name : node.output_name_list) {
                             auto found =
                               required_output_table.find(output_name);
@@ -160,14 +162,19 @@ namespace menoh_impl {
                             if(found == required_output_table.end()) {
                                 // not required output
                                 // add `any` format memory
-                                output_memory_list.push_back(
-                                  make_memory_from_array_profile(
-                                    output_profile_table.at(output_name),
-                                    mkldnn::memory::format::any, engine_));
+                                auto arr =
+                                  array(output_profile_table.at(output_name));
+                                allocated_array_list_.push_back(arr);
+                                output_formatted_array_list.push_back(
+                                  formatted_array(mkldnn::memory::format::any,
+                                                  arr));
                             } else {
                                 // required output
-                                output_memory_list.push_back(
-                                  array_to_data_memory(found->second, engine_));
+                                output_formatted_array_list.push_back(
+                                  formatted_array(
+                                    ndims_to_data_memory_format(
+                                      found->second.dims().size()),
+                                    found->second));
                             }
                         }
 
@@ -178,10 +185,15 @@ namespace menoh_impl {
                                                      node.op_type);
                         }
                         auto factory = found->second;
-                        std::tie(new_primitive_list,
-                                 new_named_output_memory_cache_list) =
+                        procedure_factory_return_type factory_return =
                           factory.operator()(node, input_memory_cache_list,
-                                             output_memory_list, engine_);
+                                             output_formatted_array_list,
+                                             engine_);
+                        new_primitive_list = factory_return.primitives;
+                        new_output_memory_cache_list =
+                          factory_return.output_memory_cache_list;
+                        new_named_temp_memory_cache_list =
+                          factory_return.named_temp_memory_cache_list;
                     } catch(std::exception const& e) {
                         *logger << e.what() << std::endl;
                         break;
@@ -198,9 +210,15 @@ namespace menoh_impl {
                       std::make_move_iterator(new_copy_procedure_list.end()));
 
                     // update context
-                    variable_memory_cache_table_.insert(
-                      new_named_output_memory_cache_list.begin(),
-                      new_named_output_memory_cache_list.end());
+                    for(unsigned int i = 0; i < node.output_name_list.size();
+                        ++i) {
+                        variable_memory_cache_table_.emplace(
+                          node.output_name_list.at(i),
+                          new_output_memory_cache_list.at(i));
+                    }
+                    temp_memory_cache_table_.insert(
+                      new_named_temp_memory_cache_list.begin(),
+                      new_named_temp_memory_cache_list.end());
                 }
 
                 // when no nodes are processed
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
index 6f35207..6821ef6 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -1,14 +1,22 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
 #define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
 
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <mkldnn.hpp>
+
+#include <menoh/any.hpp>
 #include <menoh/array.hpp>
 #include <menoh/mkldnn/utility.hpp>
 #include <menoh/model_core.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
 #include <menoh/mkldnn_with_generic_fallback/context.hpp>
 
-#include <mkldnn.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
@@ -70,19 +78,12 @@ namespace menoh_impl {
                     return variable_memory_cache_table_.at(name);
                 }
 
-                using procedure_factory = std::function<
-                  std::tuple<std::vector<mkldnn::primitive>,
-                             std::vector<std::pair<std::string, memory_cache>>>(
-                    node const&,
-                    std::vector<std::reference_wrapper<
-                      memory_cache>> const&, // input_memory_cache_list
-                    std::vector<mkldnn::memory> const&, // output_memory_list
-                    mkldnn::engine const&               // engine
-                    )>;
-
                 mkldnn::engine engine_{mkldnn::engine::kind::cpu, 0}; // TODO
+                std::vector<array> allocated_array_list_;
                 std::unordered_map<std::string, memory_cache>
                   variable_memory_cache_table_;
+                std::unordered_map<std::string, memory_cache>
+                  temp_memory_cache_table_;
                 std::unordered_map<std::string, procedure_factory>
                   procedure_factory_table_;
             };
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index 669f60a..cbdae12 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -1,7 +1,10 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
@@ -9,44 +12,39 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_gemm(node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
+            inline procedure_factory_return_type
+            MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY(make_gemm) {
 
                 std::vector<mkldnn::primitive> primitives;
 
-                auto alpha = optional_attribute_float(node, "alpha", 1.f);
-                if(alpha != 1) {
+                auto alpha = attribute_float(node, "alpha");
+                if(alpha != 1.f) {
                     throw failed_to_configure_operator(
                       node.op_type, node.output_name_list.at(0),
                       "alpha of Gemm must be 1 but given: " +
                         std::to_string(alpha));
                 }
-                auto beta = optional_attribute_float(node, "beta", 1.f);
-                if(beta != 1) {
+                auto beta = attribute_float(node, "beta");
+                if(beta != 1.f) {
                     throw failed_to_configure_operator(
                       node.op_type, node.output_name_list.at(0),
                       "beta of Gemm must be 1 but given: " +
-                        std::to_string(alpha));
+                        std::to_string(beta));
                 }
 
-                auto trans_a = optional_attribute_int(node, "transA", 0);
+                auto trans_a = attribute_int(node, "transA");
                 if(trans_a) {
                     throw failed_to_configure_operator(
                       node.op_type, node.output_name_list.at(0),
                       "transA of Gemm must be 0 but given: " +
-                        std::to_string(alpha));
+                        std::to_string(trans_a));
                 }
-                auto trans_b = optional_attribute_int(node, "transB", 0);
+                auto trans_b = attribute_int(node, "transB");
                 if(!trans_b) {
                     throw failed_to_configure_operator(
                       node.op_type, node.output_name_list.at(0),
                       "transB of Gemm must be 0 but given: " +
-                        std::to_string(alpha));
+                        std::to_string(trans_b));
                 }
 
                 memory_cache& input_memory_cache =
@@ -75,20 +73,20 @@ namespace menoh_impl {
                       "broadcast is not supported yet");
                 }
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
                 assert(output_dims.at(0) == input_dims.at(0) &&
                        "invalid shape inference");
                 assert(output_dims.at(1) == output_size &&
                        "invalid shape inference");
-                auto gemm_input_md =
-                  mkldnn::memory::desc({input_dims}, input_memory_cache.dtype(),
-                                       mkldnn::memory::format::any);
+                auto gemm_input_md = mkldnn::memory::desc(
+                  {input_dims}, input_memory_cache.data_type(),
+                  mkldnn::memory::format::any);
                 auto gemm_weight_md = mkldnn::memory::desc(
-                  {weight_dims}, weight_memory_cache.dtype(),
+                  {weight_dims}, weight_memory_cache.data_type(),
                   mkldnn::memory::format::any);
                 auto gemm_output_md = mkldnn::memory::desc(
-                  {output_dims}, extract_data_type(output_memory),
+                  {output_dims}, input_memory_cache.data_type(),
                   mkldnn::memory::format::any);
 
                 auto bias_memory = get_memory(
@@ -108,45 +106,18 @@ namespace menoh_impl {
                   weight_memory_cache, weight_dims,
                   extract_format(gemm_pd.weights_primitive_desc()), primitives);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) ==
-                     extract_format(gemm_pd.dst_primitive_desc())) {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(gemm_pd.dst_primitive_desc())},
-                       engine},
-                      output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(gemm_pd.dst_primitive_desc())},
-                       engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                primitives.push_back(mkldnn::inner_product_forward(
-                  gemm_pd, input_memory, weight_memory, bias_memory,
-                  *op_output_memory));
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) !=
-                     extract_format(gemm_pd.dst_primitive_desc())) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                std::vector<std::pair<std::string, memory_cache>>
-                  output_memory_cache_list({std::make_pair(
-                    node.output_name_list.at(0), output_memory_cache)});
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  gemm_pd.dst_primitive_desc(), engine, primitives,
+                  [&gemm_pd, &input_memory, &weight_memory,
+                   &bias_memory](mkldnn::memory const& output_memory) {
+                      return mkldnn::inner_product_forward(
+                        gemm_pd, input_memory, weight_memory, bias_memory,
+                        output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
             }
 
         } // namespace mkldnn_backend
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
new file mode 100644
index 0000000..46ad361
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
@@ -0,0 +1,65 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            template <typename PrimitiveGen>
+            inline std::tuple<memory_cache, std::vector<mkldnn::primitive>>
+            manage_output(
+              formatted_array const& output_formatted_array,
+              mkldnn::memory::primitive_desc const& output_memory_pd,
+              mkldnn::engine const& engine, PrimitiveGen pg) {
+                std::vector<mkldnn::primitive> primitives;
+                memory_cache output_memory_cache;
+
+                auto op_output_format = extract_format(output_memory_pd);
+                bool is_reorder_needed =
+                  !is_format_any(output_formatted_array) &&
+                  output_formatted_array.format() != op_output_format;
+                auto op_output_memory =
+                  is_reorder_needed
+                    ? mkldnn::memory(
+                        output_memory_pd) // this line allocates memory
+                    : output_formatted_array.make_memory(op_output_format,
+                                                         engine);
+                output_memory_cache.add_cached_memory(op_output_memory);
+
+                primitives.push_back(pg(op_output_memory));
+
+                if(is_reorder_needed) {
+                    auto output_memory =
+                      make_memory(output_formatted_array, engine);
+                    output_memory_cache.add_cached_memory(output_memory);
+                    primitives.push_back(
+                      mkldnn::reorder(op_output_memory, output_memory));
+                }
+                return std::make_tuple(output_memory_cache, primitives);
+            }
+
+            template <typename PrimitiveGen>
+            inline memory_cache manage_output(
+              formatted_array const& output_formatted_array,
+              mkldnn::memory::primitive_desc const& output_memory_pd,
+              mkldnn::engine const& engine,
+              std::vector<mkldnn::primitive>& primitives, PrimitiveGen pg) {
+                memory_cache output_memory_cache;
+                std::vector<mkldnn::primitive> temp_primitives;
+                std::tie(output_memory_cache, temp_primitives) = manage_output(
+                  output_formatted_array, output_memory_pd, engine, pg);
+                primitives.insert(primitives.end(), temp_primitives.begin(),
+                                  temp_primitives.end());
+                return output_memory_cache;
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
new file mode 100644
index 0000000..1f98ec4
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
@@ -0,0 +1,43 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <mkldnn.hpp>
+
+#define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY(factory_name)           \
+    factory_name(                                                      \
+      node const& node,                                                \
+      std::vector<std::reference_wrapper<memory_cache>> const&         \
+        input_memory_cache_list,                                       \
+      std::vector<formatted_array> const& output_formatted_array_list, \
+      mkldnn::engine const& engine)
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            struct procedure_factory_return_type {
+                std::vector<mkldnn::primitive> primitives;
+                std::vector<memory_cache> output_memory_cache_list;
+                std::vector<std::pair<std::string, memory_cache>>
+                  named_temp_memory_cache_list;
+            };
+
+            using procedure_factory =
+              std::function<procedure_factory_return_type(
+                node const&,
+                std::vector<std::reference_wrapper<
+                  memory_cache>> const&, // input_memory_cache_list
+                std::vector<
+                  formatted_array> const&, // output_formatted_array_list
+                mkldnn::engine const&      // engine
+                )>;
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP

From 41327f611f3540021021e704200099e9ec0b1bff Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 14:05:08 +0900
Subject: [PATCH 215/321] add MENOH_MKLDNN_CONTEXT_FACTORY_PARAMETER_LIST and
 ARGUMENT_LIST then refactor gemm

---
 .../backend/mkldnn/operator/gemm.hpp          |  2 +-
 .../backend/mkldnn/procedure_factory.hpp      | 28 ++++++++++---------
 2 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index cbdae12..0de6082 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -13,7 +13,7 @@ namespace menoh_impl {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
-            MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY(make_gemm) {
+            make_gemm(MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 std::vector<mkldnn::primitive> primitives;
 
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
index 1f98ec4..98cb8d5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
@@ -8,13 +8,15 @@
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
 #include <mkldnn.hpp>
 
-#define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY(factory_name)           \
-    factory_name(                                                      \
-      node const& node,                                                \
-      std::vector<std::reference_wrapper<memory_cache>> const&         \
-        input_memory_cache_list,                                       \
-      std::vector<formatted_array> const& output_formatted_array_list, \
-      mkldnn::engine const& engine)
+#define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST          \
+    node const &node,                                                  \
+      std::vector<std::reference_wrapper<memory_cache>> const          \
+        &input_memory_cache_list,                                      \
+      std::vector<formatted_array> const &output_formatted_array_list, \
+      mkldnn::engine const &engine
+
+#define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_ARGUMENT_LIST \
+    node, input_memory_cache_list, output_formatted_array_list, engine
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
@@ -29,12 +31,12 @@ namespace menoh_impl {
 
             using procedure_factory =
               std::function<procedure_factory_return_type(
-                node const&,
-                std::vector<std::reference_wrapper<
-                  memory_cache>> const&, // input_memory_cache_list
-                std::vector<
-                  formatted_array> const&, // output_formatted_array_list
-                mkldnn::engine const&      // engine
+                node const &,
+                std::vector<std::reference_wrapper<memory_cache>> const
+                  &, // input_memory_cache_list
+                std::vector<formatted_array> const
+                  &,                   // output_formatted_array_list
+                mkldnn::engine const & // engine
                 )>;
 
         } // namespace mkldnn_backend

From 38fd8b98102e1becd32e058481205dc0415ffe0a Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Sun, 21 Oct 2018 17:23:01 +0900
Subject: [PATCH 216/321] fix Travis-CI osx build failure caused by conflict of
 oclint cask and gcc
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The conflict caused the following error when installing numpy using homebrew.

==> Installing numpy dependency: gcc
==> Downloading https://homebrew.bintray.com/bottles/gcc-8.2.0.high_sierra.bottle.1.tar.gz
==> Pouring gcc-8.2.0.high_sierra.bottle.1.tar.gz
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink include/c++
Target /usr/local/include/c++
already exists. You may want to remove it:
  rm '/usr/local/include/c++'
To force the link and overwrite all conflicting files:
  brew link --overwrite gcc
To list all files that would be deleted:
  brew link --overwrite --dry-run gcc
Possible conflicting files are:
/usr/local/include/c++ -> /usr/local/Caskroom/oclint/0.13.1,17.4.0/oclint-0.13.1/include/c++
==> Summary
🍺  /usr/local/Cellar/gcc/8.2.0: 1,495 files, 344.8MB
---
 .travis/macosx-x86_64/build.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index ec672cc..52c38ad 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -17,6 +17,7 @@ g++ --version
 
 # install prerequisites
 brew update
+brew cask uninstall oclint # oclint conflicts with gcc
 brew upgrade python
 
 export PATH=/usr/local/opt/python/libexec/bin:$PATH

From e0d74fbe29cf9eb9b131710ea5d85477a3d162ac Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 23 Oct 2018 16:03:10 +0900
Subject: [PATCH 217/321] fix memory_cache

---
 .../backend/mkldnn/memory_cache.cpp                 |  9 +++++----
 .../backend/mkldnn/memory_cache.hpp                 |  8 ++++++--
 .../backend/mkldnn/mkldnn_context.cpp               | 13 ++++++++++++-
 .../backend/mkldnn/operator/gemm.hpp                |  9 +++------
 .../backend/mkldnn/operator/output_management.hpp   |  3 +--
 5 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
index 64ea0f7..4ae0a1e 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
@@ -24,6 +24,7 @@ namespace menoh_impl {
                     }
                 }
 
+                // try to convert array to memory
                 if(original_array_ &&
                    (ndims_to_data_memory_format(dims.size()) == format ||
                     ndims_to_weight_memory_format(dims.size()) == format)) {
@@ -57,9 +58,10 @@ namespace menoh_impl {
                         mkldnn::memory new_memory(
                           {{{dims}, extract_data_type(found_memory), format},
                            engine()});
-                        add_cached_memory(new_memory);
                         auto reorder_primitive =
-                          mkldnn::reorder(found_memory, new_memory);
+                          mkldnn::reorder(found_memory,
+                                          new_memory);
+                        add_cached_memory(new_memory);
                         return std::make_tuple(new_memory, reorder_primitive);
                     }
                 }
@@ -95,8 +97,7 @@ namespace menoh_impl {
                 return std::make_tuple(new_memory, reorder_primitive);
             }
 
-            mkldnn::memory
-            memory_cache::get_data_memory() {
+            mkldnn::memory memory_cache::get_data_memory() {
                 auto found =
                   std::find_if(cached_memory_list_.begin(),
                                cached_memory_list_.end(), [](auto const& m) {
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
index f94c540..a4d66c8 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
@@ -21,7 +21,7 @@ namespace menoh_impl {
 
                 memory_cache(array const& arr, mkldnn::engine const& engine)
                   : original_array_(arr), engine_(engine) {}
-                memory_cache(mkldnn::memory const& mem)
+                explicit memory_cache(mkldnn::memory const& mem)
                   : cached_memory_list_({mem}),
                     engine_(mem.get_primitive_desc().get_engine()) {}
 
@@ -42,7 +42,10 @@ namespace menoh_impl {
                     return extract_dims(cached_memory_list_.front());
                 }
 
-                mkldnn::engine engine() const { return *engine_; }
+                mkldnn::engine const& engine() const {
+                    assert(engine_ && "engine_ is not set");
+                    return *engine_;
+                }
 
                 std::tuple<mkldnn::memory, optional<mkldnn::primitive>>
                 get_memory(std::vector<int> const& dims,
@@ -54,6 +57,7 @@ namespace menoh_impl {
                     // check format is different
                     // MEMO: dims may be different (eg FC's weight for 4d input
                     // and 2d input)
+                    assert(engine_ && "please use non default constructor");
                     if(original_array_) {
                         auto mdims = extract_dims(added_memory);
                         assert(total_size(*original_array_) ==
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 23205dd..689d131 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -115,6 +115,7 @@ namespace menoh_impl {
                                 }
 
                                 // search in other contexts' variable table
+                                bool is_found_from_other_context = false;
                                 for(auto const& context_pair : context_list) {
                                     if(context_pair.first == context_name) {
                                         continue; // skip self
@@ -143,10 +144,11 @@ namespace menoh_impl {
                                           "already same named variable exist");
                                         input_memory_cache_list.push_back(
                                           std::ref(result_pair.first->second));
+                                        is_found_from_other_context = true;
                                         break;
                                     }
                                 }
-                                assert(!"never come here");
+                                assert(is_found_from_other_context);
                             } while(false);
                         }
 
@@ -227,9 +229,18 @@ namespace menoh_impl {
                 }
 
                 procedure_list.emplace_back([this, primitive_list]() {
+                    /*
                     mkldnn::stream(mkldnn::stream::kind::eager)
                       .submit(primitive_list)
                       .wait();
+                    */
+                    int i = 0;
+                    for(auto const& primitive : primitive_list) {
+                        mkldnn::stream(mkldnn::stream::kind::eager)
+                          .submit({primitive})
+                          .wait();
+                        ++i;
+                    }
                 });
 
                 return std::make_tuple(procedure_list, current_index);
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index 0de6082..c276bef 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -56,7 +56,7 @@ namespace menoh_impl {
                 auto weight_dims = weight_memory_cache.dims(); // mutable
                 assert(weight_dims.size() == 2);
                 if(input_dims.size() != 2) {
-                    weight_dims = std::vector<int>{weight_dims.front()};
+                    weight_dims = std::vector<int>({weight_dims.front()});
                     weight_dims.insert(weight_dims.end(),
                                        input_dims.begin() + 1,
                                        input_dims.end());
@@ -66,11 +66,7 @@ namespace menoh_impl {
                 auto bias_dims = bias_memory_cache.dims();
                 int output_size = weight_dims.at(0);
                 if(output_size != bias_dims.at(0)) {
-                    throw failed_to_configure_operator(
-                      node.op_type, node.output_name_list.at(0),
-                      "dims[0] of input C must be equal to dims[0] of "
-                      "input B: "
-                      "broadcast is not supported yet");
+                    throw std::runtime_error("broadcast is not supported yet");
                 }
 
                 auto output_dims =
@@ -98,6 +94,7 @@ namespace menoh_impl {
                   gemm_output_md);
                 auto gemm_pd = mkldnn::inner_product_forward::primitive_desc(
                   gemm_desc, engine);
+                auto op_input_dims = extract_dims(gemm_pd.src_primitive_desc());
 
                 auto input_memory = get_memory(
                   input_memory_cache,
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
index 46ad361..38d2719 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
@@ -17,7 +17,6 @@ namespace menoh_impl {
               mkldnn::memory::primitive_desc const& output_memory_pd,
               mkldnn::engine const& engine, PrimitiveGen pg) {
                 std::vector<mkldnn::primitive> primitives;
-                memory_cache output_memory_cache;
 
                 auto op_output_format = extract_format(output_memory_pd);
                 bool is_reorder_needed =
@@ -29,7 +28,7 @@ namespace menoh_impl {
                         output_memory_pd) // this line allocates memory
                     : output_formatted_array.make_memory(op_output_format,
                                                          engine);
-                output_memory_cache.add_cached_memory(op_output_memory);
+                memory_cache output_memory_cache(op_output_memory);
 
                 primitives.push_back(pg(op_output_memory));
 

From c823b9831ab65dfaad42b2c34d27d51757664d9e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 25 Oct 2018 12:32:02 +0900
Subject: [PATCH 218/321] fix execution

---
 .../backend/mkldnn/mkldnn_context.cpp                    | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 689d131..f3007b3 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -229,18 +229,9 @@ namespace menoh_impl {
                 }
 
                 procedure_list.emplace_back([this, primitive_list]() {
-                    /*
                     mkldnn::stream(mkldnn::stream::kind::eager)
                       .submit(primitive_list)
                       .wait();
-                    */
-                    int i = 0;
-                    for(auto const& primitive : primitive_list) {
-                        mkldnn::stream(mkldnn::stream::kind::eager)
-                          .submit({primitive})
-                          .wait();
-                        ++i;
-                    }
                 });
 
                 return std::make_tuple(procedure_list, current_index);

From ea755fd7f3e933602d22ebe660079ff562f3b36b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 25 Oct 2018 12:32:23 +0900
Subject: [PATCH 219/321] remove useless line

---
 .../backend/mkldnn/operator/gemm.hpp                             | 1 -
 1 file changed, 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
index c276bef..9617914 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
@@ -94,7 +94,6 @@ namespace menoh_impl {
                   gemm_output_md);
                 auto gemm_pd = mkldnn::inner_product_forward::primitive_desc(
                   gemm_desc, engine);
-                auto op_input_dims = extract_dims(gemm_pd.src_primitive_desc());
 
                 auto input_memory = get_memory(
                   input_memory_cache,

From caee4a4de9712fd8a3fdb5ac3396f6425356cd74 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 25 Oct 2018 14:25:59 +0900
Subject: [PATCH 220/321] add shape inference and test for GlobalAveragePool
 and GlobalMaxPool

---
 ...tribute_completion_and_shape_inference.hpp | 34 +++++++++++++++++++
 ...bute_completion_and_shape_inference_hpp.py | 14 ++++++++
 test/operator.cpp                             |  4 +++
 3 files changed, 52 insertions(+)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 29a6e7b..a9904f6 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -618,6 +618,40 @@ add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 else
 
 
+if(node.op_type == "GlobalAveragePool") {
+    
+    
+    
+    {
+        
+        
+auto input_dims = dims_of(input(0));
+auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
+
+    }
+}
+else
+
+
+if(node.op_type == "GlobalMaxPool") {
+    
+    
+    
+    {
+        
+        
+auto input_dims = dims_of(input(0));
+auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
+
+    }
+}
+else
+
+
 if(node.op_type == "LeakyRelu") {
     
     
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index aa5b677..cd0b751 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -284,6 +284,20 @@ def main():
 
 auto output_dims = ints({a_dims.at(0), b_dims.at(1)});
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+'''))
+    code_list.append(
+        make_completion_code("GlobalAveragePool", [], '''
+auto input_dims = dims_of(input(0));
+auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
+'''))
+    code_list.append(
+        make_completion_code("GlobalMaxPool", [], '''
+auto input_dims = dims_of(input(0));
+auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
+add_variable_to_table(output(0), dtype_of(input(0)),
+    output_dims);
 '''))
     code_list.append(
         make_completion_code("LeakyRelu", [("alpha", "float", "0.01f")]))
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..944eb39 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -200,6 +200,10 @@ namespace {
     // TEST_OP(mkldnn, test_conv_with_strides_padding, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_convtranspose, eps); // not found
     // TEST_OP(mkldnn, test_gemm_nobroadcast, eps);
+    TEST_OP(mkldnn, test_globalaveragepool, eps);
+    TEST_OP(mkldnn, test_globalaveragepool_precomputed, eps);
+    TEST_OP(mkldnn, test_globalmaxpool, eps);
+    TEST_OP(mkldnn, test_globalmaxpool_precomputed, eps);
     //TEST_OP(mkldnn, test_globalaveragepool, eps);
     //TEST_OP(mkldnn, test_globalmaxpool, eps);
     TEST_OP(mkldnn, test_maxpool_2d_default, eps);

From 880196be200fc6991bf74368549f03d9d7881162 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 13 Oct 2018 22:29:47 +0900
Subject: [PATCH 221/321] implement mkldnn eltwise

- Abs
- Elu
- Relu
- LeakyRelu
- Sqrt
- Tanh
---
 .../backend/mkldnn/mkldnn_context.cpp         |  21 +++
 .../backend/mkldnn/operator.hpp               |   1 +
 .../backend/mkldnn/operator/eltwise.hpp       | 169 ++++++++++++++++++
 test/mkldnn_with_generic_fallback_backend.cpp |   5 +
 test/operator.cpp                             |   9 +-
 5 files changed, 203 insertions(+), 2 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f3007b3..590ca56 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -12,6 +12,27 @@ namespace menoh_impl {
                 procedure_factory_table_.emplace(
                   "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
                             make_gemm);
+
+                // eltwise
+                procedure_factory_table_.emplace(
+                  "Abs", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_abs);
+                procedure_factory_table_.emplace(
+                  "Elu", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_elu);
+                procedure_factory_table_.emplace(
+                  "LeakyRelu",
+                mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_leaky_relu);
+                procedure_factory_table_.emplace(
+                  "Relu", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_relu);
+                procedure_factory_table_.emplace(
+                  "Sqrt", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_sqrt);
+                procedure_factory_table_.emplace(
+                  "Tanh", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_tanh);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index db71fad..7c7d4e4 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
new file mode 100644
index 0000000..5c53f5a
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
@@ -0,0 +1,169 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_eltwise(
+              mkldnn::algorithm eltwise_alg, float alpha, float beta,
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+
+                std::vector<mkldnn::primitive> primitives;
+                std::vector<mkldnn::memory> temp_memory_list;
+                std::vector<array> owned_array_list;
+
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+                auto input_memory = input_memory_cache.get_data_memory();
+
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+
+                mkldnn::eltwise_forward::desc eltwise_desc(
+                  mkldnn::prop_kind::forward_inference, eltwise_alg,
+                  input_memory.get_primitive_desc().desc(), alpha, beta);
+                auto eltwise_pd =
+                  mkldnn::eltwise_forward::primitive_desc(eltwise_desc, engine);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) ==
+                     extract_format(eltwise_pd.dst_primitive_desc())) {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(eltwise_pd.dst_primitive_desc())},
+                       engine},
+                      output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(eltwise_pd.dst_primitive_desc())},
+                       engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
+                }
+
+                primitives.push_back(mkldnn::eltwise_forward(
+                  eltwise_pd, input_memory, *op_output_memory));
+
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) !=
+                     extract_format(eltwise_pd.dst_primitive_desc())) {
+                    primitives.push_back(
+                      mkldnn::reorder(*op_output_memory, output_memory));
+                }
+
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list({std::make_pair(
+                    node.output_name_list.at(0), output_memory_cache)});
+                return std::make_tuple(primitives, output_memory_cache_list);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_abs(node const& node,
+                     std::vector<std::reference_wrapper<memory_cache>> const&
+                       input_memory_cache_list,
+                     std::vector<mkldnn::memory> const& output_memory_list,
+                     mkldnn::engine const& engine) {
+                auto alpha = 0.f;
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_abs, alpha, beta,
+                                    node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_elu(node const& node,
+                     std::vector<std::reference_wrapper<memory_cache>> const&
+                       input_memory_cache_list,
+                     std::vector<mkldnn::memory> const& output_memory_list,
+                     mkldnn::engine const& engine) {
+                auto alpha = attribute_float(node, "alpha");
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_elu, alpha, beta,
+                                    node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_leaky_relu(
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+                auto alpha = attribute_float(node, "alpha");
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_relu,
+                                    alpha, beta, node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_relu(node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
+                      mkldnn::engine const& engine) {
+                auto alpha = 0.f;
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_relu, alpha,
+                                    beta, node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_sqrt(node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
+                      mkldnn::engine const& engine) {
+                auto alpha = 0.f;
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_sqrt, alpha,
+                                    beta, node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_tanh(node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
+                      mkldnn::engine const& engine) {
+                auto alpha = 0.f;
+                auto beta = 0.f;
+                return make_eltwise(mkldnn::algorithm::eltwise_tanh, alpha,
+                                    beta, node, input_memory_cache_list,
+                                    output_memory_list, engine);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
diff --git a/test/mkldnn_with_generic_fallback_backend.cpp b/test/mkldnn_with_generic_fallback_backend.cpp
index 3815e07..e4e265e 100644
--- a/test/mkldnn_with_generic_fallback_backend.cpp
+++ b/test/mkldnn_with_generic_fallback_backend.cpp
@@ -129,4 +129,9 @@ namespace menoh {
         relu_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
                   "../data/random_input_3_4096.txt", "../data/relu_1d.txt");
     }
+
+    TEST_F(MkldnnWithGenericFallbackBackendTest, tanh_test) {
+        tanh_test("mkldnn_with_generic_fallback", R"({"log_output": "stdout"})",
+                  "../data/random_input_3_4096.txt", "../data/tanh_1d.txt");
+    }
 } // namespace menoh
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..c93ed66 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -123,7 +123,7 @@ namespace {
                       input.name, static_cast<void*>(input.data.get()));
                 }
                 auto model =
-                  model_builder.build_model(model_data, backend_name);
+                  model_builder.build_model(model_data, backend_name,  R"({"log_output": "stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -213,7 +213,12 @@ namespace {
 
 
     // Tests for MKLDNN with Generic fallback backend
-    TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_abs, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_elu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_leakyrelu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_relu, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_sqrt, eps);
+    TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_tanh, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 

From 0e412f55c1ba0aedcba9ed3151653703b3cd148b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 14:05:53 +0900
Subject: [PATCH 222/321] refactor eltwise

---
 .../backend/mkldnn/operator/eltwise.hpp       | 183 +++++-------------
 1 file changed, 49 insertions(+), 134 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
index 5c53f5a..18558a1 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
@@ -1,7 +1,10 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
@@ -9,27 +12,19 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_eltwise(
+            inline procedure_factory_return_type make_eltwise(
               mkldnn::algorithm eltwise_alg, float alpha, float beta,
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 std::vector<mkldnn::primitive> primitives;
-                std::vector<mkldnn::memory> temp_memory_list;
-                std::vector<array> owned_array_list;
 
                 memory_cache& input_memory_cache =
                   input_memory_cache_list.at(0);
                 auto input_dims = input_memory_cache.dims();
                 auto input_memory = input_memory_cache.get_data_memory();
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
 
                 mkldnn::eltwise_forward::desc eltwise_desc(
                   mkldnn::prop_kind::forward_inference, eltwise_alg,
@@ -37,130 +32,50 @@ namespace menoh_impl {
                 auto eltwise_pd =
                   mkldnn::eltwise_forward::primitive_desc(eltwise_desc, engine);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) ==
-                     extract_format(eltwise_pd.dst_primitive_desc())) {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(eltwise_pd.dst_primitive_desc())},
-                       engine},
-                      output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(eltwise_pd.dst_primitive_desc())},
-                       engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                primitives.push_back(mkldnn::eltwise_forward(
-                  eltwise_pd, input_memory, *op_output_memory));
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) !=
-                     extract_format(eltwise_pd.dst_primitive_desc())) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                std::vector<std::pair<std::string, memory_cache>>
-                  output_memory_cache_list({std::make_pair(
-                    node.output_name_list.at(0), output_memory_cache)});
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  eltwise_pd.dst_primitive_desc(), engine, primitives,
+                  [&eltwise_pd,
+                   &input_memory](mkldnn::memory const& output_memory) {
+                      return mkldnn::eltwise_forward(eltwise_pd, input_memory,
+                                                     output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
             }
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_abs(node const& node,
-                     std::vector<std::reference_wrapper<memory_cache>> const&
-                       input_memory_cache_list,
-                     std::vector<mkldnn::memory> const& output_memory_list,
-                     mkldnn::engine const& engine) {
-                auto alpha = 0.f;
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_abs, alpha, beta,
-                                    node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
-
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_elu(node const& node,
-                     std::vector<std::reference_wrapper<memory_cache>> const&
-                       input_memory_cache_list,
-                     std::vector<mkldnn::memory> const& output_memory_list,
-                     mkldnn::engine const& engine) {
-                auto alpha = attribute_float(node, "alpha");
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_elu, alpha, beta,
-                                    node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
-
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_leaky_relu(
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
-                auto alpha = attribute_float(node, "alpha");
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_relu,
-                                    alpha, beta, node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
-
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_relu(node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
-                auto alpha = 0.f;
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_relu, alpha,
-                                    beta, node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
-
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_sqrt(node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
-                auto alpha = 0.f;
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_sqrt, alpha,
-                                    beta, node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
-
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_tanh(node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
-                auto alpha = 0.f;
-                auto beta = 0.f;
-                return make_eltwise(mkldnn::algorithm::eltwise_tanh, alpha,
-                                    beta, node, input_memory_cache_list,
-                                    output_memory_list, engine);
-            }
+#define MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY(factory_name, eltwise_alg, alpha, \
+                                             beta)                             \
+    inline procedure_factory_return_type factory_name(                         \
+      MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {                 \
+        return make_eltwise(                                                   \
+          eltwise_alg, alpha, beta,                                            \
+          MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_ARGUMENT_LIST);               \
+    }
+#define MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM(factory_name, \
+                                                      eltwise_alg)  \
+    MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY(factory_name, eltwise_alg, 0.f, 0.f)
+
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM(
+              make_abs, mkldnn::algorithm::eltwise_abs);
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM(
+              make_sqrt, mkldnn::algorithm::eltwise_sqrt);
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM(
+              make_tanh, mkldnn::algorithm::eltwise_tanh);
+
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY(make_elu,
+                                                 mkldnn::algorithm::eltwise_elu,
+                                                 attribute_float(node, "alpha"),
+                                                 0.f);
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY(
+              make_leaky_relu, mkldnn::algorithm::eltwise_relu,
+              attribute_float(node, "alpha"), 0.f);
+            MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM(
+              make_relu, mkldnn::algorithm::eltwise_relu);
+
+#undef MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY_NO_PARAM
+#undef MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY
 
         } // namespace mkldnn_backend
     }     // namespace mkldnn_with_generic_fallback_backend

From 12abf6ac366e2fcdc2af8165a48a954a4749cbbe Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sat, 13 Oct 2018 23:58:42 +0900
Subject: [PATCH 223/321] implement mkldnn conv

---
 .../backend/mkldnn/mkldnn_context.cpp         |   3 +
 .../backend/mkldnn/operator.hpp               |   1 +
 .../backend/mkldnn/operator/conv.hpp          | 160 ++++++++++++++++++
 test/operator.cpp                             |   7 +
 4 files changed, 171 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f3007b3..21619b5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -9,6 +9,9 @@ namespace menoh_impl {
         namespace mkldnn_backend {
 
             mkldnn_context::mkldnn_context() : context() {
+                procedure_factory_table_.emplace(
+                  "Conv", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_conv);
                 procedure_factory_table_.emplace(
                   "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
                             make_gemm);
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index db71fad..07956c8 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -1,6 +1,7 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 #define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
new file mode 100644
index 0000000..6299db4
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
@@ -0,0 +1,160 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_conv(node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
+                      mkldnn::engine const& engine) {
+
+                std::vector<mkldnn::primitive> primitives;
+
+                std::vector<int> strides, kernel_shape, pads;
+                std::tie(strides, kernel_shape, pads) =
+                  attributes_for_2d_data_processing(node);
+                std::vector<int> padding_l{pads[0], pads[1]};
+                std::vector<int> padding_r{pads[2], pads[3]};
+
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+
+                memory_cache& weight_memory_cache =
+                  input_memory_cache_list.at(1);
+                auto weight_dims = weight_memory_cache.dims();
+
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+                assert(output_dims.at(0) == input_dims.at(0) &&
+                       "invalid shape inference");
+                assert(output_dims.at(1) == output_size &&
+                       "invalid shape inference");
+                auto conv_input_md =
+                  mkldnn::memory::desc({input_dims}, input_memory_cache.dtype(),
+                                       mkldnn::memory::format::any);
+                auto conv_weight_md = mkldnn::memory::desc(
+                  {weight_dims}, weight_memory_cache.dtype(),
+                  mkldnn::memory::format::any);
+                auto conv_output_md = mkldnn::memory::desc(
+                  {output_dims}, extract_data_type(output_memory),
+                  mkldnn::memory::format::any);
+
+                optional<mkldnn::memory> bias_memory_opt;
+                menoh_impl::optional<mkldnn::convolution_forward::desc>
+                  conv_desc_opt;
+                auto dilations = attribute_ints(node, "dilations");
+                auto is_no_dilations =
+                  std::all_of(dilations.begin(), dilations.end(),
+                              [](auto e) { return e == 1; });
+                if(node.input_name_list.size() == 2) {
+                    if(is_no_dilations) {
+                        conv_desc_opt = mkldnn::convolution_forward::desc(
+                          mkldnn::prop_kind::forward_inference,
+                          mkldnn::algorithm::convolution_direct, conv_input_md,
+                          conv_weight_md, conv_output_md, strides, padding_l,
+                          padding_r, mkldnn::padding_kind::zero);
+                    } else {
+                        conv_desc_opt = mkldnn::convolution_forward::desc(
+                          mkldnn::prop_kind::forward_inference,
+                          mkldnn::algorithm::convolution_direct, conv_input_md,
+                          conv_weight_md, conv_output_md, strides, dilations,
+                          padding_l, padding_r, mkldnn::padding_kind::zero);
+                    }
+                } else {
+                    assert(node.input_name_list.size() == 3);
+
+                    memory_cache& bias_memory_cache =
+                      input_memory_cache_list.at(2);
+                    bias_memory_opt = get_memory(
+                      bias_memory_cache, mkldnn::memory::format::x, primitives);
+
+                    if(is_no_dilations) {
+                        conv_desc_opt = mkldnn::convolution_forward::desc(
+                          mkldnn::prop_kind::forward_inference,
+                          mkldnn::algorithm::convolution_direct, conv_input_md,
+                          conv_weight_md,
+                          bias_memory_opt->get_primitive_desc().desc(),
+                          conv_output_md, strides, padding_l, padding_r,
+                          mkldnn::padding_kind::zero);
+                    } else {
+                        conv_desc_opt = mkldnn::convolution_forward::desc(
+                          mkldnn::prop_kind::forward_inference,
+                          mkldnn::algorithm::convolution_direct, conv_input_md,
+                          conv_weight_md,
+                          bias_memory_opt->get_primitive_desc().desc(),
+                          conv_output_md, strides, dilations, padding_l,
+                          padding_r, mkldnn::padding_kind::zero);
+                    }
+                }
+                auto conv_desc = *conv_desc_opt;
+                auto conv_pd = mkldnn::convolution_forward::primitive_desc(
+                  conv_desc, engine);
+
+                auto input_memory = get_memory(
+                  input_memory_cache,
+                  extract_format(conv_pd.src_primitive_desc()), primitives);
+                auto weight_memory = get_memory(
+                  weight_memory_cache, weight_dims,
+                  extract_format(conv_pd.weights_primitive_desc()), primitives);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) ==
+                     extract_format(conv_pd.dst_primitive_desc())) {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(conv_pd.dst_primitive_desc())},
+                       engine},
+                      output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(conv_pd.dst_primitive_desc())},
+                       engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
+                }
+
+                if(bias_memory_opt) {
+                    primitives.push_back(mkldnn::convolution_forward(
+                      conv_pd, input_memory, weight_memory, *bias_memory_opt,
+                      *op_output_memory));
+                } else {
+                    primitives.push_back(mkldnn::convolution_forward(
+                      conv_pd, input_memory, weight_memory, *op_output_memory));
+                }
+
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) !=
+                     extract_format(conv_pd.dst_primitive_desc())) {
+                    primitives.push_back(
+                      mkldnn::reorder(*op_output_memory, output_memory));
+                }
+
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list({std::make_pair(
+                    node.output_name_list.at(0), output_memory_cache)});
+                return std::make_tuple(primitives, output_memory_cache_list);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..f79bd49 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -212,6 +212,13 @@ namespace {
     // TEST_OP(mkldnn, test_averagepool_2d_precomputed_same_upper, eps);
 
 
+    // Conv
+    TEST_OP(mkldnn_with_generic_fallback, test_basic_conv_without_padding, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_basic_conv_with_padding, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_and_asymmetric_padding, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_no_padding, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_padding, eps);
+
     // Tests for MKLDNN with Generic fallback backend
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
 

From 8a3d8d5169a4b30d3ff10809b67c9ac3ab3b08e9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 14:17:01 +0900
Subject: [PATCH 224/321] refactor

---
 .../backend/mkldnn/operator/conv.hpp          | 90 +++++++------------
 1 file changed, 30 insertions(+), 60 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
index 6299db4..0fcd313 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
@@ -1,7 +1,10 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
@@ -9,13 +12,8 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_conv(node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
+            inline procedure_factory_return_type
+            make_conv(MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 std::vector<mkldnn::primitive> primitives;
 
@@ -33,20 +31,18 @@ namespace menoh_impl {
                   input_memory_cache_list.at(1);
                 auto weight_dims = weight_memory_cache.dims();
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
                 assert(output_dims.at(0) == input_dims.at(0) &&
                        "invalid shape inference");
-                assert(output_dims.at(1) == output_size &&
-                       "invalid shape inference");
-                auto conv_input_md =
-                  mkldnn::memory::desc({input_dims}, input_memory_cache.dtype(),
-                                       mkldnn::memory::format::any);
+                auto conv_input_md = mkldnn::memory::desc(
+                  {input_dims}, input_memory_cache.data_type(),
+                  mkldnn::memory::format::any);
                 auto conv_weight_md = mkldnn::memory::desc(
-                  {weight_dims}, weight_memory_cache.dtype(),
+                  {weight_dims}, weight_memory_cache.data_type(),
                   mkldnn::memory::format::any);
                 auto conv_output_md = mkldnn::memory::desc(
-                  {output_dims}, extract_data_type(output_memory),
+                  {output_dims}, input_memory_cache.data_type(),
                   mkldnn::memory::format::any);
 
                 optional<mkldnn::memory> bias_memory_opt;
@@ -107,50 +103,24 @@ namespace menoh_impl {
                   weight_memory_cache, weight_dims,
                   extract_format(conv_pd.weights_primitive_desc()), primitives);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) ==
-                     extract_format(conv_pd.dst_primitive_desc())) {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(conv_pd.dst_primitive_desc())},
-                       engine},
-                      output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(conv_pd.dst_primitive_desc())},
-                       engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                if(bias_memory_opt) {
-                    primitives.push_back(mkldnn::convolution_forward(
-                      conv_pd, input_memory, weight_memory, *bias_memory_opt,
-                      *op_output_memory));
-                } else {
-                    primitives.push_back(mkldnn::convolution_forward(
-                      conv_pd, input_memory, weight_memory, *op_output_memory));
-                }
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) !=
-                     extract_format(conv_pd.dst_primitive_desc())) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                std::vector<std::pair<std::string, memory_cache>>
-                  output_memory_cache_list({std::make_pair(
-                    node.output_name_list.at(0), output_memory_cache)});
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  conv_pd.dst_primitive_desc(), engine, primitives,
+                  [&conv_pd, &input_memory, &weight_memory,
+                   &bias_memory_opt](mkldnn::memory const& output_memory) {
+                      if(bias_memory_opt) {
+                          return mkldnn::convolution_forward(
+                            conv_pd, input_memory, weight_memory,
+                            *bias_memory_opt, output_memory);
+                      } else {
+                          return mkldnn::convolution_forward(
+                            conv_pd, input_memory, weight_memory,
+                            output_memory);
+                      }
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
             }
 
         } // namespace mkldnn_backend

From bc4b6a5b725db7e426f511b9a5894304930012e7 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 14 Oct 2018 23:48:49 +0900
Subject: [PATCH 225/321] impl mkldnn pool

---
 .../backend/mkldnn/mkldnn_context.cpp         |   8 +-
 .../backend/mkldnn/operator.hpp               |   1 +
 .../backend/mkldnn/operator/pool.hpp          | 133 ++++++++++++++++++
 test/operator.cpp                             |  27 +++-
 4 files changed, 165 insertions(+), 4 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f3007b3..00b05cc 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -9,9 +9,11 @@ namespace menoh_impl {
         namespace mkldnn_backend {
 
             mkldnn_context::mkldnn_context() : context() {
-                procedure_factory_table_.emplace(
-                  "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
-                            make_gemm);
+                using namespace mkldnn_with_generic_fallback_backend::
+                  mkldnn_backend;
+                procedure_factory_table_.emplace("AveragePool", make_average_pool);
+                procedure_factory_table_.emplace("Gemm", make_gemm);
+                procedure_factory_table_.emplace("MaxPool", make_max_pool);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index db71fad..fe23d13 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
new file mode 100644
index 0000000..1f7c517
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
@@ -0,0 +1,133 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_pool(mkldnn::algorithm pooling_alg, node const& node,
+                      std::vector<std::reference_wrapper<memory_cache>> const&
+                        input_memory_cache_list,
+                      std::vector<mkldnn::memory> const& output_memory_list,
+                      mkldnn::engine const& engine) {
+
+                assert(pooling_alg == mkldnn::pooling_max ||
+                       pooling_alg == mkldnn::pooling_avg_include_padding ||
+                       pooling_alg == mkldnn::pooling_avg_exclude_padding);
+
+                std::vector<mkldnn::primitive> primitives;
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list;
+
+                std::vector<int> strides, kernel_shape, pads;
+                std::tie(strides, kernel_shape, pads) =
+                  attributes_for_2d_data_processing(node);
+                std::vector<int> padding_l{pads[0], pads[1]};
+                std::vector<int> padding_r{pads[2], pads[3]};
+
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+                auto input_memory = input_memory_cache.get_data_memory();
+
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+                assert(output_dims.at(0) == input_dims.at(0) &&
+                       "invalid shape inference");
+                auto pool_output_md = mkldnn::memory::desc(
+                  {output_dims}, extract_data_type(output_memory),
+                  mkldnn::memory::format::any);
+
+                mkldnn::pooling_forward::desc pool_desc(
+                  mkldnn::prop_kind::forward_inference, pooling_alg,
+                  input_memory.get_primitive_desc().desc(), pool_output_md,
+                  strides, kernel_shape, padding_l, padding_r,
+                  mkldnn::padding_kind::zero);
+                mkldnn::pooling_forward::primitive_desc pool_pd(pool_desc,
+                                                                engine);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) ==
+                     extract_format(pool_pd.dst_primitive_desc())) {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(pool_pd.dst_primitive_desc())},
+                       engine},
+                      output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(pool_pd.dst_primitive_desc())},
+                       engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
+                }
+
+                primitives.push_back(mkldnn::pooling_forward(
+                  pool_pd, input_memory, *op_output_memory));
+
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) !=
+                     extract_format(pool_pd.dst_primitive_desc())) {
+                    primitives.push_back(
+                      mkldnn::reorder(*op_output_memory, output_memory));
+                }
+
+                output_memory_cache_list.emplace_back(
+                  node.output_name_list.at(0), output_memory_cache);
+                return std::make_tuple(primitives, output_memory_cache_list);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_average_pool(
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+                auto pooling_alg =
+                  attribute_int(node, "count_include_pad")
+                    ? mkldnn::algorithm::pooling_avg_include_padding
+                    : mkldnn::algorithm::pooling_avg_exclude_padding;
+                return make_pool(pooling_alg, node, input_memory_cache_list,
+                                 output_memory_list, engine);
+            }
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_max_pool(
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+                if(node.output_name_list.size() != 1) {
+                    throw std::runtime_error(
+                      "MaxPool issuing multiple outputs");
+                }
+                return make_pool(mkldnn::algorithm::pooling_max, node,
+                                 input_memory_cache_list, output_memory_list,
+                                 engine);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..e2b2b4c 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -123,7 +123,7 @@ namespace {
                       input.name, static_cast<void*>(input.data.get()));
                 }
                 auto model =
-                  model_builder.build_model(model_data, backend_name);
+                  model_builder.build_model(model_data, backend_name, R"({"log_output": "stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -216,6 +216,31 @@ namespace {
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_averagepool_1d_default, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_default, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_pads, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_pads_count_include_pad, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_precomputed_pads, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_precomputed_pads_count_include_pad, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_precomputed_same_upper, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_precomputed_strides, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_same_lower, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_same_upper, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_averagepool_2d_strides, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_averagepool_3d_default, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_1d_default, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_default, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_pads, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_precomputed_pads, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_precomputed_same_upper, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_precomputed_strides, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_same_lower, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_same_upper, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_maxpool_2d_strides, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_3d_default, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_with_argmax_2d_precomputed_pads, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_with_argmax_2d_precomputed_strides, eps);
+
 
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP

From 863ce8c1b355c726455d42a77bd915e7865ebf8d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 14:30:14 +0900
Subject: [PATCH 226/321] refactor

---
 .../backend/mkldnn/operator/pool.hpp          | 100 ++++++------------
 1 file changed, 30 insertions(+), 70 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
index 1f7c517..083092a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
@@ -1,23 +1,20 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
-#include <iostream>
-
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_pool(mkldnn::algorithm pooling_alg, node const& node,
-                      std::vector<std::reference_wrapper<memory_cache>> const&
-                        input_memory_cache_list,
-                      std::vector<mkldnn::memory> const& output_memory_list,
-                      mkldnn::engine const& engine) {
+            inline procedure_factory_return_type make_pool_impl(
+              mkldnn::algorithm pooling_alg,
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 assert(pooling_alg == mkldnn::pooling_max ||
                        pooling_alg == mkldnn::pooling_avg_include_padding ||
@@ -38,12 +35,12 @@ namespace menoh_impl {
                 auto input_dims = input_memory_cache.dims();
                 auto input_memory = input_memory_cache.get_data_memory();
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
                 assert(output_dims.at(0) == input_dims.at(0) &&
                        "invalid shape inference");
                 auto pool_output_md = mkldnn::memory::desc(
-                  {output_dims}, extract_data_type(output_memory),
+                  {output_dims}, input_memory_cache.data_type(),
                   mkldnn::memory::format::any);
 
                 mkldnn::pooling_forward::desc pool_desc(
@@ -54,76 +51,39 @@ namespace menoh_impl {
                 mkldnn::pooling_forward::primitive_desc pool_pd(pool_desc,
                                                                 engine);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) ==
-                     extract_format(pool_pd.dst_primitive_desc())) {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(pool_pd.dst_primitive_desc())},
-                       engine},
-                      output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(pool_pd.dst_primitive_desc())},
-                       engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                primitives.push_back(mkldnn::pooling_forward(
-                  pool_pd, input_memory, *op_output_memory));
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) !=
-                     extract_format(pool_pd.dst_primitive_desc())) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                output_memory_cache_list.emplace_back(
-                  node.output_name_list.at(0), output_memory_cache);
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  pool_pd.dst_primitive_desc(), engine, primitives,
+                  [&pool_pd,
+                   &input_memory](mkldnn::memory const& output_memory) {
+                      return mkldnn::pooling_forward(pool_pd, input_memory,
+                                                     output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
             }
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_average_pool(
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
+            inline procedure_factory_return_type make_average_pool(
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
                 auto pooling_alg =
                   attribute_int(node, "count_include_pad")
                     ? mkldnn::algorithm::pooling_avg_include_padding
                     : mkldnn::algorithm::pooling_avg_exclude_padding;
-                return make_pool(pooling_alg, node, input_memory_cache_list,
-                                 output_memory_list, engine);
+                return make_pool_impl(
+                  pooling_alg,
+                  MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_ARGUMENT_LIST);
             }
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_max_pool(
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
+            inline procedure_factory_return_type make_max_pool(
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
                 if(node.output_name_list.size() != 1) {
                     throw std::runtime_error(
                       "MaxPool issuing multiple outputs");
                 }
-                return make_pool(mkldnn::algorithm::pooling_max, node,
-                                 input_memory_cache_list, output_memory_list,
-                                 engine);
+                return make_pool_impl(
+                  mkldnn::algorithm::pooling_max,
+                  MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_ARGUMENT_LIST);
             }
 
         } // namespace mkldnn_backend

From 85ec0a71829fe6c1134fce84a39728c1cd374069 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 15 Oct 2018 00:26:40 +0900
Subject: [PATCH 227/321] implement mkldnn softmax

---
 .../backend/mkldnn/mkldnn_context.cpp         |  3 +
 .../backend/mkldnn/operator.hpp               |  1 +
 .../backend/mkldnn/operator/softmax.hpp       | 84 +++++++++++++++++++
 test/operator.cpp                             |  8 +-
 4 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f3007b3..95adb13 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -12,6 +12,9 @@ namespace menoh_impl {
                 procedure_factory_table_.emplace(
                   "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
                             make_gemm);
+                procedure_factory_table_.emplace(
+                  "Softmax", mkldnn_with_generic_fallback_backend::mkldnn_backend::
+                            make_softmax);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index db71fad..47ef806 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
new file mode 100644
index 0000000..78a636a
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
@@ -0,0 +1,84 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_softmax(
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+
+                std::vector<mkldnn::primitive> primitives;
+
+                auto axis = attribute_int(node, "axis");
+
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+                auto input_memory = input_memory_cache.get_data_memory();
+                auto input_format = extract_format(input_memory);
+
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+                assert(output_dims.at(0) == input_dims.at(0) &&
+                       "invalid shape inference");
+
+                mkldnn::softmax_forward::desc softmax_desc(
+                  mkldnn::prop_kind::forward_inference,
+                  input_memory.get_primitive_desc().desc(), axis);
+                auto softmax_pd =
+                  mkldnn::softmax_forward::primitive_desc(softmax_desc, engine);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) == input_format) {
+                    op_output_memory =
+                      mkldnn::memory({{{extract_dims(output_memory)},
+                                       extract_data_type(output_memory),
+                                       input_format},
+                                      engine},
+                                     output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory =
+                      mkldnn::memory({{{extract_dims(output_memory)},
+                                       extract_data_type(output_memory),
+                                       input_format},
+                                      engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
+                }
+
+                primitives.push_back(mkldnn::softmax_forward(
+                  softmax_pd, input_memory, *op_output_memory));
+
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) != input_format) {
+                    primitives.push_back(
+                      mkldnn::reorder(*op_output_memory, output_memory));
+                }
+
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list({std::make_pair(
+                    node.output_name_list.at(0), output_memory_cache)});
+                return std::make_tuple(primitives, output_memory_cache_list);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..0a5e170 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -123,7 +123,7 @@ namespace {
                       input.name, static_cast<void*>(input.data.get()));
                 }
                 auto model =
-                  model_builder.build_model(model_data, backend_name);
+                  model_builder.build_model(model_data, backend_name, R"({"log_output":"stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -216,6 +216,12 @@ namespace {
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_softmax_axis_0, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_softmax_axis_1, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_softmax_axis_2, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_softmax_default_axis, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_softmax_example, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_softmax_large_number, eps);
 
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP

From 220dd070d917b4971947ccfc9f402da85912479f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 14:55:39 +0900
Subject: [PATCH 228/321] refactor

---
 .../backend/mkldnn/operator/softmax.hpp       | 64 ++++++-------------
 1 file changed, 18 insertions(+), 46 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
index 78a636a..b9539a5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
@@ -1,7 +1,10 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
@@ -9,14 +12,8 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_softmax(
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
+            inline procedure_factory_return_type make_softmax(
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 std::vector<mkldnn::primitive> primitives;
 
@@ -28,8 +25,8 @@ namespace menoh_impl {
                 auto input_memory = input_memory_cache.get_data_memory();
                 auto input_format = extract_format(input_memory);
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
                 assert(output_dims.at(0) == input_dims.at(0) &&
                        "invalid shape inference");
 
@@ -39,42 +36,17 @@ namespace menoh_impl {
                 auto softmax_pd =
                   mkldnn::softmax_forward::primitive_desc(softmax_desc, engine);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) == input_format) {
-                    op_output_memory =
-                      mkldnn::memory({{{extract_dims(output_memory)},
-                                       extract_data_type(output_memory),
-                                       input_format},
-                                      engine},
-                                     output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory =
-                      mkldnn::memory({{{extract_dims(output_memory)},
-                                       extract_data_type(output_memory),
-                                       input_format},
-                                      engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                primitives.push_back(mkldnn::softmax_forward(
-                  softmax_pd, input_memory, *op_output_memory));
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) != input_format) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                std::vector<std::pair<std::string, memory_cache>>
-                  output_memory_cache_list({std::make_pair(
-                    node.output_name_list.at(0), output_memory_cache)});
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  input_memory.get_primitive_desc(), engine, primitives,
+                  [&softmax_pd,
+                   &input_memory](mkldnn::memory const& output_memory) {
+                      return mkldnn::softmax_forward(softmax_pd, input_memory,
+                                                     output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
             }
 
         } // namespace mkldnn_backend

From 6bd395af5ed2d0d174bc9754a932dac74a6be555 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 15 Oct 2018 16:07:00 +0900
Subject: [PATCH 229/321] implement mkldnn BatchNormalization

---
 .../backend/mkldnn/mkldnn_context.cpp         |   3 +
 .../backend/mkldnn/operator.hpp               |   1 +
 .../backend/mkldnn/operator/batch_norm.hpp    | 147 ++++++++++++++++++
 test/operator.cpp                             |  26 ++--
 4 files changed, 167 insertions(+), 10 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index f3007b3..debc165 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -12,6 +12,9 @@ namespace menoh_impl {
                 procedure_factory_table_.emplace(
                   "Gemm", mkldnn_with_generic_fallback_backend::mkldnn_backend::
                             make_gemm);
+                procedure_factory_table_.emplace(
+                  "BatchNormalization", mkldnn_with_generic_fallback_backend::
+                                          mkldnn_backend::make_batch_norm);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index db71fad..d0c7d9a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -1,6 +1,7 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 #define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
new file mode 100644
index 0000000..964122c
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
@@ -0,0 +1,147 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+
+#include <mkldnn.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline std::tuple<std::vector<mkldnn::primitive>,
+                              std::vector<std::pair<std::string, memory_cache>>>
+            make_batch_norm(
+              node const& node,
+              std::vector<std::reference_wrapper<memory_cache>> const&
+                input_memory_cache_list,
+              std::vector<mkldnn::memory> const& output_memory_list,
+              mkldnn::engine const& engine) {
+
+                std::vector<mkldnn::primitive> primitives;
+                std::vector<std::pair<std::string, memory_cache>>
+                  output_memory_cache_list;
+
+                auto epsilon = attribute_float(node, "epsilon");
+                auto spatial = attribute_int(node, "spatial");
+                if(!spatial) {
+                    throw std::runtime_error(
+                      "Non spacial BatchNorm is not supported");
+                }
+
+                memory_cache& input_memory_cache =
+                  input_memory_cache_list.at(0);
+                auto input_dims = input_memory_cache.dims();
+                auto input_memory = input_memory_cache.get_data_memory();
+
+                auto mean_memory =
+                  get_memory(input_memory_cache_list.at(3),
+                             mkldnn::memory::format::x, primitives);
+                auto var_memory =
+                  get_memory(input_memory_cache_list.at(4),
+                             mkldnn::memory::format::x, primitives);
+
+                memory_cache& scale_memory_cache =
+                  input_memory_cache_list.at(1);
+                auto scale_dims = scale_memory_cache.dims();
+                memory_cache& b_memory_cache = input_memory_cache_list.at(2);
+                std::vector<int> weight_dims({2});
+                weight_dims.insert(weight_dims.end(), scale_dims.begin(),
+                                   scale_dims.end());
+                auto scale_memory = get_memory(scale_memory_cache, scale_dims,
+                                               mkldnn::memory::x, primitives);
+                auto b_memory = get_memory(b_memory_cache, scale_dims,
+                                           mkldnn::memory::x, primitives);
+                mkldnn::memory weight_memory({{{weight_dims},
+                                               extract_data_type(scale_memory),
+                                               mkldnn::memory::format::nc},
+                                              engine});
+                auto scale_total_size =
+                  std::accumulate(scale_dims.begin(), scale_dims.end(), 1,
+                                  std::multiplies<int>());
+                // TODO other data_type
+                if(extract_data_type(scale_memory) ==
+                   mkldnn::memory::data_type::f32) {
+                    std::copy(
+                      static_cast<float*>(scale_memory.get_data_handle()),
+                      static_cast<float*>(scale_memory.get_data_handle()) +
+                        scale_total_size,
+                      static_cast<float*>(weight_memory.get_data_handle()));
+                    std::copy(
+                      static_cast<float*>(b_memory.get_data_handle()),
+                      static_cast<float*>(b_memory.get_data_handle()) +
+                        scale_total_size,
+                      static_cast<float*>(weight_memory.get_data_handle()) +
+                        scale_total_size);
+                } else {
+                    throw std::runtime_error(
+                      "BatchNormalization with invalid data_type");
+                }
+                memory_cache weight_memory_cache(weight_memory);
+                output_memory_cache_list.emplace_back(
+                  "menoh_mkldnn_temp_memory_" + node.op_type + "_" +
+                    node.output_name_list.front() + "_weight_memory",
+                  weight_memory_cache);
+
+                auto const& output_memory = output_memory_list.at(0);
+                auto output_dims = extract_dims(output_memory);
+                assert(output_dims.at(0) == input_dims.at(0) &&
+                       "invalid shape inference");
+
+                mkldnn::batch_normalization_forward::desc batch_norm_desc(
+                  mkldnn::prop_kind::forward_inference,
+                  input_memory.get_primitive_desc().desc(), epsilon,
+                  mkldnn::use_global_stats | mkldnn::use_scale_shift |
+                    omit_stats);
+                mkldnn::batch_normalization_forward::primitive_desc
+                  batch_norm_pd(batch_norm_desc, engine);
+
+                memory_cache output_memory_cache;
+                optional<mkldnn::memory> op_output_memory;
+                if(extract_format(output_memory) ==
+                     mkldnn::memory::format::any ||
+                   extract_format(output_memory) ==
+                     extract_format(batch_norm_pd.dst_primitive_desc())) {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(batch_norm_pd.dst_primitive_desc())},
+                       engine},
+                      output_memory.get_data_handle());
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                } else {
+                    op_output_memory = mkldnn::memory(
+                      {{{extract_dims(output_memory)},
+                        extract_data_type(output_memory),
+                        extract_format(batch_norm_pd.dst_primitive_desc())},
+                       engine});
+                    output_memory_cache.add_cached_memory(*op_output_memory);
+                    output_memory_cache.add_cached_memory(output_memory);
+                }
+
+                primitives.push_back(mkldnn::batch_normalization_forward(
+                  batch_norm_pd,
+                  static_cast<mkldnn::primitive::at>(input_memory),
+                  static_cast<mkldnn::primitive::at>(mean_memory),
+                  static_cast<mkldnn::primitive::at>(var_memory),
+                  static_cast<mkldnn::primitive::at>(weight_memory),
+                  *op_output_memory));
+
+                if(extract_format(output_memory) !=
+                     mkldnn::memory::format::any &&
+                   extract_format(output_memory) !=
+                     extract_format(batch_norm_pd.dst_primitive_desc())) {
+                    primitives.push_back(
+                      mkldnn::reorder(*op_output_memory, output_memory));
+                }
+
+                output_memory_cache_list.emplace_back(
+                  node.output_name_list.at(0), output_memory_cache);
+                return std::make_tuple(primitives, output_memory_cache_list);
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..136c12a 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -43,8 +43,8 @@ namespace {
 
         // TODO int array
         std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
-        assert(2 <= dims.size());
         if(squash_dims) {
+            assert(2 <= dims.size());
             dims.at(1) = std::accumulate(dims.begin() + 1, dims.end(), 1,
                                          std::multiplies<int>());
             dims.erase(dims.begin() + 2, dims.end());
@@ -122,8 +122,8 @@ namespace {
                     model_builder.attach_external_buffer(
                       input.name, static_cast<void*>(input.data.get()));
                 }
-                auto model =
-                  model_builder.build_model(model_data, backend_name);
+                auto model = model_builder.build_model(
+                  model_data, backend_name, R"({"log_output" : "stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -176,9 +176,13 @@ namespace {
     };
 
 #define TEST_OP_IMPL(backend_name, test_name, eps, squash) \
-    TEST_F(OperatorTest, backend_name##_##test_name) { run_test(#backend_name, #test_name, eps, squash); }
-#define TEST_OP(backend_name, test_name, eps) TEST_OP_IMPL(backend_name, test_name, eps, false)
-#define TEST_OP_SQUASH_DIMS(backend_name, test_name, eps) TEST_OP_IMPL(backend_name, test_name, eps, true)
+    TEST_F(OperatorTest, backend_name##_##test_name) {     \
+        run_test(#backend_name, #test_name, eps, squash);  \
+    }
+#define TEST_OP(backend_name, test_name, eps) \
+    TEST_OP_IMPL(backend_name, test_name, eps, false)
+#define TEST_OP_SQUASH_DIMS(backend_name, test_name, eps) \
+    TEST_OP_IMPL(backend_name, test_name, eps, true)
 
     float eps = 1.e-4;
 
@@ -200,8 +204,8 @@ namespace {
     // TEST_OP(mkldnn, test_conv_with_strides_padding, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_convtranspose, eps); // not found
     // TEST_OP(mkldnn, test_gemm_nobroadcast, eps);
-    //TEST_OP(mkldnn, test_globalaveragepool, eps);
-    //TEST_OP(mkldnn, test_globalmaxpool, eps);
+    // TEST_OP(mkldnn, test_globalaveragepool, eps);
+    // TEST_OP(mkldnn, test_globalmaxpool, eps);
     TEST_OP(mkldnn, test_maxpool_2d_default, eps);
     TEST_OP_SQUASH_DIMS(mkldnn, test_softmax_axis_1, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_sum_one_input, eps);
@@ -211,11 +215,13 @@ namespace {
     // TEST_OP(mkldnn, test_averagepool_2d_precomputed_pads, eps);
     // TEST_OP(mkldnn, test_averagepool_2d_precomputed_same_upper, eps);
 
-
     // Tests for MKLDNN with Generic fallback backend
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
 
-    //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_batchnorm_epsilon, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_batchnorm_example, eps);
+
+    // TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP

From 304dab09432db29aa626ad417e494dd04bf0330e Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Sun, 21 Oct 2018 15:32:39 +0900
Subject: [PATCH 230/321] refactor

---
 .../backend/mkldnn/operator/batch_norm.hpp    | 81 ++++++-------------
 1 file changed, 26 insertions(+), 55 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
index 964122c..7effed4 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
@@ -1,7 +1,10 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
@@ -9,18 +12,12 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace mkldnn_backend {
 
-            inline std::tuple<std::vector<mkldnn::primitive>,
-                              std::vector<std::pair<std::string, memory_cache>>>
-            make_batch_norm(
-              node const& node,
-              std::vector<std::reference_wrapper<memory_cache>> const&
-                input_memory_cache_list,
-              std::vector<mkldnn::memory> const& output_memory_list,
-              mkldnn::engine const& engine) {
+            inline procedure_factory_return_type make_batch_norm(
+              MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
 
                 std::vector<mkldnn::primitive> primitives;
                 std::vector<std::pair<std::string, memory_cache>>
-                  output_memory_cache_list;
+                  temp_memory_cache_list;
 
                 auto epsilon = attribute_float(node, "epsilon");
                 auto spatial = attribute_int(node, "spatial");
@@ -78,13 +75,13 @@ namespace menoh_impl {
                       "BatchNormalization with invalid data_type");
                 }
                 memory_cache weight_memory_cache(weight_memory);
-                output_memory_cache_list.emplace_back(
+                temp_memory_cache_list.emplace_back(
                   "menoh_mkldnn_temp_memory_" + node.op_type + "_" +
                     node.output_name_list.front() + "_weight_memory",
                   weight_memory_cache);
 
-                auto const& output_memory = output_memory_list.at(0);
-                auto output_dims = extract_dims(output_memory);
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
                 assert(output_dims.at(0) == input_dims.at(0) &&
                        "invalid shape inference");
 
@@ -92,52 +89,26 @@ namespace menoh_impl {
                   mkldnn::prop_kind::forward_inference,
                   input_memory.get_primitive_desc().desc(), epsilon,
                   mkldnn::use_global_stats | mkldnn::use_scale_shift |
-                    omit_stats);
+                    mkldnn::omit_stats);
                 mkldnn::batch_normalization_forward::primitive_desc
                   batch_norm_pd(batch_norm_desc, engine);
 
-                memory_cache output_memory_cache;
-                optional<mkldnn::memory> op_output_memory;
-                if(extract_format(output_memory) ==
-                     mkldnn::memory::format::any ||
-                   extract_format(output_memory) ==
-                     extract_format(batch_norm_pd.dst_primitive_desc())) {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(batch_norm_pd.dst_primitive_desc())},
-                       engine},
-                      output_memory.get_data_handle());
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                } else {
-                    op_output_memory = mkldnn::memory(
-                      {{{extract_dims(output_memory)},
-                        extract_data_type(output_memory),
-                        extract_format(batch_norm_pd.dst_primitive_desc())},
-                       engine});
-                    output_memory_cache.add_cached_memory(*op_output_memory);
-                    output_memory_cache.add_cached_memory(output_memory);
-                }
-
-                primitives.push_back(mkldnn::batch_normalization_forward(
-                  batch_norm_pd,
-                  static_cast<mkldnn::primitive::at>(input_memory),
-                  static_cast<mkldnn::primitive::at>(mean_memory),
-                  static_cast<mkldnn::primitive::at>(var_memory),
-                  static_cast<mkldnn::primitive::at>(weight_memory),
-                  *op_output_memory));
-
-                if(extract_format(output_memory) !=
-                     mkldnn::memory::format::any &&
-                   extract_format(output_memory) !=
-                     extract_format(batch_norm_pd.dst_primitive_desc())) {
-                    primitives.push_back(
-                      mkldnn::reorder(*op_output_memory, output_memory));
-                }
-
-                output_memory_cache_list.emplace_back(
-                  node.output_name_list.at(0), output_memory_cache);
-                return std::make_tuple(primitives, output_memory_cache_list);
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  batch_norm_pd.dst_primitive_desc(), engine, primitives,
+                  [&batch_norm_pd, &input_memory, &mean_memory, &var_memory,
+                   &weight_memory](mkldnn::memory const& output_memory) {
+                      return mkldnn::batch_normalization_forward(
+                        batch_norm_pd,
+                        static_cast<mkldnn::primitive::at>(input_memory),
+                        static_cast<mkldnn::primitive::at>(mean_memory),
+                        static_cast<mkldnn::primitive::at>(var_memory),
+                        static_cast<mkldnn::primitive::at>(weight_memory),
+                        output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, temp_memory_cache_list};
             }
 
         } // namespace mkldnn_backend

From b2e88d3c119215beca7b1679092cbe74ada73085 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 26 Oct 2018 14:07:27 +0900
Subject: [PATCH 231/321] add generic Sigmoid

---
 ...tribute_completion_and_shape_inference.hpp | 16 ++++++++
 .../backend/generic/generic_context.cpp       |  1 +
 .../backend/generic/operator.hpp              |  1 +
 .../backend/generic/operator/sigmoid.hpp      | 40 +++++++++++++++++++
 ...bute_completion_and_shape_inference_hpp.py |  1 +
 test/operator.cpp                             |  4 +-
 6 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 29a6e7b..efd5216 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -810,6 +810,22 @@ add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 else
 
 
+if(node.op_type == "Sigmoid") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
 if(node.op_type == "Softmax") {
     
     
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 7fee2d7..9157887 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -7,6 +7,7 @@ namespace menoh_impl {
 
             generic_context::generic_context() : context() {
                 procedure_factory_table_.emplace("Relu", make_relu);
+                procedure_factory_table_.emplace("Sigmoid", make_sigmoid);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
index 56a8e40..268728c 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp
new file mode 100644
index 0000000..4a2e742
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp
@@ -0,0 +1,40 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
+
+#include <cmath>
+
+#include <menoh/array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+            inline procedure
+            make_sigmoid(node const&, std::vector<array> const& input_list,
+                         std::vector<array> const& output_list) {
+                assert(input_list.size() == 1);
+                assert(output_list.size() == 1);
+
+                auto input = input_list.at(0);
+                if(input.dtype() != dtype_t::float_) {
+                    throw std::runtime_error("invalid dtype");
+                }
+
+                auto procedure = [input, output = output_list.at(0)]() {
+                    auto m = *std::max_element(fbegin(input), fend(input));
+                    auto em = std::exp(-m);
+                    for(decltype(total_size(input)) i = 0;
+                        i < total_size(input); ++i) {
+                        auto e = std::exp(fat(input, i) - m);
+                        fat(output, i) = e / (e + em);
+                    }
+                };
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index aa5b677..90ece14 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -307,6 +307,7 @@ def main():
         kernel_shape, strides, pads));
 '''))
     code_list.append(make_completion_code("Relu"))
+    code_list.append(make_completion_code("Sigmoid"))
     code_list.append(make_completion_code("Softmax", [("axis", "int", "1")]))
     code_list.append(make_completion_code("Sum"))
     code_list.append(make_completion_code("Sqrt"))
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..7c758f1 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -123,7 +123,7 @@ namespace {
                       input.name, static_cast<void*>(input.data.get()));
                 }
                 auto model =
-                  model_builder.build_model(model_data, backend_name);
+                  model_builder.build_model(model_data, backend_name, R"({"log_output":"stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -214,6 +214,8 @@ namespace {
 
     // Tests for MKLDNN with Generic fallback backend
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_sigmoid, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_sigmoid_example, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 

From 553ca1f1c3d57430980861adb82bf5102da161cf Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 26 Oct 2018 16:46:56 +0900
Subject: [PATCH 232/321] add generic Mul operator

---
 ...tribute_completion_and_shape_inference.hpp | 31 ++++++++++++++
 .../backend/generic/generic_context.cpp       |  4 +-
 .../backend/generic/operator.hpp              |  1 +
 .../backend/generic/operator/mul.hpp          | 41 +++++++++++++++++++
 ...bute_completion_and_shape_inference_hpp.py | 20 +++++++++
 test/operator.cpp                             |  5 ++-
 6 files changed, 100 insertions(+), 2 deletions(-)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 29a6e7b..4378701 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -16,6 +16,21 @@
 #include <menoh/utility.hpp>
 
 namespace menoh_impl {
+    inline std::vector<int> broadcast_shape(std::vector<int> const& adims,
+                                            std::vector<int> const& bdims) {
+        if(adims.size() < bdims.size()) {
+            return broadcast_shape(bdims, adims);
+        }
+        auto num_of_left_ones = adims.size() - bdims.size();
+        std::vector<int> cdims(num_of_left_ones, 1);
+        cdims.insert(cdims.end(), bdims.begin(), bdims.end());
+        std::vector<int> broadcast_dims;
+        assert(cdims.size() == adims.size());
+        std::transform(adims.begin(), adims.end(), cdims.begin(),
+                       std::back_inserter(broadcast_dims),
+                       [](auto a, auto b){ return std::max(a, b); });
+        return broadcast_dims;
+    }
     inline auto complete_attribute_and_infer_shape(
             model_data& model_data,
             std::unordered_map<std::string, array_profile> const&
@@ -794,6 +809,22 @@ add_variable_to_table(output(0), dtype_of(input(0)),
 else
 
 
+if(node.op_type == "Mul") {
+    
+    
+    
+    {
+        
+        
+add_variable_to_table(output(0), dtype_of(input(0)),
+    broadcast_shape(
+        dims_of(input(0)), dims_of(input(1))));
+
+    }
+}
+else
+
+
 if(node.op_type == "Relu") {
     
     
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 7fee2d7..70c5a07 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -7,6 +7,7 @@ namespace menoh_impl {
 
             generic_context::generic_context() : context() {
                 procedure_factory_table_.emplace("Relu", make_relu);
+                procedure_factory_table_.emplace("Mul", make_mul);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
@@ -120,7 +121,8 @@ namespace menoh_impl {
                         auto found =
                           procedure_factory_table_.find(node.op_type);
                         if(found == procedure_factory_table_.end()) {
-                            throw std::runtime_error("factory not found for: " + node.op_type);
+                            throw std::runtime_error("factory not found for: " +
+                                                     node.op_type);
                         }
                         auto factory = found->second;
                         op_proc =
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
index 56a8e40..0f717c9 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
new file mode 100644
index 0000000..abcc45e
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
@@ -0,0 +1,41 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
+
+#include <menoh/array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+            inline procedure make_mul(node const&,
+                                      std::vector<array> const& input_list,
+                                      std::vector<array> const& output_list) {
+                assert(input_list.size() == 2);
+                assert(output_list.size() == 1);
+
+                for(auto const& input : input_list) {
+                    if(input.dtype() != dtype_t::float_) {
+                        throw std::runtime_error("invalid dtype");
+                    }
+                }
+                if(total_size(input_list.at(0)) != total_size(input_list.at(1))) {
+                    throw std::runtime_error("broadcast is not supported yet");
+                }
+
+                auto procedure = [input_a = input_list.at(0),
+                                  input_b = input_list.at(1),
+                                  output = output_list.at(0)]() {
+                    for(decltype(total_size(input_a)) i = 0;
+                        i < total_size(input_a); ++i) {
+                        fat(output, i) = fat(input_a, i) * fat(input_b, i);
+                    }
+                };
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index aa5b677..4ad23a0 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -84,6 +84,21 @@ def main():
 #include <menoh/utility.hpp>
 
 namespace menoh_impl {{
+    inline std::vector<int> broadcast_shape(std::vector<int> const& adims,
+                                            std::vector<int> const& bdims) {{
+        if(adims.size() < bdims.size()) {{
+            return broadcast_shape(bdims, adims);
+        }}
+        auto num_of_left_ones = adims.size() - bdims.size();
+        std::vector<int> cdims(num_of_left_ones, 1);
+        cdims.insert(cdims.end(), bdims.begin(), bdims.end());
+        std::vector<int> broadcast_dims;
+        assert(cdims.size() == adims.size());
+        std::transform(adims.begin(), adims.end(), cdims.begin(),
+                       std::back_inserter(broadcast_dims),
+                       [](auto a, auto b){{ return std::max(a, b); }});
+        return broadcast_dims;
+    }}
     inline auto complete_attribute_and_infer_shape(
             model_data& model_data,
             std::unordered_map<std::string, array_profile> const&
@@ -305,6 +320,11 @@ def main():
     calc_2d_output_dims(
         dims_of(input(0)), dims_of(input(0)).at(1),
         kernel_shape, strides, pads));
+'''))
+    code_list.append(make_completion_code("Mul", [], '''
+add_variable_to_table(output(0), dtype_of(input(0)),
+    broadcast_shape(
+        dims_of(input(0)), dims_of(input(1))));
 '''))
     code_list.append(make_completion_code("Relu"))
     code_list.append(make_completion_code("Softmax", [("axis", "int", "1")]))
diff --git a/test/operator.cpp b/test/operator.cpp
index cbeaa89..bbbfd34 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -123,7 +123,7 @@ namespace {
                       input.name, static_cast<void*>(input.data.get()));
                 }
                 auto model =
-                  model_builder.build_model(model_data, backend_name);
+                  model_builder.build_model(model_data, backend_name, R"({"log_output":"stdout"})");
                 model_data.reset();
 
                 std::vector<menoh::variable> output_list;
@@ -214,6 +214,9 @@ namespace {
 
     // Tests for MKLDNN with Generic fallback backend
     TEST_OP(mkldnn_with_generic_fallback, test_relu, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_mul, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_mul_bcast, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_mul_example, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
 

From 2b56eccc9be83dac82a17a0c2e257bc16a742952 Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Fri, 26 Oct 2018 17:48:07 +0900
Subject: [PATCH 233/321] remove useless line

---
 .../backend/mkldnn/operator/softmax.hpp                          | 1 -
 1 file changed, 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
index b9539a5..955b61a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
@@ -23,7 +23,6 @@ namespace menoh_impl {
                   input_memory_cache_list.at(0);
                 auto input_dims = input_memory_cache.dims();
                 auto input_memory = input_memory_cache.get_data_memory();
-                auto input_format = extract_format(input_memory);
 
                 auto output_dims =
                   output_formatted_array_list.at(0).array().dims();

From afa9eb8e980b5117dec9631b64d39563341d49c6 Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Fri, 26 Oct 2018 17:54:45 +0900
Subject: [PATCH 234/321] change BatchNorm -> BatchNormalization

---
 .../backend/mkldnn/operator/batch_norm.hpp                      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
index 7effed4..d94f033 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
@@ -23,7 +23,7 @@ namespace menoh_impl {
                 auto spatial = attribute_int(node, "spatial");
                 if(!spatial) {
                     throw std::runtime_error(
-                      "Non spacial BatchNorm is not supported");
+                      "Non spacial BatchNormalization is not supported");
                 }
 
                 memory_cache& input_memory_cache =

From 57d044fe8354be5499453da4c00f925c77efa6f8 Mon Sep 17 00:00:00 2001
From: Yuta Okamoto <okapies@gmail.com>
Date: Fri, 26 Oct 2018 18:28:01 +0900
Subject: [PATCH 235/321] configure protobuf::protoc for older CMake

---
 CMakeLists.txt | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b4b3346..7fd9941 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,6 +65,18 @@ else()
     # See external/onnx/CMakeLists.txt for more details.
     include(FindProtobuf)
     find_package(Protobuf ${PROTOBUF_VERSION} REQUIRED)
+
+    # Note: `protobuf::protoc` is not supported in CMake 3.9.4 or older
+    if(NOT TARGET protobuf::protoc)
+        find_program(Protobuf_PROTOC_EXECUTABLE
+            NAMES protoc
+            DOC "The Google Protocol Buffers Compiler")
+        add_executable(protobuf::protoc IMPORTED)
+        if(EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
+            set_target_properties(protobuf::protoc PROPERTIES
+                IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
+        endif()
+    endif()
 endif()
 
 # Build libonnx.a

From 77c354e334be60cec88d5434487b9e9cac9899ed Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 26 Oct 2018 19:07:46 +0900
Subject: [PATCH 236/321] appveyor: specify python executable explicitly for
 MINGW build

For using /mingw64/bin/python3 instead of C:/Python27/python.exe.
---
 appveyor.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/appveyor.yml b/appveyor.yml
index 7f330f4..49cd17e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -73,7 +73,7 @@ build_script:
     )
   )
 - if [%TARGET%]==[mingw] (
-    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 .. &&
+    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 -DPYTHON_EXECUTABLE=/mingw64/bin/python3 .. &&
     make
   ) else (
     cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&

From d780353ef3cf17c22bcceb3b90595ae265d434b3 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 11:18:34 +0900
Subject: [PATCH 237/321] fix assert position

---
 test/operator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 7c758f1..ab03b8a 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -43,8 +43,8 @@ namespace {
 
         // TODO int array
         std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
-        assert(2 <= dims.size());
         if(squash_dims) {
+            assert(2 <= dims.size());
             dims.at(1) = std::accumulate(dims.begin() + 1, dims.end(), 1,
                                          std::multiplies<int>());
             dims.erase(dims.begin() + 2, dims.end());

From b40508ae285724d7e4c590298eefa2308ccecb01 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 11:18:34 +0900
Subject: [PATCH 238/321] fix assert position

---
 test/operator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index bbbfd34..f7b5d2c 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -43,8 +43,8 @@ namespace {
 
         // TODO int array
         std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
-        assert(2 <= dims.size());
         if(squash_dims) {
+            assert(2 <= dims.size());
             dims.at(1) = std::accumulate(dims.begin() + 1, dims.end(), 1,
                                          std::multiplies<int>());
             dims.erase(dims.begin() + 2, dims.end());

From 468f29a850c534b464b898471882a0556a83403b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 14:41:16 +0900
Subject: [PATCH 239/321] add naive implementation of Transpose

---
 .../backend/generic/generic_context.cpp       |  1 +
 .../backend/generic/operator.hpp              |  1 +
 .../backend/generic/operator/transpose.hpp    | 80 +++++++++++++++++++
 test/operator.cpp                             | 10 +++
 4 files changed, 92 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 7fee2d7..e01e9ae 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -7,6 +7,7 @@ namespace menoh_impl {
 
             generic_context::generic_context() : context() {
                 procedure_factory_table_.emplace("Relu", make_relu);
+                procedure_factory_table_.emplace("Transpose", make_transpose);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
index 56a8e40..c3e4b10 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
@@ -2,5 +2,6 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
new file mode 100644
index 0000000..d08f05b
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
@@ -0,0 +1,80 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
+
+#include <vector>
+#include <menoh/array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+
+            inline std::vector<int>
+            calc_strides(std::vector<int> const& dims) {
+                std::vector<int> strides({1});
+                for(int i = dims.size() - 1; i >= 1; --i) {
+                    strides.push_back(strides.back() * dims.at(i));
+                }
+                std::reverse(strides.begin(), strides.end());
+                return strides;
+            }
+
+            inline std::vector<int>
+            index_to_indices(int index, std::vector<int> const& strides) {
+                std::vector<int> indices;
+                for(auto s : strides) {
+                    indices.push_back(index / s);
+                    index %= s;
+                }
+                return indices;
+            }
+
+            inline int indices_to_index(std::vector<int> const& indices,
+                                        std::vector<int> const& strides) {
+                int index = 0;
+                for(int i = 0; i < indices.size(); ++i) {
+                    index += indices.at(i) * strides.at(i);
+                }
+                return index;
+            }
+
+            inline procedure
+            make_transpose(node const& node, std::vector<array> const& input_list,
+                           std::vector<array> const& output_list) {
+                assert(input_list.size() == 1);
+                assert(output_list.size() == 1);
+
+                auto input = input_list.at(0);
+                if(input.dtype() != dtype_t::float_) {
+                    throw std::runtime_error("not implemented yet");
+                }
+
+                auto perm = attribute_ints(node, "perm");
+                auto output = output_list.at(0);
+                auto input_strides = calc_strides(input.dims());
+                auto output_strides = calc_strides(output.dims());
+
+                auto procedure = [input, output, input_strides, output_strides,
+                                  perm]() {
+                    for(decltype(total_size(input)) i = 0;
+                        i < total_size(input); ++i) {
+                        auto input_indices = index_to_indices(i, input_strides);
+                        std::vector<int> output_indices;
+                        for(auto p : perm) {
+                            output_indices.push_back(input_indices.at(p));
+                        }
+                        fat(output,
+                            indices_to_index(output_indices, output_strides)) =
+                          fat(input,
+                              indices_to_index(input_indices, input_strides));
+                    }
+                };
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index 24d94ac..b3af6a9 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -266,6 +266,16 @@ namespace {
     TEST_OP(mkldnn_with_generic_fallback, test_softmax_example, eps);
     TEST_OP(mkldnn_with_generic_fallback, test_softmax_large_number, eps);
 
+    // Transpose
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_0, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_1, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_2, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_3, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_4, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_all_permutations_5, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_transpose_default, eps);
+
+
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP
 #undef TEST_OP_IMPL

From 79b85963440c2ed8c41559fd472211a104bef53b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 17:02:10 +0900
Subject: [PATCH 240/321] update vgg16 example

---
 benchmark/vgg16_benchmark.cpp    |  8 ++++----
 example/vgg16_example_in_cpp.cpp | 20 ++++++++++++--------
 scripts/retrieve_data.py         |  2 +-
 test/onnx.cpp                    |  2 +-
 4 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/benchmark/vgg16_benchmark.cpp b/benchmark/vgg16_benchmark.cpp
index 845b9f3..5e47d34 100644
--- a/benchmark/vgg16_benchmark.cpp
+++ b/benchmark/vgg16_benchmark.cpp
@@ -13,7 +13,7 @@ int main(int argc, char** argv) {
     cmdline::parser a;
     a.add<std::string>("input", '\0', "input_data");
     a.add<std::string>("model", '\0', "onnx model path", false,
-                       "../data/VGG16.onnx");
+                       "../data/vgg16.onnx");
     a.parse_check(argc, argv);
 
     constexpr auto category_num = 1000;
@@ -25,8 +25,8 @@ int main(int argc, char** argv) {
     auto onnx_model_path = a.get<std::string>("model");
 
     // Aliases to onnx's node input and output tensor name
-    auto conv1_1_in_name = "140326425860192";
-    auto softmax_out_name = "140326200803680";
+    auto conv1_1_in_name = "Input_0";
+    auto softmax_out_name = "Softmax_0";
 
     // Load ONNX model data
     auto model_data = menoh::make_model_data_from_onnx(onnx_model_path);
@@ -40,7 +40,7 @@ int main(int argc, char** argv) {
 
     // Build model
     menoh::model_builder model_builder(vpt);
-    auto model = model_builder.build_model(model_data, "mkldnn");
+    auto model = model_builder.build_model(model_data, "mkldnn_with_generic_fallback");
     model_data
       .reset(); // you can delete model_data explicitly after model building
 
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index 3d39ef9..e4c1318 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -15,14 +15,14 @@
 
 #include "../external/cmdline.h"
 
-auto reorder_to_chw(cv::Mat const& mat) {
+auto reorder_bgr_hwc_to_rgb_chw(cv::Mat const& mat) {
     assert(mat.channels() == 3);
     std::vector<float> data(mat.channels() * mat.rows * mat.cols);
     for(int y = 0; y < mat.rows; ++y) {
         for(int x = 0; x < mat.cols; ++x) {
             for(int c = 0; c < mat.channels(); ++c) {
                 data[c * (mat.rows * mat.cols) + y * mat.cols + x] =
-                  mat.at<cv::Vec3f>(y, x)[c];
+                  mat.at<cv::Vec3f>(y, x)[2 - c];
             }
         }
     }
@@ -67,9 +67,9 @@ int main(int argc, char** argv) {
     // Aliases to onnx's node input and output tensor name
     // Please use [Netron](https://github.com/lutzroeder/Netron)
     // See Menoh tutorial for more information.
-    const std::string conv1_1_in_name = "140326425860192";
-    const std::string fc6_out_name = "140326200777584";
-    const std::string softmax_out_name = "140326200803680";
+    const std::string conv1_1_in_name = "Input_0";
+    const std::string fc6_out_name = "Gemm_0";
+    const std::string softmax_out_name = "Softmax_0";
 
     const int batch_size = 1;
     const int channel_num = 3;
@@ -80,7 +80,7 @@ int main(int argc, char** argv) {
     a.add<std::string>("input_image", 'i', "input image path", false,
                        "../data/Light_sussex_hen.jpg");
     a.add<std::string>("model", 'm', "onnx model path", false,
-                       "../data/VGG16.onnx");
+                       "../data/vgg16.onnx");
     a.add<std::string>("synset_words", 's', "synset words path", false,
                        "../data/synset_words.txt");
     a.parse_check(argc, argv);
@@ -100,7 +100,7 @@ int main(int argc, char** argv) {
     cv::resize(image_mat, image_mat, cv::Size(width, height));
     image_mat.convertTo(image_mat, CV_32FC3);
     image_mat -= cv::Scalar(103.939, 116.779, 123.68); // subtract BGR mean
-    auto image_data = reorder_to_chw(image_mat);
+    auto image_data = reorder_bgr_hwc_to_rgb_chw(image_mat);
 
     // Load ONNX model data
     auto model_data = menoh::make_model_data_from_onnx(onnx_model_path);
@@ -119,6 +119,8 @@ int main(int argc, char** argv) {
     std::vector<float> fc6_out_data(std::accumulate(
       fc6_dims.begin(), fc6_dims.end(), 1, std::multiplies<int32_t>()));
 
+    model_data.optimize(vpt);
+
     // Make model_builder and attach extenal memory buffer
     // Variables which are not attached external memory buffer here are attached
     // internal memory buffers which are automatically allocated
@@ -139,7 +141,9 @@ int main(int argc, char** argv) {
       static_cast<float*>(softmax_output_var.buffer_handle);
 
     // Run inference
-    model.run();
+    try {
+        model.run();
+    } catch(std::exception const& e) { std::cout << e.what() << std::endl; }
 
     // Get output
     for(int i = 0; i < 10; ++i) {
diff --git a/scripts/retrieve_data.py b/scripts/retrieve_data.py
index 96567c9..c3da66e 100644
--- a/scripts/retrieve_data.py
+++ b/scripts/retrieve_data.py
@@ -13,7 +13,7 @@ def wget( address, target ):
         import urllib.request
         urllib.request.urlretrieve(address,  target)
 
-wget('https://www.dropbox.com/s/bjfn9kehukpbmcm/VGG16.onnx?dl=1', './data/VGG16.onnx')
+wget('https://preferredjp.box.com/shared/static/o2xip23e3f0knwc5ve78oderuglkf2wt.onnx', './data/vgg16.onnx')
 wget('https://raw.githubusercontent.com/HoldenCaulfieldRye/caffe/master/data/ilsvrc12/synset_words.txt', './data/synset_words.txt')
 wget('https://upload.wikimedia.org/wikipedia/commons/5/54/Light_sussex_hen.jpg', './data/Light_sussex_hen.jpg')
 
diff --git a/test/onnx.cpp b/test/onnx.cpp
index f2fa869..7d6798a 100644
--- a/test/onnx.cpp
+++ b/test/onnx.cpp
@@ -14,7 +14,7 @@ namespace menoh_impl {
     namespace {
         class ONNXTest : public ::testing::Test {
         public:
-            std::string model_filename{"../data/VGG16.onnx"};
+            std::string model_filename{"../data/vgg16.onnx"};
         };
 
         TEST_F(ONNXTest, make_model_data_from_onnx_file) {

From 7b87686d6b7573ed20032351392598df235391b0 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 17:40:44 +0900
Subject: [PATCH 241/321] add mkldnn `Sum` and `Add`

---
 .../backend/mkldnn/mkldnn_context.cpp         |  4 +
 .../backend/mkldnn/operator.hpp               |  1 +
 .../backend/mkldnn/operator/sum.hpp           | 84 +++++++++++++++++++
 test/operator.cpp                             |  9 ++
 4 files changed, 98 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 0c3d5ed..373b72b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -36,6 +36,10 @@ namespace menoh_impl {
               
                 // Softmax
                 procedure_factory_table_.emplace("Softmax", make_softmax);
+
+                // Sum and Add
+                procedure_factory_table_.emplace("Sum", make_sum);
+                procedure_factory_table_.emplace("Add", make_sum);
             }
 
             optional<std::tuple<std::vector<procedure>, int>>
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
index 7158053..f806124 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
@@ -7,5 +7,6 @@
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp>
 
 #endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
new file mode 100644
index 0000000..aac1252
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
@@ -0,0 +1,84 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
+
+#include <algorithm>
+
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+
+#include <mkldnn.hpp>
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace mkldnn_backend {
+
+            inline procedure_factory_return_type
+            make_sum(MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST) {
+
+                std::vector<mkldnn::primitive> primitives;
+
+                auto output_dims =
+                  output_formatted_array_list.at(0).array().dims();
+
+                auto output_md = mkldnn::memory::desc(
+                  {output_dims},
+                  dtype_to_mkldnn_memory_data_type(
+                    output_formatted_array_list.at(0).array().dtype()),
+                  mkldnn::memory::format::any);
+
+                std::vector<mkldnn::memory> input_memory_list;
+                for(memory_cache& input_memory_cache :
+                    input_memory_cache_list) {
+                    input_memory_list.push_back(
+                      input_memory_cache.get_data_memory());
+                }
+                assert(std::all_of(
+                         input_memory_list.begin() + 1, input_memory_list.end(),
+                         [&output_dims](auto const& e) {
+                             return extract_dims(e).at(0) == output_dims.at(0);
+                         }) &&
+                       "invalid shape inference");
+                if(!std::all_of(
+                     input_memory_list.begin() + 1, input_memory_list.end(),
+                     [first = input_memory_list.at(0)](auto const& e) {
+                         return extract_dims(e) == extract_dims(first);
+                     })) {
+                    throw std::runtime_error(
+                      "broadcasting is not supported yet");
+                }
+                std::vector<mkldnn::memory::primitive_desc>
+                  input_memory_pd_list;
+                for(auto const& input_memory : input_memory_list) {
+                    input_memory_pd_list.push_back(
+                      input_memory.get_primitive_desc());
+                }
+
+                auto sum_pd = mkldnn::sum::primitive_desc(
+                  output_md,
+                  std::vector<float>(node.input_name_list.size(), 1.f),
+                  input_memory_pd_list);
+
+                auto output_memory_cache = manage_output(
+                  output_formatted_array_list.at(0),
+                  input_memory_list.at(0).get_primitive_desc(), engine,
+                  primitives,
+                  [&sum_pd,
+                   &input_memory_list](mkldnn::memory const& output_memory) {
+                      std::vector<mkldnn::primitive::at> inputs(
+                        input_memory_list.begin(), input_memory_list.end());
+                      return mkldnn::sum(sum_pd, inputs, output_memory);
+                  });
+
+                return procedure_factory_return_type{
+                  primitives, {output_memory_cache}, {}};
+            }
+
+        } // namespace mkldnn_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
diff --git a/test/operator.cpp b/test/operator.cpp
index 67b57d8..1e47252 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -275,6 +275,15 @@ namespace {
     TEST_OP(mkldnn_with_generic_fallback, test_softmax_example, eps);
     TEST_OP(mkldnn_with_generic_fallback, test_softmax_large_number, eps);
 
+    // Sum and Add
+    TEST_OP(mkldnn_with_generic_fallback, test_sum_example, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_sum_one_input, eps);
+    TEST_OP(mkldnn_with_generic_fallback, test_sum_two_inputs, eps);
+    // TEST_OP(mkldnn_with_generic_fallback, test_add, eps); // ndims=3 is not
+    // implemented yet (mkldnn will support soon)
+    // TEST_OP(mkldnn_with_generic_fallback, test_add_bcast, eps); //broadcast
+    // is not implemented yet
+
 #undef TEST_OP_SQUASH_DIMS
 #undef TEST_OP
 #undef TEST_OP_IMPL

From e4a790874ec4de4a4f8f58318f386bacd36ff77d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 18:08:38 +0900
Subject: [PATCH 242/321] add ResNet50 example

---
 README.md                | 14 +++++++++-----
 scripts/retrieve_data.py |  1 +
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 7370afd..6bb7498 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ Execute following command in build directory created at Build section.
 make install
 ```
 
-# Run VGG16 example
+# Run VGG16 example (it can run Resnet50 as well)
 
 Execute following command in root directory.
 
@@ -97,6 +97,12 @@ top 5 categories are
 
 ```
 
+You can also run ResNet50
+
+```
+./example/vgg16_example_in_cpp -m ../data/resnet50.onnx
+```
+
 Please give `--help` option for details
 
 ```
@@ -155,7 +161,5 @@ make
 
 Menoh is released under MIT License. Please see the LICENSE file for details.
 
-Note: `scripts/retrieve_data.py` downloads `data/VGG16.onnx`. `data/VGG16.onnx` is generated by onnx-chainer from pre-trained model which is uploaded
-at http://www.robots.ox.ac.uk/%7Evgg/software/very_deep/caffe/VGG_ILSVRC_16_layers.caffemodel
-
-That pre-trained model is released under Creative Commons Attribution License.
+Pre-trained models downloaded via `retrieve_data.py` were converted by onnx-chainer. The original models were downloaded via [ChainerCV](https://github.com/chainer/chainercv).
+Check `scripts/generate_vgg16_onnx.py` and `scripts/generate_resnet50_onnx.py` and see [the LICENSE of ChainerCV](https://chainercv.readthedocs.io/en/stable/license.html) about each terms of use of the pre-trained models. 
diff --git a/scripts/retrieve_data.py b/scripts/retrieve_data.py
index 96567c9..5bb1844 100644
--- a/scripts/retrieve_data.py
+++ b/scripts/retrieve_data.py
@@ -14,6 +14,7 @@ def wget( address, target ):
         urllib.request.urlretrieve(address,  target)
 
 wget('https://www.dropbox.com/s/bjfn9kehukpbmcm/VGG16.onnx?dl=1', './data/VGG16.onnx')
+wget('https://preferredjp.box.com/shared/static/x4k1pya1w1vuvpfk77pp6ma8oaye8syb.onnx', './data/resnet50.onnx')
 wget('https://raw.githubusercontent.com/HoldenCaulfieldRye/caffe/master/data/ilsvrc12/synset_words.txt', './data/synset_words.txt')
 wget('https://upload.wikimedia.org/wikipedia/commons/5/54/Light_sussex_hen.jpg', './data/Light_sussex_hen.jpg')
 

From fe8ae8f2dec836521e1ef7379f532ac1fd21a6cd Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 19:25:29 +0900
Subject: [PATCH 243/321] fix error

---
 .../backend/generic/operator/mul.hpp              | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
index abcc45e..cc1c113 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
@@ -2,12 +2,13 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
 
 #include <menoh/array.hpp>
+#include <menoh/graph.hpp> // for dimension_mismatch error
 #include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace generic_backend {
-            inline procedure make_mul(node const&,
+            inline procedure make_mul(node const& node,
                                       std::vector<array> const& input_list,
                                       std::vector<array> const& output_list) {
                 assert(input_list.size() == 2);
@@ -15,11 +16,17 @@ namespace menoh_impl {
 
                 for(auto const& input : input_list) {
                     if(input.dtype() != dtype_t::float_) {
-                        throw std::runtime_error("invalid dtype");
+                        throw invalid_dtype(
+                          std::to_string(static_cast<int>(input.dtype())));
                     }
                 }
-                if(total_size(input_list.at(0)) != total_size(input_list.at(1))) {
-                    throw std::runtime_error("broadcast is not supported yet");
+                if(total_size(input_list.at(0)) !=
+                   total_size(input_list.at(1))) {
+                    throw dimension_mismatch(
+                      node.op_type, node.output_name_list.front(),
+                      "total size is invalid. broadcast is not supported yet",
+                      std::to_string(total_size(input_list.at(0))),
+                      std::to_string(total_size(input_list.at(1))));
                 }
 
                 auto procedure = [input_a = input_list.at(0),

From 2afbd1fc69be678bfb33385adf03d424182f4a9f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 29 Oct 2018 14:41:16 +0900
Subject: [PATCH 244/321] add naive implementation of Transpose

---
 .../backend/generic/generic_context.cpp                |  3 ++-
 .../backend/generic/operator/transpose.hpp             | 10 ++++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index c45ba48..d2c841a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -122,7 +122,8 @@ namespace menoh_impl {
                         auto found =
                           procedure_factory_table_.find(node.op_type);
                         if(found == procedure_factory_table_.end()) {
-                            throw std::runtime_error("factory not found for: " + node.op_type);
+                            throw std::runtime_error("factory not found for: " +
+                                                     node.op_type);
                         }
                         auto factory = found->second;
                         op_proc =
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
index d08f05b..0b4c7f5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
@@ -2,6 +2,7 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
 
 #include <vector>
+
 #include <menoh/array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
 
@@ -9,8 +10,7 @@ namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
         namespace generic_backend {
 
-            inline std::vector<int>
-            calc_strides(std::vector<int> const& dims) {
+            inline std::vector<int> calc_strides(std::vector<int> const& dims) {
                 std::vector<int> strides({1});
                 for(int i = dims.size() - 1; i >= 1; --i) {
                     strides.push_back(strides.back() * dims.at(i));
@@ -39,14 +39,16 @@ namespace menoh_impl {
             }
 
             inline procedure
-            make_transpose(node const& node, std::vector<array> const& input_list,
+            make_transpose(node const& node,
+                           std::vector<array> const& input_list,
                            std::vector<array> const& output_list) {
                 assert(input_list.size() == 1);
                 assert(output_list.size() == 1);
 
                 auto input = input_list.at(0);
                 if(input.dtype() != dtype_t::float_) {
-                    throw std::runtime_error("not implemented yet");
+                    throw invalid_dtype(
+                      std::to_string(static_cast<int>(input.dtype())));
                 }
 
                 auto perm = attribute_ints(node, "perm");

From bd62cce03d78ad70a80941ce1512b43d52f8c063 Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Tue, 30 Oct 2018 15:02:56 +0900
Subject: [PATCH 245/321] modify resnet name

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 6bb7498..c88e0ba 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ Execute following command in build directory created at Build section.
 make install
 ```
 
-# Run VGG16 example (it can run Resnet50 as well)
+# Run VGG16 example (it can run ResNet-50 as well)
 
 Execute following command in root directory.
 

From 5d64c1b621b7df999df65739fbb58c53470ff191 Mon Sep 17 00:00:00 2001
From: Shintarou Okada <kokuzen@gmail.com>
Date: Tue, 30 Oct 2018 15:04:02 +0900
Subject: [PATCH 246/321] modify ResNet50 -> ResNet-50

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index c88e0ba..5fbfded 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,7 @@ top 5 categories are
 
 ```
 
-You can also run ResNet50
+You can also run ResNet-50
 
 ```
 ./example/vgg16_example_in_cpp -m ../data/resnet50.onnx

From 699c203844e7e5ec10a8cbc6b340878090725499 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 30 Oct 2018 16:48:49 +0900
Subject: [PATCH 247/321] modify error type

---
 .../backend/mkldnn/operator/sum.hpp           | 32 +++++++++++++++++--
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
index aac1252..e55f61d 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
@@ -3,6 +3,8 @@
 
 #include <algorithm>
 
+#include <menoh/graph.hpp> // for dimension_mismatch error
+
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
@@ -10,7 +12,7 @@
 
 #include <mkldnn.hpp>
 
-#include <iostream>
+#include <sstream>
 
 namespace menoh_impl {
     namespace mkldnn_with_generic_fallback_backend {
@@ -47,8 +49,32 @@ namespace menoh_impl {
                      [first = input_memory_list.at(0)](auto const& e) {
                          return extract_dims(e) == extract_dims(first);
                      })) {
-                    throw std::runtime_error(
-                      "broadcasting is not supported yet");
+
+                    auto different_input_memory = std::find_if(
+                      input_memory_list.begin(), input_memory_list.end(),
+                      [first = input_memory_list.at(0)](auto const& e) {
+                          return extract_dims(e) != extract_dims(first);
+                      });
+                    auto index = static_cast<int>(different_input_memory -
+                                                  input_memory_list.begin());
+                    auto different_dims = extract_dims(*different_input_memory);
+                    auto dims_to_string = [](std::vector<int> const& dims) {
+                        std::stringstream ss;
+                        ss << "(";
+                        for(auto d : dims) {
+                            ss << d << " ";
+                        }
+                        ss << ")";
+                        return ss.str();
+                    };
+                    throw dimension_mismatch(
+                      node.op_type, node.output_name_list.front(),
+                      "input[" + std::to_string(index) +
+                        "] has different shape from "
+                        "the input[0]'s. broadcast "
+                        "is not supported yet",
+                      dims_to_string(different_dims),
+                      dims_to_string(extract_dims(input_memory_list.at(0))));
                 }
                 std::vector<mkldnn::memory::primitive_desc>
                   input_memory_pd_list;

From 45360154c9fc40ae50f2a874f118f6b6e311b417 Mon Sep 17 00:00:00 2001
From: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
Date: Thu, 1 Nov 2018 10:43:50 +0900
Subject: [PATCH 248/321] Add --iteration flag to vgg16_benchmark

so we will get more stable number. Also, now it up to three
digits after the decimal point.
---
 benchmark/vgg16_benchmark.cpp | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/benchmark/vgg16_benchmark.cpp b/benchmark/vgg16_benchmark.cpp
index 5e47d34..8f4f068 100644
--- a/benchmark/vgg16_benchmark.cpp
+++ b/benchmark/vgg16_benchmark.cpp
@@ -14,6 +14,7 @@ int main(int argc, char** argv) {
     a.add<std::string>("input", '\0', "input_data");
     a.add<std::string>("model", '\0', "onnx model path", false,
                        "../data/vgg16.onnx");
+    a.add<int>("iteration", '\0', "number of iterations", false, 1);
     a.parse_check(argc, argv);
 
     constexpr auto category_num = 1000;
@@ -50,14 +51,18 @@ int main(int argc, char** argv) {
       static_cast<float*>(model.get_buffer_handle(softmax_out_name));
     */
 
-    auto start = clock::now();
+    std::vector<std::chrono::microseconds> usecs;
 
-    // Run inference
-    model.run();
+    for (int i = 0; i < a.get<int>("iteration"); ++i) {
+        auto start = clock::now();
 
-    auto end = clock::now();
-    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end -
-                                                                       start)
-                   .count()
-              << std::endl;
+        // Run inference
+        model.run();
+
+        auto end = clock::now();
+        usecs.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end - start));
+    }
+
+    auto total_usec = std::accumulate(usecs.begin(), usecs.end(), std::chrono::microseconds());
+    std::cout << total_usec.count() / usecs.size() * 0.001 << " msec" << std::endl;
 }

From 5b565685fe38e1481bc2e53d08596d31e151cf21 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 1 Nov 2018 12:46:50 +0900
Subject: [PATCH 249/321] deal with new dtypes

---
 include/menoh/menoh.h                         |  9 ++-
 include/menoh/menoh.hpp                       | 11 +++-
 menoh/array.cpp                               | 32 ++++++---
 menoh/array.hpp                               | 18 +++++
 menoh/dtype.hpp                               | 31 ++++++++-
 menoh/mkldnn/utility.cpp                      | 18 +++++
 .../backend/mkldnn/memory_conversion.cpp      | 18 +++++
 menoh/onnx.cpp                                | 66 ++++++++++++-------
 8 files changed, 164 insertions(+), 39 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index b7a5fbd..adfcb28 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -44,7 +44,14 @@ extern "C" {
 /*! @ingroup vpt
  */
 enum menoh_dtype_constant {
-    menoh_dtype_float,
+    menoh_dtype_float, // float32
+    menoh_dtype_float16,
+    menoh_dtype_float32 = menoh_dtype_float,
+    menoh_dtype_float64 = menoh_dtype_float16 + 1,
+    menoh_dtype_int8,
+    menoh_dtype_int16,
+    menoh_dtype_int32,
+    menoh_dtype_int64,
 };
 /*! @ingroup vpt
  */
diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index b884971..0807b94 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -70,7 +70,16 @@ namespace menoh {
     };
     /** @} */
 
-    enum class dtype_t { float_ = menoh_dtype_float };
+    enum class dtype_t {
+        float_ = menoh_dtype_float, // float32
+        float16 = menoh_dtype_float16,
+        float32 = menoh_dtype_float32,
+        float64 = menoh_dtype_float64,
+        int8 = menoh_dtype_int8,
+        int16 = menoh_dtype_int16,
+        int32 = menoh_dtype_int32,
+        int64 = menoh_dtype_int64,
+    };
 
     class variable_profile_table;
 
diff --git a/menoh/array.cpp b/menoh/array.cpp
index 818c82d..9af963e 100644
--- a/menoh/array.cpp
+++ b/menoh/array.cpp
@@ -1,5 +1,7 @@
 #include <menoh/array.hpp>
 
+#include <cstdint>
+
 namespace menoh_impl {
 
     array::array(dtype_t d, std::vector<int> const& dims, void* data_handle)
@@ -13,13 +15,26 @@ namespace menoh_impl {
     std::shared_ptr<void> allocate_data(dtype_t d,
                                         std::vector<int> const& dims) {
         auto total_size = calc_total_size(dims);
-        if(d == dtype_t::float_) {
+        if(d == dtype_t::float_ || d == dtype_t::float32) {
             // libc++ workaround
             // Below 2 lines are equal to `return std::unique_ptr<float[]>(new
             // float[total_size]);`
             auto u = std::make_unique<float[]>(total_size);
             return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::int8) {
+            auto u = std::make_unique<std::int8_t[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::int16) {
+            auto u = std::make_unique<std::int16_t[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::int32) {
+            auto u = std::make_unique<std::int32_t[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::int64) {
+            auto u = std::make_unique<std::int64_t[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
         }
+
         throw invalid_dtype(std::to_string(static_cast<int>(d)));
     }
 
@@ -28,18 +43,15 @@ namespace menoh_impl {
 
     std::size_t total_size(array const& a) { return calc_total_size(a.dims()); }
 
-    float* fbegin(array const& a) {
-        assert(a.dtype() == dtype_t::float_);
-        return static_cast<float*>(a.data());
+    dtype_to_type_t<dtype_t::float32>* fbegin(array const& a) {
+        return begin<dtype_t::float32>(a);
     }
-    float* fend(array const& a) {
-        assert(a.dtype() == dtype_t::float_);
-        return fbegin(a) + total_size(a);
+    dtype_to_type_t<dtype_t::float32>* fend(array const& a) {
+        return end<dtype_t::float32>(a);
     }
 
-    float& fat(array const& a, std::size_t i) {
-        assert(a.dtype() == dtype_t::float_);
-        return *(static_cast<float*>(a.data()) + i);
+    dtype_to_type_t<dtype_t::float32>& fat(array const& a, std::size_t i) {
+        return at<dtype_t::float32>(a, i);
     }
 
     array zeros(dtype_t d, std::vector<int> const& dims) {
diff --git a/menoh/array.hpp b/menoh/array.hpp
index 9b9ce2c..3952c7c 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -81,6 +81,24 @@ namespace menoh_impl {
 
     array zeros(dtype_t d, std::vector<int> const& dims);
 
+    template <dtype_t dtype>
+    dtype_to_type_t<dtype>* begin(array const& a) {
+        assert(a.dtype() == dtype);
+        return static_cast<dtype_to_type_t<dtype>*>(a.data());
+    }
+
+    template <dtype_t dtype>
+    dtype_to_type_t<dtype>* end(array const& a) {
+        assert(a.dtype() == dtype);
+        return static_cast<dtype_to_type_t<dtype>*>(a.data());
+    }
+
+    template <dtype_t dtype>
+    dtype_to_type_t<dtype>& at(array const& a, std::size_t i) {
+        assert(a.dtype() == dtype);
+        return *(static_cast<dtype_to_type_t<dtype>*>(a.data()) + i);
+    }
+
 } // namespace menoh_impl
 
 #endif // MENOH_ARRAY_HPP
diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index c404506..95952fd 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -20,7 +20,14 @@ namespace menoh_impl {
 
     enum class dtype_t {
         undefined = -1,
-        float_ = menoh_dtype_float
+        float_ = menoh_dtype_float,
+        float16 = menoh_dtype_float16,
+        float32 = menoh_dtype_float32,
+        float64 = menoh_dtype_float64,
+        int8 = menoh_dtype_int8,
+        int16 = menoh_dtype_int16,
+        int32 = menoh_dtype_int32,
+        int64 = menoh_dtype_int64,
         // TODO more types
     };
     static_assert(dtype_t::undefined != dtype_t::float_, "");
@@ -38,10 +45,30 @@ namespace menoh_impl {
     struct dtype_to_type {};
 
     template <>
-    struct dtype_to_type<dtype_t::float_> {
+    struct dtype_to_type<dtype_t::float32> { // including dtype_t::float_
         using type = float;
     };
 
+    template <>
+    struct dtype_to_type<dtype_t::int8> {
+        using type = std::int8_t;
+    };
+
+    template <>
+    struct dtype_to_type<dtype_t::int16> {
+        using type = std::int16_t;
+    };
+
+    template <>
+    struct dtype_to_type<dtype_t::int32> {
+        using type = std::int32_t;
+    };
+
+    template <>
+    struct dtype_to_type<dtype_t::int64> {
+        using type = std::int64_t;
+    };
+
     template <dtype_t d>
     using dtype_to_type_t = typename dtype_to_type<d>::type;
 
diff --git a/menoh/mkldnn/utility.cpp b/menoh/mkldnn/utility.cpp
index 7393996..d7963c9 100644
--- a/menoh/mkldnn/utility.cpp
+++ b/menoh/mkldnn/utility.cpp
@@ -19,6 +19,15 @@ namespace menoh_impl {
             if(dtype == dtype_t::float_) {
                 return mkldnn::memory::data_type::f32;
             }
+            if(dtype == dtype_t::int8) {
+                return mkldnn::memory::data_type::s8;
+            }
+            if(dtype == dtype_t::int16) {
+                return mkldnn::memory::data_type::s16;
+            }
+            if(dtype == dtype_t::int32) {
+                return mkldnn::memory::data_type::s32;
+            }
             throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
         }
 
@@ -27,6 +36,15 @@ namespace menoh_impl {
             if(mem_data_type == mkldnn::memory::data_type::f32) {
                 return dtype_t::float_;
             }
+            if(mem_data_type == mkldnn::memory::data_type::s8) {
+                return dtype_t::int8;
+            }
+            if(mem_data_type == mkldnn::memory::data_type::s16) {
+                return dtype_t::int16;
+            }
+            if(mem_data_type == mkldnn::memory::data_type::s32) {
+                return dtype_t::int32;
+            }
             throw invalid_dtype(
               std::to_string(static_cast<int>(mem_data_type)));
         }
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
index cb18f6c..5c80f9e 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
@@ -47,6 +47,15 @@ namespace menoh_impl {
                 if(dtype == dtype_t::float_) {
                     return mkldnn::memory::data_type::f32;
                 }
+                if(dtype == dtype_t::int8) {
+                    return mkldnn::memory::data_type::s8;
+                }
+                if(dtype == dtype_t::int16) {
+                    return mkldnn::memory::data_type::s16;
+                }
+                if(dtype == dtype_t::int32) {
+                    return mkldnn::memory::data_type::s32;
+                }
                 throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
             }
 
@@ -55,6 +64,15 @@ namespace menoh_impl {
                 if(mem_data_type == mkldnn::memory::data_type::f32) {
                     return dtype_t::float_;
                 }
+                if(mem_data_type == mkldnn::memory::data_type::s8) {
+                    return dtype_t::int8;
+                }
+                if(mem_data_type == mkldnn::memory::data_type::s16) {
+                    return dtype_t::int16;
+                }
+                if(mem_data_type == mkldnn::memory::data_type::s32) {
+                    return dtype_t::int32;
+                }
                 throw invalid_dtype(
                   std::to_string(static_cast<int>(mem_data_type)));
             }
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index dce8553..8ec1d23 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -25,6 +25,14 @@ namespace menoh_impl {
     dtype_t tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt) {
         if(tpdt == onnx::TensorProto_DataType_FLOAT) {
             return dtype_t::float_;
+        } else if(tpdt == onnx::TensorProto_DataType_INT8) {
+            return dtype_t::int8;
+        } else if(tpdt == onnx::TensorProto_DataType_INT16) {
+            return dtype_t::int16;
+        } else if(tpdt == onnx::TensorProto_DataType_INT32) {
+            return dtype_t::int32;
+        } else if(tpdt == onnx::TensorProto_DataType_INT64) {
+            return dtype_t::int64;
         }
         throw invalid_dtype(std::to_string(tpdt));
     }
@@ -75,6 +83,25 @@ namespace menoh_impl {
         return needed_parameter_name_set;
     }
 
+    template <menoh_impl::dtype_t dtype>
+    auto move_tensor_from_onnx_data(int total_size, onnx::TensorProto& tensor) {
+        // libc++ workaround
+        // Below 2 lines are equal to `data =
+        // std::unique_ptr<float_t[]>(new float_t[total_size]);`
+        using dtype_type = dtype_to_type_t<dtype>;
+        auto u = std::make_unique<dtype_type[]>(total_size);
+        auto data = std::shared_ptr<void>(u.release(), u.get_deleter());
+        // TODO other format: float_data
+        assert(tensor.has_raw_data());
+        assert(tensor.raw_data().length() ==
+               static_cast<decltype(tensor.raw_data().length())>(
+                 total_size * size_in_bytes<dtype>));
+        std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
+                  static_cast<char*>(data.get()));
+        delete tensor.release_raw_data();
+        return data;
+    }
+
     auto extract_parameter_name_and_array_list_from_onnx_graph(
       onnx::GraphProto& graph,
       std::vector<std::string> const& needed_parameter_name_list) {
@@ -93,35 +120,24 @@ namespace menoh_impl {
             auto total_size = std::accumulate(dims.begin(), dims.end(), 1,
                                               std::multiplies<int>());
 
-            // FIXME workaround for Reshape-5
-            if(tensor.data_type() == onnx::TensorProto_DataType_INT64) {
-                parameter_name_and_array_list.push_back(
-                  {tensor.name(),
-                   menoh_impl::array(dtype_t::float_, std::move(dims))});
-            }
-            // end workaround
-
             dtype_t d = tensor_proto_data_type_to_dtype(tensor.data_type());
 
             std::shared_ptr<void> data;
             if(d == menoh_impl::dtype_t::float_) {
-                using float_t =
-                  menoh_impl::dtype_to_type_t<menoh_impl::dtype_t::float_>;
-                // libc++ workaround
-                // Below 2 lines are equal to `data =
-                // std::unique_ptr<float_t[]>(new float_t[total_size]);`
-                auto u = std::make_unique<float_t[]>(total_size);
-                data = std::shared_ptr<void>(u.release(), u.get_deleter());
-                // TODO other format: float_data
-                assert(tensor.has_raw_data());
-                assert(tensor.raw_data().length() ==
-                       static_cast<decltype(tensor.raw_data().length())>(
-                         total_size * 4));
-                std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
-                          static_cast<char*>(data.get()));
-                delete tensor.release_raw_data();
-            } else {
-                throw invalid_dtype(std::to_string(tensor.data_type()));
+                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::float_>(
+                  total_size, tensor);
+            } else if(d == menoh_impl::dtype_t::int8) {
+                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int8>(
+                  total_size, tensor);
+            } else if(d == menoh_impl::dtype_t::int16) {
+                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int16>(
+                  total_size, tensor);
+            } else if(d == menoh_impl::dtype_t::int32) {
+                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int32>(
+                  total_size, tensor);
+            } else if(d == menoh_impl::dtype_t::int64) {
+                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int64>(
+                  total_size, tensor);
             }
             parameter_name_and_array_list.push_back(
               {tensor.name(),

From ecf2f226f4edc0258895aa602527ce8c4c7f38ad Mon Sep 17 00:00:00 2001
From: Shinichiro Hamaji <shinichiro.hamaji@gmail.com>
Date: Thu, 1 Nov 2018 21:26:00 +0900
Subject: [PATCH 250/321] Use microseconds::zero instead of the default

---
 benchmark/vgg16_benchmark.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/benchmark/vgg16_benchmark.cpp b/benchmark/vgg16_benchmark.cpp
index 8f4f068..729a40d 100644
--- a/benchmark/vgg16_benchmark.cpp
+++ b/benchmark/vgg16_benchmark.cpp
@@ -63,6 +63,6 @@ int main(int argc, char** argv) {
         usecs.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end - start));
     }
 
-    auto total_usec = std::accumulate(usecs.begin(), usecs.end(), std::chrono::microseconds());
+    auto total_usec = std::accumulate(usecs.begin(), usecs.end(), std::chrono::microseconds::zero());
     std::cout << total_usec.count() / usecs.size() * 0.001 << " msec" << std::endl;
 }

From 4c80a99aa713c40df15008b94163f3682eb73818 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 2 Nov 2018 20:11:29 +0900
Subject: [PATCH 251/321] add int types

---
 menoh/array.cpp                                        | 10 ++++++++--
 menoh/dtype.hpp                                        | 10 ++++++++++
 menoh/mkldnn/utility.cpp                               |  3 ++-
 .../backend/mkldnn/memory_conversion.cpp               |  3 ++-
 menoh/onnx.cpp                                         |  2 ++
 5 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/menoh/array.cpp b/menoh/array.cpp
index 9af963e..a22e735 100644
--- a/menoh/array.cpp
+++ b/menoh/array.cpp
@@ -15,12 +15,18 @@ namespace menoh_impl {
     std::shared_ptr<void> allocate_data(dtype_t d,
                                         std::vector<int> const& dims) {
         auto total_size = calc_total_size(dims);
-        if(d == dtype_t::float_ || d == dtype_t::float32) {
+        if(d == dtype_t::float16) {
             // libc++ workaround
             // Below 2 lines are equal to `return std::unique_ptr<float[]>(new
             // float[total_size]);`
+            auto u = std::make_unique<std::int16_t[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::float32) {
             auto u = std::make_unique<float[]>(total_size);
             return std::shared_ptr<void>(u.release(), u.get_deleter());
+        } else if(d == dtype_t::float64) {
+            auto u = std::make_unique<double[]>(total_size);
+            return std::shared_ptr<void>(u.release(), u.get_deleter());
         } else if(d == dtype_t::int8) {
             auto u = std::make_unique<std::int8_t[]>(total_size);
             return std::shared_ptr<void>(u.release(), u.get_deleter());
@@ -36,7 +42,7 @@ namespace menoh_impl {
         }
 
         throw invalid_dtype(std::to_string(static_cast<int>(d)));
-    }
+    } // namespace menoh_impl
 
     array::array(dtype_t d, std::vector<int> const& dims)
       : array(d, dims, allocate_data(d, dims)) {}
diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index 95952fd..78d555c 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -44,11 +44,21 @@ namespace menoh_impl {
     template <dtype_t>
     struct dtype_to_type {};
 
+    template <>
+    struct dtype_to_type<dtype_t::float16> {
+        using type = std::int16_t;
+    };
+
     template <>
     struct dtype_to_type<dtype_t::float32> { // including dtype_t::float_
         using type = float;
     };
 
+    template <>
+    struct dtype_to_type<dtype_t::float64> {
+        using type = double;
+    };
+
     template <>
     struct dtype_to_type<dtype_t::int8> {
         using type = std::int8_t;
diff --git a/menoh/mkldnn/utility.cpp b/menoh/mkldnn/utility.cpp
index d7963c9..f0bcc19 100644
--- a/menoh/mkldnn/utility.cpp
+++ b/menoh/mkldnn/utility.cpp
@@ -16,7 +16,8 @@ namespace menoh_impl {
 
         mkldnn::memory::data_type
         dtype_to_mkldnn_memory_data_type(dtype_t dtype) {
-            if(dtype == dtype_t::float_) {
+            // float16 and float64 is not supported by MKLDNN
+            if(dtype == dtype_t::float32) {
                 return mkldnn::memory::data_type::f32;
             }
             if(dtype == dtype_t::int8) {
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
index 5c80f9e..3f2d15c 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
@@ -44,7 +44,8 @@ namespace menoh_impl {
 
             mkldnn::memory::data_type
             dtype_to_mkldnn_memory_data_type(dtype_t dtype) {
-                if(dtype == dtype_t::float_) {
+                // float16 and float64 is not supported by MKLDNN
+                if(dtype == dtype_t::float32) {
                     return mkldnn::memory::data_type::f32;
                 }
                 if(dtype == dtype_t::int8) {
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 8ec1d23..1f15673 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -138,6 +138,8 @@ namespace menoh_impl {
             } else if(d == menoh_impl::dtype_t::int64) {
                 data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int64>(
                   total_size, tensor);
+            } else {
+                throw invalid_dtype(std::to_string(tensor.data_type()));
             }
             parameter_name_and_array_list.push_back(
               {tensor.name(),

From 445ecf0aeae6a7d5a575c395a16da51c33366450 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 5 Nov 2018 21:34:53 +0900
Subject: [PATCH 252/321] fix bug in `end()`

---
 menoh/array.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/array.hpp b/menoh/array.hpp
index 3952c7c..8f7435c 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -90,7 +90,7 @@ namespace menoh_impl {
     template <dtype_t dtype>
     dtype_to_type_t<dtype>* end(array const& a) {
         assert(a.dtype() == dtype);
-        return static_cast<dtype_to_type_t<dtype>*>(a.data());
+        return static_cast<dtype_to_type_t<dtype>*>(a.data()) + total_size(a);
     }
 
     template <dtype_t dtype>

From 41e67c3319dd203239a0883f96d35718534a571c Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 6 Nov 2018 15:30:18 +0900
Subject: [PATCH 253/321] remove useless file

---
 .../computation_node_factory.hpp              | 27 -------------------
 .../model_core.cpp                            |  1 -
 2 files changed, 28 deletions(-)
 delete mode 100644 menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp b/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp
deleted file mode 100644
index 3cf8bae..0000000
--- a/menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
-#define MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
-
-#include <functional>
-#include <memory>
-#include <tuple>
-#include <unordered_map>
-#include <vector>
-
-#include <menoh/array.hpp>
-
-namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback {
-
-        using computation_node_factory_return_type =
-          std::tuple<std::function<void()>,
-                     std::vector<std::pair<std::string, array>>>;
-
-        using computation_node_factory =
-          std::function<computation_node_factory_return_type(
-            int32_t, std::vector<node> const&,
-            std::unordered_map<std::string, array> const&)>;
-
-    } // namespace mkldnn_with_generic_fallback
-} // namespace menoh_impl
-
-#endif // MENOH_MKLDNN_WITH_FALLBACK_COMPUTATION_FACTORY_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/mkldnn_with_generic_fallback/model_core.cpp
index ad9b019..7e993f7 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/mkldnn_with_generic_fallback/model_core.cpp
@@ -4,7 +4,6 @@
 #include <cassert>
 #include <memory>
 
-#include <menoh/mkldnn_with_generic_fallback/computation_node_factory.hpp>
 #include <menoh/mkldnn_with_generic_fallback/context.hpp>
 
 #include <menoh/mkldnn/utility.hpp>

From 93851755b006096650eebd9d8d685ea0e9006c93 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 7 Nov 2018 11:10:36 +0900
Subject: [PATCH 254/321] implement generic reshape

---
 ...tribute_completion_and_shape_inference.hpp | 38 ++++++++++++++++
 .../backend/generic/generic_context.cpp       |  1 +
 .../backend/generic/operator.hpp              |  3 +-
 .../backend/mkldnn/mkldnn_context.cpp         | 34 +++++++-------
 .../backend/mkldnn/mkldnn_context.hpp         |  4 ++
 menoh/onnx.cpp                                |  1 -
 ...bute_completion_and_shape_inference_hpp.py | 27 +++++++++++
 test/operator.cpp                             | 45 ++++++++++++++-----
 8 files changed, 122 insertions(+), 31 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index 49f474a..dbd2453 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -875,6 +875,44 @@ add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 else
 
 
+if(node.op_type == "Reshape") {
+    
+    
+    
+    {
+        
+        
+auto found = std::find_if(model_data.parameter_name_and_array_list.begin(),
+                          model_data.parameter_name_and_array_list.end(),
+                          [shape_name=node.input_name_list.at(1)](
+                            auto const& p){ return p.first == shape_name; });
+assert(found != model_data.parameter_name_and_array_list.end());
+auto shape = found->second;
+std::vector<int> new_dims(menoh_impl::begin<dtype_t::int64>(shape),
+                          menoh_impl::end<dtype_t::int64>(shape));
+for(unsigned int i = 0; i < new_dims.size(); ++i) {
+    if(new_dims.at(i) == 0) {
+        assert(i < ndims_of(input(0)));
+        new_dims.at(i) = dims_of(input(0)).at(i);
+    }
+    auto found =
+      std::find(new_dims.begin(), new_dims.end(), -1);
+    if(found != new_dims.end()) {
+        auto other_size =
+          -std::accumulate(new_dims.begin(), new_dims.end(),
+                           1, std::multiplies<>());
+        auto total_size = calc_total_size(dims_of(input(0)));
+        assert(total_size % other_size == 0);
+        *found = total_size / other_size;
+    }
+}
+add_variable_to_table(output(0), dtype_of(input(0)), new_dims);
+
+    }
+}
+else
+
+
 if(node.op_type == "Sigmoid") {
     
     
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
index 51cf051..444aed4 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
@@ -7,6 +7,7 @@ namespace menoh_impl {
 
             generic_context::generic_context() : context() {
                 procedure_factory_table_.emplace("Relu", make_relu);
+                procedure_factory_table_.emplace("Reshape", make_reshape);
                 procedure_factory_table_.emplace("Mul", make_mul);
                 procedure_factory_table_.emplace("Sigmoid", make_sigmoid);
                 procedure_factory_table_.emplace("Transpose", make_transpose);
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
index 6386fe0..15dc52b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
@@ -1,8 +1,9 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
+#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp>
 #include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp>
 
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
index 373b72b..d379dfb 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
@@ -79,6 +79,23 @@ namespace menoh_impl {
                           input_memory_cache_list;
                         for(auto const& input_name : node.input_name_list) {
                             do {
+                                // search in self variable table
+                                {
+                                    auto found =
+                                      variable_memory_cache_table_.find(
+                                        input_name);
+                                    if(found !=
+                                       variable_memory_cache_table_.end()) {
+                                        *logger << input_name
+                                                << " is found from self "
+                                                   "variable table"
+                                                << std::endl;
+                                        input_memory_cache_list.push_back(
+                                          found->second);
+                                        break;
+                                    }
+                                }
+
                                 // search in common parameter table
                                 {
                                     auto found =
@@ -102,23 +119,6 @@ namespace menoh_impl {
                                     }
                                 }
 
-                                // search in self variable table
-                                {
-                                    auto found =
-                                      variable_memory_cache_table_.find(
-                                        input_name);
-                                    if(found !=
-                                       variable_memory_cache_table_.end()) {
-                                        *logger << input_name
-                                                << " is found from self "
-                                                   "variable table"
-                                                << std::endl;
-                                        input_memory_cache_list.push_back(
-                                          found->second);
-                                        break;
-                                    }
-                                }
-
                                 // search in common input table
                                 {
                                     auto found =
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
index 6821ef6..167130a 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
@@ -40,6 +40,10 @@ namespace menoh_impl {
                                  ndims_to_data_memory_format(
                                    variable_memory_cache.dims().size()),
                                  primitives);
+                    assert(extract_format(variable_memory) ==
+                             mkldnn::memory::format::nchw ||
+                           extract_format(variable_memory) ==
+                             mkldnn::memory::format::nc);
                     procedure copy_proc =
                       primitives.empty()
                         ? procedure(nullptr)
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 1f15673..58afd28 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -14,7 +14,6 @@
 #include <onnx/onnx.pb.h>
 
 #include <menoh/array.hpp>
-#include <menoh/dtype.hpp>
 #include <menoh/exception.hpp>
 #include <menoh/graph.hpp>
 #include <menoh/model_data.hpp>
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index ab2bbca..86571e0 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -341,6 +341,33 @@ def main():
         dims_of(input(0)), dims_of(input(1))));
 '''))
     code_list.append(make_completion_code("Relu"))
+    code_list.append(make_completion_code("Reshape", [], '''
+auto found = std::find_if(model_data.parameter_name_and_array_list.begin(),
+                          model_data.parameter_name_and_array_list.end(),
+                          [shape_name=node.input_name_list.at(1)](
+                            auto const& p){ return p.first == shape_name; });
+assert(found != model_data.parameter_name_and_array_list.end());
+auto shape = found->second;
+std::vector<int> new_dims(menoh_impl::begin<dtype_t::int64>(shape),
+                          menoh_impl::end<dtype_t::int64>(shape));
+for(unsigned int i = 0; i < new_dims.size(); ++i) {
+    if(new_dims.at(i) == 0) {
+        assert(i < ndims_of(input(0)));
+        new_dims.at(i) = dims_of(input(0)).at(i);
+    }
+    auto found =
+      std::find(new_dims.begin(), new_dims.end(), -1);
+    if(found != new_dims.end()) {
+        auto other_size =
+          -std::accumulate(new_dims.begin(), new_dims.end(),
+                           1, std::multiplies<>());
+        auto total_size = calc_total_size(dims_of(input(0)));
+        assert(total_size % other_size == 0);
+        *found = total_size / other_size;
+    }
+}
+add_variable_to_table(output(0), dtype_of(input(0)), new_dims);
+'''))
     code_list.append(make_completion_code("Sigmoid"))
     code_list.append(make_completion_code("Softmax", [("axis", "int", "1")]))
     code_list.append(make_completion_code("Sum"))
diff --git a/test/operator.cpp b/test/operator.cpp
index c724617..aa31d95 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -52,16 +52,30 @@ namespace {
         auto total_size =
           std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int>());
         assert(tensor.has_raw_data());
-        assert(
-          tensor.raw_data().length() ==
-          static_cast<decltype(tensor.raw_data().length())>(total_size * 4));
-
-        auto data = std::make_unique<char[]>(total_size * 4);
-        std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
-                  data.get());
-        // TODO other dtype
-        return named_array_data{tensor.name(), menoh::dtype_t::float_,
-                                std::move(dims), std::move(data)};
+        if(tensor.data_type() == onnx::TensorProto_DataType_FLOAT) {
+            assert(tensor.raw_data().length() ==
+                   static_cast<decltype(tensor.raw_data().length())>(
+                     total_size * 4));
+
+            auto data = std::make_unique<char[]>(total_size * 4);
+            std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
+                      data.get());
+            // TODO other dtype
+            return named_array_data{tensor.name(), menoh::dtype_t::float32,
+                                    std::move(dims), std::move(data)};
+        }
+        if(tensor.data_type() == onnx::TensorProto_DataType_INT64) {
+            assert(tensor.raw_data().length() ==
+                   static_cast<decltype(tensor.raw_data().length())>(
+                     total_size * 8));
+
+            auto data = std::make_unique<char[]>(total_size * 8);
+            std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
+                      data.get());
+            // TODO other dtype
+            return named_array_data{tensor.name(), menoh::dtype_t::int64,
+                                    std::move(dims), std::move(data)};
+        }
     }
 
     class OperatorTest : public ::testing::Test {
@@ -210,8 +224,8 @@ namespace {
     TEST_OP(mkldnn, test_globalaveragepool_precomputed, eps);
     TEST_OP(mkldnn, test_globalmaxpool, eps);
     TEST_OP(mkldnn, test_globalmaxpool_precomputed, eps);
-    //TEST_OP(mkldnn, test_globalaveragepool, eps);
-    //TEST_OP(mkldnn, test_globalmaxpool, eps);
+    // TEST_OP(mkldnn, test_globalaveragepool, eps);
+    // TEST_OP(mkldnn, test_globalmaxpool, eps);
     TEST_OP(mkldnn, test_maxpool_2d_default, eps);
     TEST_OP_SQUASH_DIMS(mkldnn, test_softmax_axis_1, eps);
     // TEST_OP_SQUASH_DIMS(mkldnn, test_sum_one_input, eps);
@@ -278,6 +292,13 @@ namespace {
     //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_with_argmax_2d_precomputed_pads, eps);
     //TEST_OP(mkldnn_with_generic_fallback, test_maxpool_with_argmax_2d_precomputed_strides, eps);
 
+    // Reshape
+    //TEST_OP(mkldnn_with_generic_fallback, test_reshape_extended_dims, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_reshape_negative_dim, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_reshape_one_dim, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_reshape_reduced_dims, eps);
+    //TEST_OP(mkldnn_with_generic_fallback, test_reshape_reordered_dims, eps);
+
     // Softmax
     //TEST_OP(mkldnn_with_generic_fallback, test_softmax_axis_0, eps);
     //TEST_OP(mkldnn_with_generic_fallback, test_softmax_axis_1, eps);

From 46aedc2c0cc5624da58aff1d20ca6f09f281bc73 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 7 Nov 2018 18:25:00 +0900
Subject: [PATCH 255/321] add reshape file

---
 .../backend/generic/operator/reshape.hpp      | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp
new file mode 100644
index 0000000..043fcff
--- /dev/null
+++ b/menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp
@@ -0,0 +1,32 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
+
+#include <menoh/array.hpp>
+#include <menoh/graph.hpp> // for dimension_mismatch error
+#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+
+namespace menoh_impl {
+    namespace mkldnn_with_generic_fallback_backend {
+        namespace generic_backend {
+            inline procedure
+            make_reshape(node const& node, std::vector<array> const& input_list,
+                         std::vector<array> const& output_list) {
+                assert(input_list.size() == 2);
+                assert(output_list.size() == 1);
+
+                auto procedure = [data = input_list.at(0),
+                                  output = output_list.at(0)]() {
+                    assert(total_size(data) == total_size(output));
+                    std::copy(begin<dtype_t::float32>(data),
+                              end<dtype_t::float32>(data),
+                              begin<dtype_t::float32>(output));
+                };
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace mkldnn_with_generic_fallback_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP

From fef0281024a6c84fdfa60375389e92c2b5c74927 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 6 Nov 2018 15:22:56 +0900
Subject: [PATCH 256/321] rename mkldnn_with_generic_fallback
 combinated_backends

---
 .../backend/generic/generic_context.cpp        |  8 ++++----
 .../backend/generic/generic_context.hpp        | 12 ++++++------
 .../backend/generic/operator.hpp               |  9 +++++++++
 .../backend/generic/operator/mul.hpp           |  6 +++---
 .../backend/generic/operator/relu.hpp          |  6 +++---
 .../backend/generic/operator/reshape.hpp       |  0
 .../backend/generic/operator/sigmoid.hpp       |  6 +++---
 .../backend/generic/operator/transpose.hpp     |  6 +++---
 .../backend/mkldnn/formatted_array.hpp         |  6 +++---
 .../backend/mkldnn/memory_cache.cpp            |  6 +++---
 .../backend/mkldnn/memory_cache.hpp            |  6 +++---
 .../backend/mkldnn/memory_conversion.cpp       |  6 +++---
 .../backend/mkldnn/memory_conversion.hpp       |  4 ++--
 .../backend/mkldnn/mkldnn_context.cpp          | 12 ++++++------
 .../backend/mkldnn/mkldnn_context.hpp          | 18 +++++++++---------
 .../backend/mkldnn/operator.hpp                | 12 ++++++++++++
 .../backend/mkldnn/operator/batch_norm.hpp     | 12 ++++++------
 .../backend/mkldnn/operator/conv.hpp           | 12 ++++++------
 .../backend/mkldnn/operator/eltwise.hpp        | 12 ++++++------
 .../backend/mkldnn/operator/gemm.hpp           | 12 ++++++------
 .../mkldnn/operator/output_management.hpp      |  8 ++++----
 .../backend/mkldnn/operator/pool.hpp           | 12 ++++++------
 .../backend/mkldnn/operator/softmax.hpp        | 12 ++++++------
 .../backend/mkldnn/operator/sum.hpp            | 12 ++++++------
 .../backend/mkldnn/procedure_factory.hpp       | 12 ++++++------
 .../context.hpp                                |  8 ++++----
 .../logger.hpp                                 |  4 ++--
 .../model_core.cpp                             | 10 +++++-----
 .../model_core.hpp                             |  8 ++++----
 menoh/combinated_backends/procedure.hpp        | 12 ++++++++++++
 .../backend/generic/operator.hpp               | 10 ----------
 .../backend/mkldnn/operator.hpp                | 12 ------------
 .../mkldnn_with_generic_fallback/procedure.hpp | 12 ------------
 menoh/model_core_factory.cpp                   | 16 ++++++++--------
 34 files changed, 159 insertions(+), 160 deletions(-)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/generic_context.cpp (96%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/generic_context.hpp (86%)
 create mode 100644 menoh/combinated_backends/backend/generic/operator.hpp
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/operator/mul.hpp (91%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/operator/relu.hpp (86%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/operator/reshape.hpp (100%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/operator/sigmoid.hpp (89%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/generic/operator/transpose.hpp (94%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/formatted_array.hpp (90%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/memory_cache.cpp (96%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/memory_cache.hpp (95%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/memory_conversion.cpp (97%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/memory_conversion.hpp (95%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/mkldnn_context.cpp (97%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/mkldnn_context.hpp (85%)
 create mode 100644 menoh/combinated_backends/backend/mkldnn/operator.hpp
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/batch_norm.hpp (92%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/conv.hpp (93%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/eltwise.hpp (89%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/gemm.hpp (92%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/output_management.hpp (91%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/pool.hpp (89%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/softmax.hpp (81%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/operator/sum.hpp (91%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/backend/mkldnn/procedure_factory.hpp (75%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/context.hpp (92%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/logger.hpp (76%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/model_core.cpp (94%)
 rename menoh/{mkldnn_with_generic_fallback => combinated_backends}/model_core.hpp (86%)
 create mode 100644 menoh/combinated_backends/procedure.hpp
 delete mode 100644 menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
 delete mode 100644 menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
 delete mode 100644 menoh/mkldnn_with_generic_fallback/procedure.hpp

diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp b/menoh/combinated_backends/backend/generic/generic_context.cpp
similarity index 96%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
rename to menoh/combinated_backends/backend/generic/generic_context.cpp
index 444aed4..1d99864 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.cpp
+++ b/menoh/combinated_backends/backend/generic/generic_context.cpp
@@ -1,8 +1,8 @@
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp>
+#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
+#include <menoh/combinated_backends/backend/generic/operator.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
 
             generic_context::generic_context() : context() {
@@ -162,5 +162,5 @@ namespace menoh_impl {
                 return std::make_tuple(procedure_list, current_index);
             }
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp b/menoh/combinated_backends/backend/generic/generic_context.hpp
similarity index 86%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
rename to menoh/combinated_backends/backend/generic/generic_context.hpp
index cdfda3f..d2801fd 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp
+++ b/menoh/combinated_backends/backend/generic/generic_context.hpp
@@ -1,10 +1,10 @@
-#ifndef MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
-#define MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
+#ifndef MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
+#define MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+#include <menoh/combinated_backends/context.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
 
             class generic_context final : public context {
@@ -61,7 +61,7 @@ namespace menoh_impl {
             };
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
-#endif // MENOH_MKLDNN_WITH_FALLBACK_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
+#endif // MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
diff --git a/menoh/combinated_backends/backend/generic/operator.hpp b/menoh/combinated_backends/backend/generic/operator.hpp
new file mode 100644
index 0000000..1a32637
--- /dev/null
+++ b/menoh/combinated_backends/backend/generic/operator.hpp
@@ -0,0 +1,9 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+
+#include <menoh/combinated_backends/backend/generic/operator/relu.hpp>
+#include <menoh/combinated_backends/backend/generic/operator/mul.hpp>
+#include <menoh/combinated_backends/backend/generic/operator/sigmoid.hpp>
+#include <menoh/combinated_backends/backend/generic/operator/transpose.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp b/menoh/combinated_backends/backend/generic/operator/mul.hpp
similarity index 91%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
rename to menoh/combinated_backends/backend/generic/operator/mul.hpp
index cc1c113..24a0096 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp
+++ b/menoh/combinated_backends/backend/generic/operator/mul.hpp
@@ -3,10 +3,10 @@
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp> // for dimension_mismatch error
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/combinated_backends/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
             inline procedure make_mul(node const& node,
                                       std::vector<array> const& input_list,
@@ -42,7 +42,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp b/menoh/combinated_backends/backend/generic/operator/relu.hpp
similarity index 86%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
rename to menoh/combinated_backends/backend/generic/operator/relu.hpp
index b5d278a..848a1bf 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp
+++ b/menoh/combinated_backends/backend/generic/operator/relu.hpp
@@ -2,10 +2,10 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
 
 #include <menoh/array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/combinated_backends/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
             inline procedure make_relu(node const&,
                                        std::vector<array> const& input_list,
@@ -25,7 +25,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp b/menoh/combinated_backends/backend/generic/operator/reshape.hpp
similarity index 100%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp
rename to menoh/combinated_backends/backend/generic/operator/reshape.hpp
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp b/menoh/combinated_backends/backend/generic/operator/sigmoid.hpp
similarity index 89%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp
rename to menoh/combinated_backends/backend/generic/operator/sigmoid.hpp
index 4a2e742..f537646 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp
+++ b/menoh/combinated_backends/backend/generic/operator/sigmoid.hpp
@@ -4,10 +4,10 @@
 #include <cmath>
 
 #include <menoh/array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/combinated_backends/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
             inline procedure
             make_sigmoid(node const&, std::vector<array> const& input_list,
@@ -34,7 +34,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp b/menoh/combinated_backends/backend/generic/operator/transpose.hpp
similarity index 94%
rename from menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
rename to menoh/combinated_backends/backend/generic/operator/transpose.hpp
index 0b4c7f5..439bc9e 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp
+++ b/menoh/combinated_backends/backend/generic/operator/transpose.hpp
@@ -4,10 +4,10 @@
 #include <vector>
 
 #include <menoh/array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/combinated_backends/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace generic_backend {
 
             inline std::vector<int> calc_strides(std::vector<int> const& dims) {
@@ -76,7 +76,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp b/menoh/combinated_backends/backend/mkldnn/formatted_array.hpp
similarity index 90%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp
rename to menoh/combinated_backends/backend/mkldnn/formatted_array.hpp
index 22bfcfe..af2ad86 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/formatted_array.hpp
@@ -3,12 +3,12 @@
 
 #include <menoh/array.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             class formatted_array {
@@ -48,7 +48,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp b/menoh/combinated_backends/backend/mkldnn/memory_cache.cpp
similarity index 96%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
rename to menoh/combinated_backends/backend/mkldnn/memory_cache.cpp
index 4ae0a1e..29d69c5 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.cpp
+++ b/menoh/combinated_backends/backend/mkldnn/memory_cache.cpp
@@ -1,9 +1,9 @@
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
 
 #include <numeric> // for accumulate
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             std::tuple<mkldnn::memory, optional<mkldnn::primitive>>
@@ -123,5 +123,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp b/menoh/combinated_backends/backend/mkldnn/memory_cache.hpp
similarity index 95%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
rename to menoh/combinated_backends/backend/mkldnn/memory_cache.hpp
index a4d66c8..ee38470 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/memory_cache.hpp
@@ -7,12 +7,12 @@
 #include <menoh/array.hpp>
 #include <menoh/optional.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             class memory_cache {
@@ -100,7 +100,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp b/menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp
similarity index 97%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
rename to menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp
index 3f2d15c..862d097 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.cpp
+++ b/menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp
@@ -1,7 +1,7 @@
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             bool is_data_format(mkldnn::memory::format format) {
@@ -171,5 +171,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp b/menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp
similarity index 95%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp
rename to menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp
index 9d6d2a2..05298a0 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp
@@ -6,7 +6,7 @@
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             bool is_data_format(mkldnn::memory::format format);
@@ -49,7 +49,7 @@ namespace menoh_impl {
                                                 mkldnn::engine const& engine);
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp b/menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp
similarity index 97%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
rename to menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp
index d379dfb..47a5e91 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp
@@ -1,15 +1,15 @@
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_conversion.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator.hpp>
 
 #include <menoh/graph.hpp> // for unsupported_operator error
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             mkldnn_context::mkldnn_context() : context() {
-                using namespace mkldnn_with_generic_fallback_backend::
+                using namespace combinated_backends::
                   mkldnn_backend;
               
                 // BatchNormalization
@@ -266,5 +266,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp b/menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp
similarity index 85%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
rename to menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp
index 167130a..6c1611b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
-#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#ifndef MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#define MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
 
 #include <string>
 #include <unordered_map>
@@ -12,14 +12,14 @@
 #include <menoh/mkldnn/utility.hpp>
 #include <menoh/model_core.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+#include <menoh/combinated_backends/context.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             class mkldnn_context final : public context {
@@ -93,7 +93,7 @@ namespace menoh_impl {
             };
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#endif // MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator.hpp b/menoh/combinated_backends/backend/mkldnn/operator.hpp
new file mode 100644
index 0000000..859cd06
--- /dev/null
+++ b/menoh/combinated_backends/backend/mkldnn/operator.hpp
@@ -0,0 +1,12 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+
+#include <menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/conv.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/pool.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/sum.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp b/menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp
similarity index 92%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp
index d94f033..3ca4113 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_batch_norm(
@@ -112,7 +112,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp b/menoh/combinated_backends/backend/mkldnn/operator/conv.hpp
similarity index 93%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/conv.hpp
index 0fcd313..50569bd 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/conv.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -124,7 +124,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp b/menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp
similarity index 89%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp
index 18558a1..9ab15fe 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_eltwise(
@@ -78,7 +78,7 @@ namespace menoh_impl {
 #undef MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp b/menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp
similarity index 92%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp
index 9617914..bda27f7 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -117,7 +117,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp b/menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp
similarity index 91%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp
index 38d2719..4873bc6 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp
@@ -1,13 +1,13 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             template <typename PrimitiveGen>
@@ -58,7 +58,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp b/menoh/combinated_backends/backend/mkldnn/operator/pool.hpp
similarity index 89%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/pool.hpp
index 083092a..1e9c428 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/pool.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_pool_impl(
@@ -87,7 +87,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp b/menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp
similarity index 81%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp
index 955b61a..289c8f0 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_softmax(
@@ -49,7 +49,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp b/menoh/combinated_backends/backend/mkldnn/operator/sum.hpp
similarity index 91%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
rename to menoh/combinated_backends/backend/mkldnn/operator/sum.hpp
index e55f61d..9bb646b 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/operator/sum.hpp
@@ -5,17 +5,17 @@
 
 #include <menoh/graph.hpp> // for dimension_mismatch error
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/formatted_array.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 #include <sstream>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -104,7 +104,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp b/menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp
similarity index 75%
rename from menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
rename to menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp
index 98cb8d5..1067246 100644
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/procedure_factory.hpp
+++ b/menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp
@@ -1,11 +1,11 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
-#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#ifndef MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#define MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
 
 #include <string>
 #include <utility>
 #include <vector>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/memory_cache.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
 #include <mkldnn.hpp>
 
 #define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST          \
@@ -19,7 +19,7 @@
     node, input_memory_cache_list, output_formatted_array_list, engine
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         namespace mkldnn_backend {
 
             struct procedure_factory_return_type {
@@ -40,6 +40,6 @@ namespace menoh_impl {
                 )>;
 
         } // namespace mkldnn_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace combinated_backends
 } // namespace menoh_impl
-#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#endif // MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/context.hpp b/menoh/combinated_backends/context.hpp
similarity index 92%
rename from menoh/mkldnn_with_generic_fallback/context.hpp
rename to menoh/combinated_backends/context.hpp
index 98c4b48..dd77381 100644
--- a/menoh/mkldnn_with_generic_fallback/context.hpp
+++ b/menoh/combinated_backends/context.hpp
@@ -8,11 +8,11 @@
 #include <menoh/node.hpp>
 #include <menoh/optional.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/logger.hpp>
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/combinated_backends/logger.hpp>
+#include <menoh/combinated_backends/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
 
         class context {
         public:
@@ -74,7 +74,7 @@ namespace menoh_impl {
         };
         inline context::~context(){}
 
-    } // namespace mkldnn_with_generic_fallback_backend
+    } // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/logger.hpp b/menoh/combinated_backends/logger.hpp
similarity index 76%
rename from menoh/mkldnn_with_generic_fallback/logger.hpp
rename to menoh/combinated_backends/logger.hpp
index 84c642d..2301f27 100644
--- a/menoh/mkldnn_with_generic_fallback/logger.hpp
+++ b/menoh/combinated_backends/logger.hpp
@@ -4,10 +4,10 @@
 #include <iostream>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
         using logger = std::unique_ptr<std::ostream>;
         using logger_handle = std::ostream*;
-    } // namespace mkldnn_with_generic_fallback_backend
+    } // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.cpp b/menoh/combinated_backends/model_core.cpp
similarity index 94%
rename from menoh/mkldnn_with_generic_fallback/model_core.cpp
rename to menoh/combinated_backends/model_core.cpp
index 7e993f7..8fc56bd 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.cpp
+++ b/menoh/combinated_backends/model_core.cpp
@@ -1,4 +1,4 @@
-#include <menoh/mkldnn_with_generic_fallback/model_core.hpp>
+#include <menoh/combinated_backends/model_core.hpp>
 
 #include <algorithm>
 #include <cassert>
@@ -17,7 +17,7 @@
 #include <iosfwd>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
 
         model_core::model_core(
           std::vector<std::pair<std::string, std::unique_ptr<context>>>
@@ -44,12 +44,12 @@ namespace menoh_impl {
                         logger_->rdbuf(std::cout.rdbuf());
                     } else if(log_output == "file") {
                         logger_.reset(new std::ofstream(
-                          "mkldnn_with_generic_fallback_backend_log.txt"));
+                          "combinated_backends_log.txt"));
                     } else {
                         throw invalid_backend_config_error(
                           "invalid value of \"log_output\": " + log_output);
                     }
-                    *logger_ << "mkldnn_with_generic_fallback_backend log"
+                    *logger_ << "combinated_backends log"
                              << std::endl;
                 }
             }
@@ -124,5 +124,5 @@ namespace menoh_impl {
             }
         }
 
-    } // namespace mkldnn_with_generic_fallback_backend
+    } // namespace combinated_backends
 } // namespace menoh_impl
diff --git a/menoh/mkldnn_with_generic_fallback/model_core.hpp b/menoh/combinated_backends/model_core.hpp
similarity index 86%
rename from menoh/mkldnn_with_generic_fallback/model_core.hpp
rename to menoh/combinated_backends/model_core.hpp
index dc19dc4..285e65e 100644
--- a/menoh/mkldnn_with_generic_fallback/model_core.hpp
+++ b/menoh/combinated_backends/model_core.hpp
@@ -11,11 +11,11 @@
 #include <menoh/model_data.hpp>
 #include <menoh/backend_config.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/logger.hpp>
+#include <menoh/combinated_backends/context.hpp>
+#include <menoh/combinated_backends/logger.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace combinated_backends {
 
         class model_core final : public menoh_impl::model_core {
         public:
@@ -41,7 +41,7 @@ namespace menoh_impl {
             std::vector<procedure> procedure_list_;
         };
 
-    } // namespace mkldnn_with_generic_fallback_backend
+    } // namespace combinated_backends
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_FALLBACK_MODEL_CORE_HPP
diff --git a/menoh/combinated_backends/procedure.hpp b/menoh/combinated_backends/procedure.hpp
new file mode 100644
index 0000000..bcdede1
--- /dev/null
+++ b/menoh/combinated_backends/procedure.hpp
@@ -0,0 +1,12 @@
+#ifndef MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
+#define MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
+
+#include <functional>
+
+namespace menoh_impl {
+namespace combinated_backends {
+    using procedure = std::function<void()>;
+} // namespace combinated_backends
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
deleted file mode 100644
index 15dc52b..0000000
--- a/menoh/mkldnn_with_generic_fallback/backend/generic/operator.hpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
-
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/mul.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/relu.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/reshape.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/sigmoid.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/operator/transpose.hpp>
-
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp b/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
deleted file mode 100644
index f806124..0000000
--- a/menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
-#define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
-
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/batch_norm.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/conv.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/eltwise.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/gemm.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/pool.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/softmax.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/operator/sum.hpp>
-
-#endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/mkldnn_with_generic_fallback/procedure.hpp b/menoh/mkldnn_with_generic_fallback/procedure.hpp
deleted file mode 100644
index ae6c94d..0000000
--- a/menoh/mkldnn_with_generic_fallback/procedure.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
-#define MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
-
-#include <functional>
-
-namespace menoh_impl {
-namespace mkldnn_with_generic_fallback_backend {
-    using procedure = std::function<void()>;
-} // namespace mkldnn_with_generic_fallback_backend
-} // namespace menoh_impl
-
-#endif // MENOH_IMPL_MKLDNN_WITH_FALLBACK_BACKEND_PROCEDURE_HPP
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index aa47dd4..cc4b7a5 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -2,10 +2,10 @@
 #include <menoh/model_core_factory.hpp>
 
 #include <menoh/mkldnn/model_core.hpp>
-#include <menoh/mkldnn_with_generic_fallback/model_core.hpp>
+#include <menoh/combinated_backends/model_core.hpp>
 
-#include <menoh/mkldnn_with_generic_fallback/backend/generic/generic_context.hpp>
-#include <menoh/mkldnn_with_generic_fallback/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
 
 namespace menoh_impl {
 
@@ -21,19 +21,19 @@ namespace menoh_impl {
             return std::make_unique<mkldnn_backend::model_core>(
               mkldnn_backend::make_model_core(input_table, required_output_table,
                                               model_data, config));
-        } else if(backend_name == "mkldnn_with_generic_fallback") {
-            using namespace mkldnn_with_generic_fallback_backend;
+        } else if(backend_name == "combinated_backends") {
+            using namespace combinated_backends;
             std::vector<std::pair<std::string, std::unique_ptr<context>>>
               context_list;
             context_list.emplace_back(
-              "mkldnn", std::make_unique<mkldnn_with_generic_fallback_backend::
+              "mkldnn", std::make_unique<combinated_backends::
                                            mkldnn_backend::mkldnn_context>());
             context_list.emplace_back(
               "generic",
-              std::make_unique<mkldnn_with_generic_fallback_backend::
+              std::make_unique<combinated_backends::
                                  generic_backend::generic_context>());
             return std::make_unique<
-              mkldnn_with_generic_fallback_backend::model_core>(
+              combinated_backends::model_core>(
               std::move(context_list), input_table, required_output_table,
               output_profile_table, model_data, config);
         }

From 35dc1ddad51394dec31891a0a3dd952e87b57bf8 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 6 Nov 2018 17:04:19 +0900
Subject: [PATCH 257/321] context can be selectable with backend_config

---
 example/vgg16_example_in_cpp.cpp         |  4 ++-
 menoh/combinated_backends/model_core.cpp | 44 +++++++++++++++++++++---
 menoh/combinated_backends/model_core.hpp | 13 +++++--
 menoh/model_core_factory.cpp             | 40 +++++++--------------
 4 files changed, 66 insertions(+), 35 deletions(-)

diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index e4c1318..d9c2bd9 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -131,7 +131,9 @@ int main(int argc, char** argv) {
       fc6_out_name, static_cast<void*>(fc6_out_data.data()));
 
     // Build model
-    auto model = model_builder.build_model(model_data, "mkldnn");
+    auto model = model_builder.build_model(
+      model_data, "combinated_backends",
+      R"({"backends":[{"type":"mkldnn"}, {"type":"generic"}], "log_output":"stdout"})");
     model_data
       .reset(); // you can delete model_data explicitly after model building
 
diff --git a/menoh/combinated_backends/model_core.cpp b/menoh/combinated_backends/model_core.cpp
index 8fc56bd..42c9eeb 100644
--- a/menoh/combinated_backends/model_core.cpp
+++ b/menoh/combinated_backends/model_core.cpp
@@ -4,7 +4,8 @@
 #include <cassert>
 #include <memory>
 
-#include <menoh/mkldnn_with_generic_fallback/context.hpp>
+#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
+#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
 
 #include <menoh/mkldnn/utility.hpp>
 
@@ -19,6 +20,40 @@
 namespace menoh_impl {
     namespace combinated_backends {
 
+        model_core make_model_core(
+          std::unordered_map<std::string, array> const& input_table,
+          std::unordered_map<std::string, array> const& output_table,
+          std::unordered_map<std::string, array_profile> const&
+            output_profile_table,
+          menoh_impl::model_data const& model_data,
+          backend_config const& config) {
+            std::vector<std::pair<std::string, std::unique_ptr<context>>>
+              context_list;
+            auto c = nlohmann::json::parse(config);
+            if(c.find("backends") != c.end()) {
+                auto backends = c["backends"];
+                for(auto backend : backends) {
+                    if(backend.find("type") == backend.end()) {
+                        throw invalid_backend_config_error("type not found");
+                    }
+                    if(backend["type"].get<std::string>() == "mkldnn") {
+                        context_list.emplace_back(
+                          "mkldnn",
+                          std::make_unique<combinated_backends::mkldnn_backend::
+                                             mkldnn_context>());
+                    } else if(backend["type"].get<std::string>() == "generic") {
+                        context_list.emplace_back(
+                          "generic", std::make_unique<
+                                       combinated_backends::generic_backend::
+                                         generic_context>());
+                    }
+                }
+            }
+            return model_core(std::move(context_list), input_table,
+                              output_table, output_profile_table, model_data,
+                              config);
+        }
+
         model_core::model_core(
           std::vector<std::pair<std::string, std::unique_ptr<context>>>
             context_list,
@@ -43,14 +78,13 @@ namespace menoh_impl {
                     if(log_output == "stdout") {
                         logger_->rdbuf(std::cout.rdbuf());
                     } else if(log_output == "file") {
-                        logger_.reset(new std::ofstream(
-                          "combinated_backends_log.txt"));
+                        logger_.reset(
+                          new std::ofstream("combinated_backends_log.txt"));
                     } else {
                         throw invalid_backend_config_error(
                           "invalid value of \"log_output\": " + log_output);
                     }
-                    *logger_ << "combinated_backends log"
-                             << std::endl;
+                    *logger_ << "combinated_backends log" << std::endl;
                 }
             }
 
diff --git a/menoh/combinated_backends/model_core.hpp b/menoh/combinated_backends/model_core.hpp
index 285e65e..a0dec3c 100644
--- a/menoh/combinated_backends/model_core.hpp
+++ b/menoh/combinated_backends/model_core.hpp
@@ -7,9 +7,9 @@
 #include <unordered_map>
 
 #include <menoh/array.hpp>
+#include <menoh/backend_config.hpp>
 #include <menoh/model_core.hpp>
 #include <menoh/model_data.hpp>
-#include <menoh/backend_config.hpp>
 
 #include <menoh/combinated_backends/context.hpp>
 #include <menoh/combinated_backends/logger.hpp>
@@ -26,7 +26,8 @@ namespace menoh_impl {
               std::unordered_map<std::string, array> const& output_table,
               std::unordered_map<std::string, array_profile> const&
                 output_profile_table,
-              menoh_impl::model_data const& model_data, backend_config const& config);
+              menoh_impl::model_data const& model_data,
+              backend_config const& config);
 
         private:
             virtual void do_run() override;
@@ -41,6 +42,14 @@ namespace menoh_impl {
             std::vector<procedure> procedure_list_;
         };
 
+        model_core make_model_core(
+          std::unordered_map<std::string, array> const& input_table,
+          std::unordered_map<std::string, array> const& output_table,
+          std::unordered_map<std::string, array_profile> const&
+            output_profile_table,
+          menoh_impl::model_data const& model_data,
+          backend_config const& config);
+
     } // namespace combinated_backends
 } // namespace menoh_impl
 
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index cc4b7a5..6eb41a9 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -1,41 +1,27 @@
 #include <menoh/model_core.hpp>
 #include <menoh/model_core_factory.hpp>
 
-#include <menoh/mkldnn/model_core.hpp>
 #include <menoh/combinated_backends/model_core.hpp>
-
-#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/mkldnn/model_core.hpp>
 
 namespace menoh_impl {
 
-    std::unique_ptr<menoh_impl::model_core>
-    make_model_core(std::unordered_map<std::string, array> const& input_table,
-                    std::unordered_map<std::string, array> const& required_output_table,
-                    std::unordered_map<std::string, array_profile> const&
-                      output_profile_table,
-                    menoh_impl::model_data const& model_data,
-                    std::string const& backend_name,
-                    backend_config const& config) {
+    std::unique_ptr<menoh_impl::model_core> make_model_core(
+      std::unordered_map<std::string, array> const& input_table,
+      std::unordered_map<std::string, array> const& required_output_table,
+      std::unordered_map<std::string, array_profile> const&
+        output_profile_table,
+      menoh_impl::model_data const& model_data, std::string const& backend_name,
+      backend_config const& config) {
         if(backend_name == "mkldnn") {
             return std::make_unique<mkldnn_backend::model_core>(
-              mkldnn_backend::make_model_core(input_table, required_output_table,
-                                              model_data, config));
+              mkldnn_backend::make_model_core(
+                input_table, required_output_table, model_data, config));
         } else if(backend_name == "combinated_backends") {
-            using namespace combinated_backends;
-            std::vector<std::pair<std::string, std::unique_ptr<context>>>
-              context_list;
-            context_list.emplace_back(
-              "mkldnn", std::make_unique<combinated_backends::
-                                           mkldnn_backend::mkldnn_context>());
-            context_list.emplace_back(
-              "generic",
-              std::make_unique<combinated_backends::
-                                 generic_backend::generic_context>());
             return std::make_unique<
-              combinated_backends::model_core>(
-              std::move(context_list), input_table, required_output_table,
-              output_profile_table, model_data, config);
+              combinated_backends::model_core>(combinated_backends::make_model_core(
+              input_table, required_output_table,
+              output_profile_table, model_data, config));
         }
 
         throw invalid_backend_name(backend_name);

From e849c89512660dd46fe9738449fe33d8acfce206 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 7 Nov 2018 12:16:21 +0900
Subject: [PATCH 258/321] rename combinated_backends composite_backend

---
 .../backend/generic/operator.hpp               |  9 ---------
 .../backend/mkldnn/operator.hpp                | 12 ------------
 menoh/combinated_backends/procedure.hpp        | 12 ------------
 .../backend/generic/generic_context.cpp        |  8 ++++----
 .../backend/generic/generic_context.hpp        | 12 ++++++------
 .../backend/generic/operator.hpp               |  9 +++++++++
 .../backend/generic/operator/mul.hpp           |  6 +++---
 .../backend/generic/operator/relu.hpp          |  6 +++---
 .../backend/generic/operator/reshape.hpp       |  0
 .../backend/generic/operator/sigmoid.hpp       |  6 +++---
 .../backend/generic/operator/transpose.hpp     |  6 +++---
 .../backend/mkldnn/formatted_array.hpp         |  6 +++---
 .../backend/mkldnn/memory_cache.cpp            |  6 +++---
 .../backend/mkldnn/memory_cache.hpp            |  6 +++---
 .../backend/mkldnn/memory_conversion.cpp       |  6 +++---
 .../backend/mkldnn/memory_conversion.hpp       |  4 ++--
 .../backend/mkldnn/mkldnn_context.cpp          | 12 ++++++------
 .../backend/mkldnn/mkldnn_context.hpp          | 18 +++++++++---------
 .../backend/mkldnn/operator.hpp                | 12 ++++++++++++
 .../backend/mkldnn/operator/batch_norm.hpp     | 12 ++++++------
 .../backend/mkldnn/operator/conv.hpp           | 12 ++++++------
 .../backend/mkldnn/operator/eltwise.hpp        | 12 ++++++------
 .../backend/mkldnn/operator/gemm.hpp           | 12 ++++++------
 .../mkldnn/operator/output_management.hpp      |  8 ++++----
 .../backend/mkldnn/operator/pool.hpp           | 12 ++++++------
 .../backend/mkldnn/operator/softmax.hpp        | 12 ++++++------
 .../backend/mkldnn/operator/sum.hpp            | 12 ++++++------
 .../backend/mkldnn/procedure_factory.hpp       | 12 ++++++------
 .../context.hpp                                |  8 ++++----
 .../logger.hpp                                 |  4 ++--
 .../model_core.cpp                             | 18 +++++++++---------
 .../model_core.hpp                             |  8 ++++----
 menoh/composite_backend/procedure.hpp          | 12 ++++++++++++
 menoh/model_core_factory.cpp                   | 12 ++++++------
 34 files changed, 161 insertions(+), 161 deletions(-)
 delete mode 100644 menoh/combinated_backends/backend/generic/operator.hpp
 delete mode 100644 menoh/combinated_backends/backend/mkldnn/operator.hpp
 delete mode 100644 menoh/combinated_backends/procedure.hpp
 rename menoh/{combinated_backends => composite_backend}/backend/generic/generic_context.cpp (97%)
 rename menoh/{combinated_backends => composite_backend}/backend/generic/generic_context.hpp (88%)
 create mode 100644 menoh/composite_backend/backend/generic/operator.hpp
 rename menoh/{combinated_backends => composite_backend}/backend/generic/operator/mul.hpp (93%)
 rename menoh/{combinated_backends => composite_backend}/backend/generic/operator/relu.hpp (89%)
 rename menoh/{combinated_backends => composite_backend}/backend/generic/operator/reshape.hpp (100%)
 rename menoh/{combinated_backends => composite_backend}/backend/generic/operator/sigmoid.hpp (91%)
 rename menoh/{combinated_backends => composite_backend}/backend/generic/operator/transpose.hpp (96%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/formatted_array.hpp (92%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/memory_cache.cpp (97%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/memory_cache.hpp (96%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/memory_conversion.cpp (97%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/memory_conversion.hpp (96%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/mkldnn_context.cpp (97%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/mkldnn_context.hpp (87%)
 create mode 100644 menoh/composite_backend/backend/mkldnn/operator.hpp
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/batch_norm.hpp (93%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/conv.hpp (94%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/eltwise.hpp (90%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/gemm.hpp (93%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/output_management.hpp (92%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/pool.hpp (91%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/softmax.hpp (84%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/operator/sum.hpp (92%)
 rename menoh/{combinated_backends => composite_backend}/backend/mkldnn/procedure_factory.hpp (79%)
 rename menoh/{combinated_backends => composite_backend}/context.hpp (94%)
 rename menoh/{combinated_backends => composite_backend}/logger.hpp (82%)
 rename menoh/{combinated_backends => composite_backend}/model_core.cpp (92%)
 rename menoh/{combinated_backends => composite_backend}/model_core.hpp (91%)
 create mode 100644 menoh/composite_backend/procedure.hpp

diff --git a/menoh/combinated_backends/backend/generic/operator.hpp b/menoh/combinated_backends/backend/generic/operator.hpp
deleted file mode 100644
index 1a32637..0000000
--- a/menoh/combinated_backends/backend/generic/operator.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
-
-#include <menoh/combinated_backends/backend/generic/operator/relu.hpp>
-#include <menoh/combinated_backends/backend/generic/operator/mul.hpp>
-#include <menoh/combinated_backends/backend/generic/operator/sigmoid.hpp>
-#include <menoh/combinated_backends/backend/generic/operator/transpose.hpp>
-
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator.hpp b/menoh/combinated_backends/backend/mkldnn/operator.hpp
deleted file mode 100644
index 859cd06..0000000
--- a/menoh/combinated_backends/backend/mkldnn/operator.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
-#define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
-
-#include <menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/conv.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/pool.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/sum.hpp>
-
-#endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/combinated_backends/procedure.hpp b/menoh/combinated_backends/procedure.hpp
deleted file mode 100644
index bcdede1..0000000
--- a/menoh/combinated_backends/procedure.hpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
-#define MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
-
-#include <functional>
-
-namespace menoh_impl {
-namespace combinated_backends {
-    using procedure = std::function<void()>;
-} // namespace combinated_backends
-} // namespace menoh_impl
-
-#endif // MENOH_IMPL_COMBINATED_BACKENDS_PROCEDURE_HPP
diff --git a/menoh/combinated_backends/backend/generic/generic_context.cpp b/menoh/composite_backend/backend/generic/generic_context.cpp
similarity index 97%
rename from menoh/combinated_backends/backend/generic/generic_context.cpp
rename to menoh/composite_backend/backend/generic/generic_context.cpp
index 1d99864..2f4fbb4 100644
--- a/menoh/combinated_backends/backend/generic/generic_context.cpp
+++ b/menoh/composite_backend/backend/generic/generic_context.cpp
@@ -1,8 +1,8 @@
-#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
-#include <menoh/combinated_backends/backend/generic/operator.hpp>
+#include <menoh/composite_backend/backend/generic/generic_context.hpp>
+#include <menoh/composite_backend/backend/generic/operator.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
 
             generic_context::generic_context() : context() {
@@ -162,5 +162,5 @@ namespace menoh_impl {
                 return std::make_tuple(procedure_list, current_index);
             }
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
diff --git a/menoh/combinated_backends/backend/generic/generic_context.hpp b/menoh/composite_backend/backend/generic/generic_context.hpp
similarity index 88%
rename from menoh/combinated_backends/backend/generic/generic_context.hpp
rename to menoh/composite_backend/backend/generic/generic_context.hpp
index d2801fd..50c9cc2 100644
--- a/menoh/combinated_backends/backend/generic/generic_context.hpp
+++ b/menoh/composite_backend/backend/generic/generic_context.hpp
@@ -1,10 +1,10 @@
-#ifndef MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
-#define MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
+#ifndef MENOH_COMPOSITE_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
+#define MENOH_COMPOSITE_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
 
-#include <menoh/combinated_backends/context.hpp>
+#include <menoh/composite_backend/context.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
 
             class generic_context final : public context {
@@ -61,7 +61,7 @@ namespace menoh_impl {
             };
 
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_COMBINATED_BACKENDS_GENERIC_GENERIC_CONTEXT_HPP
+#endif // MENOH_COMPOSITE_BACKEND_GENERIC_GENERIC_CONTEXT_HPP
diff --git a/menoh/composite_backend/backend/generic/operator.hpp b/menoh/composite_backend/backend/generic/operator.hpp
new file mode 100644
index 0000000..80c11ee
--- /dev/null
+++ b/menoh/composite_backend/backend/generic/operator.hpp
@@ -0,0 +1,9 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+
+#include <menoh/composite_backend/backend/generic/operator/relu.hpp>
+#include <menoh/composite_backend/backend/generic/operator/mul.hpp>
+#include <menoh/composite_backend/backend/generic/operator/sigmoid.hpp>
+#include <menoh/composite_backend/backend/generic/operator/transpose.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/combinated_backends/backend/generic/operator/mul.hpp b/menoh/composite_backend/backend/generic/operator/mul.hpp
similarity index 93%
rename from menoh/combinated_backends/backend/generic/operator/mul.hpp
rename to menoh/composite_backend/backend/generic/operator/mul.hpp
index 24a0096..1bb6577 100644
--- a/menoh/combinated_backends/backend/generic/operator/mul.hpp
+++ b/menoh/composite_backend/backend/generic/operator/mul.hpp
@@ -3,10 +3,10 @@
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp> // for dimension_mismatch error
-#include <menoh/combinated_backends/procedure.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
             inline procedure make_mul(node const& node,
                                       std::vector<array> const& input_list,
@@ -42,7 +42,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
diff --git a/menoh/combinated_backends/backend/generic/operator/relu.hpp b/menoh/composite_backend/backend/generic/operator/relu.hpp
similarity index 89%
rename from menoh/combinated_backends/backend/generic/operator/relu.hpp
rename to menoh/composite_backend/backend/generic/operator/relu.hpp
index 848a1bf..505d8f2 100644
--- a/menoh/combinated_backends/backend/generic/operator/relu.hpp
+++ b/menoh/composite_backend/backend/generic/operator/relu.hpp
@@ -2,10 +2,10 @@
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
 
 #include <menoh/array.hpp>
-#include <menoh/combinated_backends/procedure.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
             inline procedure make_relu(node const&,
                                        std::vector<array> const& input_list,
@@ -25,7 +25,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
diff --git a/menoh/combinated_backends/backend/generic/operator/reshape.hpp b/menoh/composite_backend/backend/generic/operator/reshape.hpp
similarity index 100%
rename from menoh/combinated_backends/backend/generic/operator/reshape.hpp
rename to menoh/composite_backend/backend/generic/operator/reshape.hpp
diff --git a/menoh/combinated_backends/backend/generic/operator/sigmoid.hpp b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
similarity index 91%
rename from menoh/combinated_backends/backend/generic/operator/sigmoid.hpp
rename to menoh/composite_backend/backend/generic/operator/sigmoid.hpp
index f537646..c680357 100644
--- a/menoh/combinated_backends/backend/generic/operator/sigmoid.hpp
+++ b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
@@ -4,10 +4,10 @@
 #include <cmath>
 
 #include <menoh/array.hpp>
-#include <menoh/combinated_backends/procedure.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
             inline procedure
             make_sigmoid(node const&, std::vector<array> const& input_list,
@@ -34,7 +34,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
diff --git a/menoh/combinated_backends/backend/generic/operator/transpose.hpp b/menoh/composite_backend/backend/generic/operator/transpose.hpp
similarity index 96%
rename from menoh/combinated_backends/backend/generic/operator/transpose.hpp
rename to menoh/composite_backend/backend/generic/operator/transpose.hpp
index 439bc9e..22f8f8f 100644
--- a/menoh/combinated_backends/backend/generic/operator/transpose.hpp
+++ b/menoh/composite_backend/backend/generic/operator/transpose.hpp
@@ -4,10 +4,10 @@
 #include <vector>
 
 #include <menoh/array.hpp>
-#include <menoh/combinated_backends/procedure.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace generic_backend {
 
             inline std::vector<int> calc_strides(std::vector<int> const& dims) {
@@ -76,7 +76,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/formatted_array.hpp b/menoh/composite_backend/backend/mkldnn/formatted_array.hpp
similarity index 92%
rename from menoh/combinated_backends/backend/mkldnn/formatted_array.hpp
rename to menoh/composite_backend/backend/mkldnn/formatted_array.hpp
index af2ad86..bf8219e 100644
--- a/menoh/combinated_backends/backend/mkldnn/formatted_array.hpp
+++ b/menoh/composite_backend/backend/mkldnn/formatted_array.hpp
@@ -3,12 +3,12 @@
 
 #include <menoh/array.hpp>
 
-#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_conversion.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             class formatted_array {
@@ -48,7 +48,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/memory_cache.cpp b/menoh/composite_backend/backend/mkldnn/memory_cache.cpp
similarity index 97%
rename from menoh/combinated_backends/backend/mkldnn/memory_cache.cpp
rename to menoh/composite_backend/backend/mkldnn/memory_cache.cpp
index 29d69c5..a8d5a9e 100644
--- a/menoh/combinated_backends/backend/mkldnn/memory_cache.cpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_cache.cpp
@@ -1,9 +1,9 @@
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
 
 #include <numeric> // for accumulate
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             std::tuple<mkldnn::memory, optional<mkldnn::primitive>>
@@ -123,5 +123,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
diff --git a/menoh/combinated_backends/backend/mkldnn/memory_cache.hpp b/menoh/composite_backend/backend/mkldnn/memory_cache.hpp
similarity index 96%
rename from menoh/combinated_backends/backend/mkldnn/memory_cache.hpp
rename to menoh/composite_backend/backend/mkldnn/memory_cache.hpp
index ee38470..e2a455f 100644
--- a/menoh/combinated_backends/backend/mkldnn/memory_cache.hpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_cache.hpp
@@ -7,12 +7,12 @@
 #include <menoh/array.hpp>
 #include <menoh/optional.hpp>
 
-#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_conversion.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             class memory_cache {
@@ -100,7 +100,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp b/menoh/composite_backend/backend/mkldnn/memory_conversion.cpp
similarity index 97%
rename from menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp
rename to menoh/composite_backend/backend/mkldnn/memory_conversion.cpp
index 862d097..6604e4d 100644
--- a/menoh/combinated_backends/backend/mkldnn/memory_conversion.cpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_conversion.cpp
@@ -1,7 +1,7 @@
-#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_conversion.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             bool is_data_format(mkldnn::memory::format format) {
@@ -171,5 +171,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
diff --git a/menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp b/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
similarity index 96%
rename from menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp
rename to menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
index 05298a0..5b09f94 100644
--- a/menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
@@ -6,7 +6,7 @@
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             bool is_data_format(mkldnn::memory::format format);
@@ -49,7 +49,7 @@ namespace menoh_impl {
                                                 mkldnn::engine const& engine);
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp b/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
similarity index 97%
rename from menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp
rename to menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
index 47a5e91..024f852 100644
--- a/menoh/combinated_backends/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
@@ -1,15 +1,15 @@
-#include <menoh/combinated_backends/backend/mkldnn/memory_conversion.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_conversion.hpp>
+#include <menoh/composite_backend/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator.hpp>
 
 #include <menoh/graph.hpp> // for unsupported_operator error
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             mkldnn_context::mkldnn_context() : context() {
-                using namespace combinated_backends::
+                using namespace composite_backend::
                   mkldnn_backend;
               
                 // BatchNormalization
@@ -266,5 +266,5 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
diff --git a/menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp b/menoh/composite_backend/backend/mkldnn/mkldnn_context.hpp
similarity index 87%
rename from menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp
rename to menoh/composite_backend/backend/mkldnn/mkldnn_context.hpp
index 6c1611b..d855769 100644
--- a/menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp
+++ b/menoh/composite_backend/backend/mkldnn/mkldnn_context.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
-#define MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
 
 #include <string>
 #include <unordered_map>
@@ -12,14 +12,14 @@
 #include <menoh/mkldnn/utility.hpp>
 #include <menoh/model_core.hpp>
 
-#include <menoh/combinated_backends/context.hpp>
+#include <menoh/composite_backend/context.hpp>
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             class mkldnn_context final : public context {
@@ -93,7 +93,7 @@ namespace menoh_impl {
             };
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_CONTEXT_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator.hpp b/menoh/composite_backend/backend/mkldnn/operator.hpp
new file mode 100644
index 0000000..ea17459
--- /dev/null
+++ b/menoh/composite_backend/backend/mkldnn/operator.hpp
@@ -0,0 +1,12 @@
+#ifndef MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+#define MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
+
+#include <menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/conv.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/gemm.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/pool.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/softmax.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/sum.hpp>
+
+#endif // MENOH_IMPL_MKLDNN_WITH_MKLDNN_FALLBACK_BACKEND_OPERATOR_OPERATOR_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
similarity index 93%
rename from menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
index 3ca4113..7b19ea6 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_batch_norm(
@@ -112,7 +112,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/conv.hpp b/menoh/composite_backend/backend/mkldnn/operator/conv.hpp
similarity index 94%
rename from menoh/combinated_backends/backend/mkldnn/operator/conv.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/conv.hpp
index 50569bd..e866e03 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/conv.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/conv.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -124,7 +124,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp b/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
similarity index 90%
rename from menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
index 9ab15fe..aad174a 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/eltwise.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_eltwise(
@@ -78,7 +78,7 @@ namespace menoh_impl {
 #undef MENOH_MKLDNN_CONTEXT_ELTWISE_FACTORY
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp b/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
similarity index 93%
rename from menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
index bda27f7..14f8ed7 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -117,7 +117,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp b/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
similarity index 92%
rename from menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
index 4873bc6..498bd71 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
@@ -1,13 +1,13 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             template <typename PrimitiveGen>
@@ -58,7 +58,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/pool.hpp b/menoh/composite_backend/backend/mkldnn/operator/pool.hpp
similarity index 91%
rename from menoh/combinated_backends/backend/mkldnn/operator/pool.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/pool.hpp
index 1e9c428..a7f2cd3 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/pool.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/pool.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_pool_impl(
@@ -87,7 +87,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp b/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
similarity index 84%
rename from menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
index 289c8f0..26aaf3f 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/softmax.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
@@ -1,15 +1,15 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type make_softmax(
@@ -49,7 +49,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/operator/sum.hpp b/menoh/composite_backend/backend/mkldnn/operator/sum.hpp
similarity index 92%
rename from menoh/combinated_backends/backend/mkldnn/operator/sum.hpp
rename to menoh/composite_backend/backend/mkldnn/operator/sum.hpp
index 9bb646b..2e28563 100644
--- a/menoh/combinated_backends/backend/mkldnn/operator/sum.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/sum.hpp
@@ -5,17 +5,17 @@
 
 #include <menoh/graph.hpp> // for dimension_mismatch error
 
-#include <menoh/combinated_backends/backend/mkldnn/formatted_array.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/operator/output_management.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp>
+#include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/operator/output_management.hpp>
+#include <menoh/composite_backend/backend/mkldnn/procedure_factory.hpp>
 
 #include <mkldnn.hpp>
 
 #include <sstream>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             inline procedure_factory_return_type
@@ -104,7 +104,7 @@ namespace menoh_impl {
             }
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
diff --git a/menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp b/menoh/composite_backend/backend/mkldnn/procedure_factory.hpp
similarity index 79%
rename from menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp
rename to menoh/composite_backend/backend/mkldnn/procedure_factory.hpp
index 1067246..c307291 100644
--- a/menoh/combinated_backends/backend/mkldnn/procedure_factory.hpp
+++ b/menoh/composite_backend/backend/mkldnn/procedure_factory.hpp
@@ -1,11 +1,11 @@
-#ifndef MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
-#define MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
 
 #include <string>
 #include <utility>
 #include <vector>
 
-#include <menoh/combinated_backends/backend/mkldnn/memory_cache.hpp>
+#include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
 #include <mkldnn.hpp>
 
 #define MENOH_MKLDNN_CONTEXT_PROCEDURE_FACTORY_PARAMETER_LIST          \
@@ -19,7 +19,7 @@
     node, input_memory_cache_list, output_formatted_array_list, engine
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         namespace mkldnn_backend {
 
             struct procedure_factory_return_type {
@@ -40,6 +40,6 @@ namespace menoh_impl {
                 )>;
 
         } // namespace mkldnn_backend
-    }     // namespace combinated_backends
+    }     // namespace composite_backend
 } // namespace menoh_impl
-#endif // MENOH_IMPL_COMBINATED_BACKENDS_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_MKLDNN_PROCEDURE_FACTORY_HPP
diff --git a/menoh/combinated_backends/context.hpp b/menoh/composite_backend/context.hpp
similarity index 94%
rename from menoh/combinated_backends/context.hpp
rename to menoh/composite_backend/context.hpp
index dd77381..7091e25 100644
--- a/menoh/combinated_backends/context.hpp
+++ b/menoh/composite_backend/context.hpp
@@ -8,11 +8,11 @@
 #include <menoh/node.hpp>
 #include <menoh/optional.hpp>
 
-#include <menoh/combinated_backends/logger.hpp>
-#include <menoh/combinated_backends/procedure.hpp>
+#include <menoh/composite_backend/logger.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
 
         class context {
         public:
@@ -74,7 +74,7 @@ namespace menoh_impl {
         };
         inline context::~context(){}
 
-    } // namespace combinated_backends
+    } // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_FALLBACK_CONTEXT_HPP
diff --git a/menoh/combinated_backends/logger.hpp b/menoh/composite_backend/logger.hpp
similarity index 82%
rename from menoh/combinated_backends/logger.hpp
rename to menoh/composite_backend/logger.hpp
index 2301f27..53ba532 100644
--- a/menoh/combinated_backends/logger.hpp
+++ b/menoh/composite_backend/logger.hpp
@@ -4,10 +4,10 @@
 #include <iostream>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
         using logger = std::unique_ptr<std::ostream>;
         using logger_handle = std::ostream*;
-    } // namespace combinated_backends
+    } // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
diff --git a/menoh/combinated_backends/model_core.cpp b/menoh/composite_backend/model_core.cpp
similarity index 92%
rename from menoh/combinated_backends/model_core.cpp
rename to menoh/composite_backend/model_core.cpp
index 42c9eeb..552a221 100644
--- a/menoh/combinated_backends/model_core.cpp
+++ b/menoh/composite_backend/model_core.cpp
@@ -1,11 +1,11 @@
-#include <menoh/combinated_backends/model_core.hpp>
+#include <menoh/composite_backend/model_core.hpp>
 
 #include <algorithm>
 #include <cassert>
 #include <memory>
 
-#include <menoh/combinated_backends/backend/generic/generic_context.hpp>
-#include <menoh/combinated_backends/backend/mkldnn/mkldnn_context.hpp>
+#include <menoh/composite_backend/backend/generic/generic_context.hpp>
+#include <menoh/composite_backend/backend/mkldnn/mkldnn_context.hpp>
 
 #include <menoh/mkldnn/utility.hpp>
 
@@ -18,7 +18,7 @@
 #include <iosfwd>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
 
         model_core make_model_core(
           std::unordered_map<std::string, array> const& input_table,
@@ -39,12 +39,12 @@ namespace menoh_impl {
                     if(backend["type"].get<std::string>() == "mkldnn") {
                         context_list.emplace_back(
                           "mkldnn",
-                          std::make_unique<combinated_backends::mkldnn_backend::
+                          std::make_unique<composite_backend::mkldnn_backend::
                                              mkldnn_context>());
                     } else if(backend["type"].get<std::string>() == "generic") {
                         context_list.emplace_back(
                           "generic", std::make_unique<
-                                       combinated_backends::generic_backend::
+                                       composite_backend::generic_backend::
                                          generic_context>());
                     }
                 }
@@ -79,12 +79,12 @@ namespace menoh_impl {
                         logger_->rdbuf(std::cout.rdbuf());
                     } else if(log_output == "file") {
                         logger_.reset(
-                          new std::ofstream("combinated_backends_log.txt"));
+                          new std::ofstream("composite_backend_log.txt"));
                     } else {
                         throw invalid_backend_config_error(
                           "invalid value of \"log_output\": " + log_output);
                     }
-                    *logger_ << "combinated_backends log" << std::endl;
+                    *logger_ << "composite_backend log" << std::endl;
                 }
             }
 
@@ -158,5 +158,5 @@ namespace menoh_impl {
             }
         }
 
-    } // namespace combinated_backends
+    } // namespace composite_backend
 } // namespace menoh_impl
diff --git a/menoh/combinated_backends/model_core.hpp b/menoh/composite_backend/model_core.hpp
similarity index 91%
rename from menoh/combinated_backends/model_core.hpp
rename to menoh/composite_backend/model_core.hpp
index a0dec3c..1f4597e 100644
--- a/menoh/combinated_backends/model_core.hpp
+++ b/menoh/composite_backend/model_core.hpp
@@ -11,11 +11,11 @@
 #include <menoh/model_core.hpp>
 #include <menoh/model_data.hpp>
 
-#include <menoh/combinated_backends/context.hpp>
-#include <menoh/combinated_backends/logger.hpp>
+#include <menoh/composite_backend/context.hpp>
+#include <menoh/composite_backend/logger.hpp>
 
 namespace menoh_impl {
-    namespace combinated_backends {
+    namespace composite_backend {
 
         class model_core final : public menoh_impl::model_core {
         public:
@@ -50,7 +50,7 @@ namespace menoh_impl {
           menoh_impl::model_data const& model_data,
           backend_config const& config);
 
-    } // namespace combinated_backends
+    } // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_MKLDNN_WITH_FALLBACK_MODEL_CORE_HPP
diff --git a/menoh/composite_backend/procedure.hpp b/menoh/composite_backend/procedure.hpp
new file mode 100644
index 0000000..e0620f4
--- /dev/null
+++ b/menoh/composite_backend/procedure.hpp
@@ -0,0 +1,12 @@
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_PROCEDURE_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_PROCEDURE_HPP
+
+#include <functional>
+
+namespace menoh_impl {
+namespace composite_backend {
+    using procedure = std::function<void()>;
+} // namespace composite_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_PROCEDURE_HPP
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index 6eb41a9..bb0916d 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -1,7 +1,7 @@
 #include <menoh/model_core.hpp>
 #include <menoh/model_core_factory.hpp>
 
-#include <menoh/combinated_backends/model_core.hpp>
+#include <menoh/composite_backend/model_core.hpp>
 #include <menoh/mkldnn/model_core.hpp>
 
 namespace menoh_impl {
@@ -17,11 +17,11 @@ namespace menoh_impl {
             return std::make_unique<mkldnn_backend::model_core>(
               mkldnn_backend::make_model_core(
                 input_table, required_output_table, model_data, config));
-        } else if(backend_name == "combinated_backends") {
-            return std::make_unique<
-              combinated_backends::model_core>(combinated_backends::make_model_core(
-              input_table, required_output_table,
-              output_profile_table, model_data, config));
+        } else if(backend_name == "composite_backend") {
+            return std::make_unique<composite_backend::model_core>(
+              composite_backend::make_model_core(
+                input_table, required_output_table, output_profile_table,
+                model_data, config));
         }
 
         throw invalid_backend_name(backend_name);

From 368b9941aaf1e8b3e40e33c98d2b46d026887ae1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 9 Nov 2018 15:18:08 +0900
Subject: [PATCH 259/321] add mkldnn_with_fallback for backward compatibility

---
 menoh/composite_backend/backend/generic/operator.hpp   |  3 ++-
 .../backend/generic/operator/reshape.hpp               |  6 +++---
 menoh/model_core_factory.cpp                           | 10 ++++++++++
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator.hpp b/menoh/composite_backend/backend/generic/operator.hpp
index 80c11ee..fef6af1 100644
--- a/menoh/composite_backend/backend/generic/operator.hpp
+++ b/menoh/composite_backend/backend/generic/operator.hpp
@@ -1,8 +1,9 @@
 #ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 #define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
 
-#include <menoh/composite_backend/backend/generic/operator/relu.hpp>
 #include <menoh/composite_backend/backend/generic/operator/mul.hpp>
+#include <menoh/composite_backend/backend/generic/operator/relu.hpp>
+#include <menoh/composite_backend/backend/generic/operator/reshape.hpp>
 #include <menoh/composite_backend/backend/generic/operator/sigmoid.hpp>
 #include <menoh/composite_backend/backend/generic/operator/transpose.hpp>
 
diff --git a/menoh/composite_backend/backend/generic/operator/reshape.hpp b/menoh/composite_backend/backend/generic/operator/reshape.hpp
index 043fcff..255650b 100644
--- a/menoh/composite_backend/backend/generic/operator/reshape.hpp
+++ b/menoh/composite_backend/backend/generic/operator/reshape.hpp
@@ -3,10 +3,10 @@
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp> // for dimension_mismatch error
-#include <menoh/mkldnn_with_generic_fallback/procedure.hpp>
+#include <menoh/composite_backend/procedure.hpp>
 
 namespace menoh_impl {
-    namespace mkldnn_with_generic_fallback_backend {
+    namespace composite_backend {
         namespace generic_backend {
             inline procedure
             make_reshape(node const& node, std::vector<array> const& input_list,
@@ -26,7 +26,7 @@ namespace menoh_impl {
             }
 
         } // namespace generic_backend
-    }     // namespace mkldnn_with_generic_fallback_backend
+    }     // namespace composite_backend
 } // namespace menoh_impl
 
 #endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index bb0916d..c26b49d 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -4,6 +4,8 @@
 #include <menoh/composite_backend/model_core.hpp>
 #include <menoh/mkldnn/model_core.hpp>
 
+#include <menoh/json.hpp>
+
 namespace menoh_impl {
 
     std::unique_ptr<menoh_impl::model_core> make_model_core(
@@ -17,6 +19,14 @@ namespace menoh_impl {
             return std::make_unique<mkldnn_backend::model_core>(
               mkldnn_backend::make_model_core(
                 input_table, required_output_table, model_data, config));
+        } else if(backend_name == "mkldnn_with_generic_fallback") {
+            auto conf = nlohmann::json::parse(config);
+            conf.merge_patch(
+              R"({"backends":[{"type":"mkldnn"}, {"type":"generic"}]})");
+            return std::make_unique<composite_backend::model_core>(
+              composite_backend::make_model_core(
+                input_table, required_output_table, output_profile_table,
+                model_data, conf.get<std::string>()));
         } else if(backend_name == "composite_backend") {
             return std::make_unique<composite_backend::model_core>(
               composite_backend::make_model_core(

From 72b2ae015c933c0cae32d7a21177f27d9242791d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 12 Nov 2018 18:45:57 +0900
Subject: [PATCH 260/321] fix include guard

---
 menoh/composite_backend/backend/generic/operator.hpp        | 6 +++---
 menoh/composite_backend/backend/generic/operator/mul.hpp    | 6 +++---
 menoh/composite_backend/backend/generic/operator/relu.hpp   | 6 +++---
 .../composite_backend/backend/generic/operator/reshape.hpp  | 6 +++---
 .../composite_backend/backend/generic/operator/sigmoid.hpp  | 6 +++---
 .../backend/generic/operator/transpose.hpp                  | 6 +++---
 menoh/composite_backend/backend/mkldnn/formatted_array.hpp  | 6 +++---
 menoh/composite_backend/backend/mkldnn/memory_cache.hpp     | 6 +++---
 .../composite_backend/backend/mkldnn/memory_conversion.hpp  | 6 +++---
 .../backend/mkldnn/operator/batch_norm.hpp                  | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/conv.hpp    | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/gemm.hpp    | 6 +++---
 .../backend/mkldnn/operator/output_management.hpp           | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/pool.hpp    | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/softmax.hpp | 6 +++---
 menoh/composite_backend/backend/mkldnn/operator/sum.hpp     | 6 +++---
 menoh/composite_backend/logger.hpp                          | 6 +++---
 18 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator.hpp b/menoh/composite_backend/backend/generic/operator.hpp
index fef6af1..dfbd0aa 100644
--- a/menoh/composite_backend/backend/generic/operator.hpp
+++ b/menoh/composite_backend/backend/generic/operator.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
 
 #include <menoh/composite_backend/backend/generic/operator/mul.hpp>
 #include <menoh/composite_backend/backend/generic/operator/relu.hpp>
@@ -7,4 +7,4 @@
 #include <menoh/composite_backend/backend/generic/operator/sigmoid.hpp>
 #include <menoh/composite_backend/backend/generic/operator/transpose.hpp>
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_GENERIC_OPERATOR_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
diff --git a/menoh/composite_backend/backend/generic/operator/mul.hpp b/menoh/composite_backend/backend/generic/operator/mul.hpp
index 1bb6577..986fd70 100644
--- a/menoh/composite_backend/backend/generic/operator/mul.hpp
+++ b/menoh/composite_backend/backend/generic/operator/mul.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp> // for dimension_mismatch error
@@ -45,4 +45,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_MUL_HPP
diff --git a/menoh/composite_backend/backend/generic/operator/relu.hpp b/menoh/composite_backend/backend/generic/operator/relu.hpp
index 505d8f2..3cb8ca9 100644
--- a/menoh/composite_backend/backend/generic/operator/relu.hpp
+++ b/menoh/composite_backend/backend/generic/operator/relu.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
 
 #include <menoh/array.hpp>
 #include <menoh/composite_backend/procedure.hpp>
@@ -28,4 +28,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RELU_HPP
diff --git a/menoh/composite_backend/backend/generic/operator/reshape.hpp b/menoh/composite_backend/backend/generic/operator/reshape.hpp
index 255650b..3ae47b3 100644
--- a/menoh/composite_backend/backend/generic/operator/reshape.hpp
+++ b/menoh/composite_backend/backend/generic/operator/reshape.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
 
 #include <menoh/array.hpp>
 #include <menoh/graph.hpp> // for dimension_mismatch error
@@ -29,4 +29,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_RESHAPE_HPP
diff --git a/menoh/composite_backend/backend/generic/operator/sigmoid.hpp b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
index c680357..40c78e3 100644
--- a/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
+++ b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
 
 #include <cmath>
 
@@ -37,4 +37,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_SIGMOID_HPP
diff --git a/menoh/composite_backend/backend/generic/operator/transpose.hpp b/menoh/composite_backend/backend/generic/operator/transpose.hpp
index 22f8f8f..90f5f1d 100644
--- a/menoh/composite_backend/backend/generic/operator/transpose.hpp
+++ b/menoh/composite_backend/backend/generic/operator/transpose.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
 
 #include <vector>
 
@@ -79,4 +79,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_TRANSPOSE_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/formatted_array.hpp b/menoh/composite_backend/backend/mkldnn/formatted_array.hpp
index bf8219e..438496a 100644
--- a/menoh/composite_backend/backend/mkldnn/formatted_array.hpp
+++ b/menoh/composite_backend/backend/mkldnn/formatted_array.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
 
 #include <menoh/array.hpp>
 
@@ -51,4 +51,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_FORMATTED_ARRAY_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/memory_cache.hpp b/menoh/composite_backend/backend/mkldnn/memory_cache.hpp
index e2a455f..b12eb3e 100644
--- a/menoh/composite_backend/backend/mkldnn/memory_cache.hpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_cache.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CACHE_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CACHE_HPP
 
 #include <numeric>
 #include <tuple>
@@ -103,4 +103,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CACHE_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CACHE_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp b/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
index 5b09f94..af29ed5 100644
--- a/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
+++ b/menoh/composite_backend/backend/mkldnn/memory_conversion.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
 
 #include <menoh/array.hpp>
 
@@ -52,4 +52,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_MKLDNN_MEMORY_CONVERSION_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
index 7b19ea6..49a1081 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -115,4 +115,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_BATCH_NORM_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/conv.hpp b/menoh/composite_backend/backend/mkldnn/operator/conv.hpp
index e866e03..089fe34 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/conv.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/conv.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -127,4 +127,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_CONV_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp b/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
index aad174a..17c4788 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/eltwise.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -81,4 +81,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_ELTWISE_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp b/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
index 14f8ed7..949d6fb 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/gemm.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -120,4 +120,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_GEMM_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp b/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
index 498bd71..7daefdf 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/output_management.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -61,4 +61,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_OUTPUT_MANAGEMENT_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/pool.hpp b/menoh/composite_backend/backend/mkldnn/operator/pool.hpp
index a7f2cd3..97a2087 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/pool.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/pool.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -90,4 +90,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_POOL_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp b/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
index 26aaf3f..38b071c 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/softmax.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
 
 #include <menoh/composite_backend/backend/mkldnn/formatted_array.hpp>
 #include <menoh/composite_backend/backend/mkldnn/memory_cache.hpp>
@@ -52,4 +52,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SOFTMAX_HPP
diff --git a/menoh/composite_backend/backend/mkldnn/operator/sum.hpp b/menoh/composite_backend/backend/mkldnn/operator/sum.hpp
index 2e28563..764ed1c 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/sum.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/sum.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
-#define MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
 
 #include <algorithm>
 
@@ -107,4 +107,4 @@ namespace menoh_impl {
     }     // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_IMPL_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_MKLDNN_OPERATOR_SUM_HPP
diff --git a/menoh/composite_backend/logger.hpp b/menoh/composite_backend/logger.hpp
index 53ba532..8263800 100644
--- a/menoh/composite_backend/logger.hpp
+++ b/menoh/composite_backend/logger.hpp
@@ -1,5 +1,5 @@
-#ifndef MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
-#define MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
+#ifndef MENOH_COMPOSITE_BACKEND_LOGGER_HPP
+#define MENOH_COMPOSITE_BACKEND_LOGGER_HPP
 
 #include <iostream>
 
@@ -10,4 +10,4 @@ namespace menoh_impl {
     } // namespace composite_backend
 } // namespace menoh_impl
 
-#endif // MENOH_MKLDNN_WITH_GENERIC_FALLBACK_BACKEND_LOGGER_HPP
+#endif // MENOH_COMPOSITE_BACKEND_LOGGER_HPP

From 281314f96fa4491ba5d21a82b0fb72c7d3ca54f0 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 13 Nov 2018 16:15:11 +0900
Subject: [PATCH 261/321] stop uninstalling oclint as Travis-CI itself removes
 it automatically

c.f. https://github.com/travis-ci/travis-build/commit/52c6b6cc1d537e52c8ae6f0906944d6fcaa3d173
---
 .travis/macosx-x86_64/build.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index 52c38ad..ec672cc 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -17,7 +17,6 @@ g++ --version
 
 # install prerequisites
 brew update
-brew cask uninstall oclint # oclint conflicts with gcc
 brew upgrade python
 
 export PATH=/usr/local/opt/python/libexec/bin:$PATH

From 45edc71bf47a2c98c28bf560e88db6b64fe74a11 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 14 Nov 2018 14:02:47 +0900
Subject: [PATCH 262/321] add a new function menoh_dtype_size for computing
 element size of a dtype

---
 include/menoh/menoh.h |  6 ++++++
 menoh/menoh.cpp       | 26 ++++++++++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index adfcb28..243a332 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -97,6 +97,12 @@ typedef int32_t menoh_error_code;
 MENOH_API const char* menoh_get_last_error_message();
 /** @} */
 
+/*! @ingroup vpt
+ */
+/*! \breaf Element size of given menoh_dtype.
+ */
+menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype, int32_t *dst_size);
+
 /*! @addtogroup model_data Model data types and operations
  * @{ */
 /*! \struct menoh_model_data
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 0f06a58..653ca0c 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -89,6 +89,32 @@ menoh_error_code check_error(Func func) {
     return menoh_error_code_success;
 }
 
+/*
+ * dtype
+ */
+
+menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype, int32_t *dst_size) {
+    switch (dtype) {
+#define MENOH_DTYPE_SIZE_CASE(dtype) \
+    case dtype: \
+        *dst_size = menoh_impl::size_in_bytes<static_cast<menoh_impl::dtype_t>(dtype)>; \
+        break;
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float16)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float64)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int8)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int16)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int32)
+    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int64)
+#undef MENOH_DTYPE_SIZE_CASE
+    default:
+        std::string msg("unknown dtype: " + std::to_string(dtype));
+        menoh_impl::set_last_error_message(msg.c_str());
+        return menoh_error_code_invalid_dtype;
+    }
+    return menoh_error_code_success;
+}
+
 /*
  * model_data
  */

From 44b629751b696d4f4ba7285936b50af998abf93e Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Mon, 19 Nov 2018 19:24:02 +0900
Subject: [PATCH 263/321] fix JSON parse error when passing empty string as
 backend_config for mkldnn_with_generic_fallback backend

menoh_build_model(model_builder, model_data, "mkldnn", "", &model)
worked. So I expect menoh_build_model(model_builder, model_data,
"mkldnn_with_generic_fallback", "", &model) also works.
---
 menoh/model_core_factory.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/model_core_factory.cpp b/menoh/model_core_factory.cpp
index c26b49d..55a16e2 100644
--- a/menoh/model_core_factory.cpp
+++ b/menoh/model_core_factory.cpp
@@ -20,7 +20,7 @@ namespace menoh_impl {
               mkldnn_backend::make_model_core(
                 input_table, required_output_table, model_data, config));
         } else if(backend_name == "mkldnn_with_generic_fallback") {
-            auto conf = nlohmann::json::parse(config);
+            auto conf = nlohmann::json::parse(config.empty() ? "{}" : config);
             conf.merge_patch(
               R"({"backends":[{"type":"mkldnn"}, {"type":"generic"}]})");
             return std::make_unique<composite_backend::model_core>(

From 16ac71acee09feac7c83d89c345c133150c0b2b4 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 20 Nov 2018 11:58:54 +0900
Subject: [PATCH 264/321] fix backend name

---
 example/vgg16_example_in_cpp.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index d9c2bd9..e5692b9 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -132,7 +132,7 @@ int main(int argc, char** argv) {
 
     // Build model
     auto model = model_builder.build_model(
-      model_data, "combinated_backends",
+      model_data, "composite_backend",
       R"({"backends":[{"type":"mkldnn"}, {"type":"generic"}], "log_output":"stdout"})");
     model_data
       .reset(); // you can delete model_data explicitly after model building

From 85eb90d4c570cdd48df7b470bc5863aa4e6da98a Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 20 Nov 2018 20:09:38 +0900
Subject: [PATCH 265/321] bump minor version number

Because menoh_dtype_size() and some menoh_dtype_* constants are introduced.
---
 CMakeLists.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7fd9941..ec69e2b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.1)
 set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 
 set(MENOH_MAJOR_VERSION 1)
-set(MENOH_MINOR_VERSION 1)
-set(MENOH_PATCH_VERSION 1)
+set(MENOH_MINOR_VERSION 2)
+set(MENOH_PATCH_VERSION 0)
 
 # Options
 option(USE_OLD_GLIBCXX_ABI "Generate binaries for the old libstdc++ ABI" OFF)

From f1245c11c5771a3c2517626d86deeea330465db2 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 3 Dec 2018 12:24:32 +0900
Subject: [PATCH 266/321] replace CV_LOAD_IMAGE_COLOR -> cv::IMREAD_COLOR

---
 example/general_cnn_example_in_cpp.cpp | 2 +-
 example/vgg16_example_in_cpp.cpp       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/example/general_cnn_example_in_cpp.cpp b/example/general_cnn_example_in_cpp.cpp
index fdc320b..179124a 100644
--- a/example/general_cnn_example_in_cpp.cpp
+++ b/example/general_cnn_example_in_cpp.cpp
@@ -84,7 +84,7 @@ int main(int argc, char** argv) {
     auto onnx_model_path = a.get<std::string>("model");
 
     cv::Mat image_mat =
-      cv::imread(input_image_path.c_str(), CV_LOAD_IMAGE_COLOR);
+      cv::imread(input_image_path.c_str(), cv::IMREAD_COLOR);
     if(!image_mat.data) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);
diff --git a/example/vgg16_example_in_cpp.cpp b/example/vgg16_example_in_cpp.cpp
index e5692b9..962b73d 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/vgg16_example_in_cpp.cpp
@@ -90,7 +90,7 @@ int main(int argc, char** argv) {
     auto synset_words_path = a.get<std::string>("synset_words");
 
     cv::Mat image_mat =
-      cv::imread(input_image_path.c_str(), CV_LOAD_IMAGE_COLOR);
+      cv::imread(input_image_path.c_str(), cv::IMREAD_COLOR);
     if(!image_mat.data) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);

From eac8a6276101651d17f40aa35f09a2c149b1baa9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 21 Nov 2018 20:33:57 +0900
Subject: [PATCH 267/321] refactor CMakeLists

- remove un target_xxx commands
- move MKLDNN setup to menoh/CMakeLists.txt
- add git finder
---
 CMakeLists.txt            | 41 ++++++++++-----------
 benchmark/CMakeLists.txt  |  1 +
 cmake/BuildProtobuf.cmake |  1 +
 example/CMakeLists.txt    |  4 ++-
 menoh/CMakeLists.txt      | 75 +++++++++++++++++++++++++++------------
 test/CMakeLists.txt       | 16 +++++----
 6 files changed, 86 insertions(+), 52 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ec69e2b..95dd3d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,16 +14,21 @@ option(ENABLE_TEST "Build test" OFF)
 option(ENABLE_BENCHMARK "Build benchmark" ON)
 option(ENABLE_EXAMPLE "Build example" ON)
 
+option(BUILD_SHARED_LIBS "Build shared libs" ON)
+
 option(SHOW_ALL_VARIABLES "Debug: show all variables" OFF)
 
-# C++ setup
+## C++ setup
 set(CMAKE_CXX_STANDARD 14)
+
+## Build type
 if("${CMAKE_BUILD_TYPE}" STREQUAL "")
     message(STATUS "CMAKE_BUILD_TYPE is unset, defaulting to Release")
     set(CMAKE_BUILD_TYPE "Release")
 endif()
 message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
 
+## Compiler dependent options
 if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # check Clang and AppleClang
     # using Clang
     set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg -Wall -Wextra")
@@ -34,23 +39,17 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
     set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG")
 endif()
 
-# Configure to use the new `libstdc++` ABI
+## Configure to use the new `libstdc++` ABI
 if(USE_OLD_GLIBCXX_ABI)
     message(STATUS "Set _GLIBCXX_USE_CXX11_ABI macro to 0")
     add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
 endif()
 
-include_directories("${PROJECT_SOURCE_DIR}")
-include_directories("${PROJECT_SOURCE_DIR}/include")
-
-set(EXTERNAL_DIR ${CMAKE_SOURCE_DIR}/external)
+set(EXTERNAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
 set(DOWNLOAD_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/downloads CACHE PATH "A directory to save the downloaded files.")
 mark_as_advanced(DOWNLOAD_LOCATION)
 
-# Enable ExternalProject_Add
-include(ExternalProject)
-
-# Setup protobuf (it is used in ONNX and Menoh)
+## Setup protobuf (it is used in ONNX and Menoh)
 if(LINK_STATIC_LIBPROTOBUF)
     # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
     # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
@@ -79,11 +78,17 @@ else()
     endif()
 endif()
 
-# Build libonnx.a
+## Setup git
+find_package(Git)
+if(NOT GIT_FOUND)
+    message(FATAL_ERROR "git not found")
+endif()
+
+## Build libonnx.a
 message(STATUS "Adding external/onnx")
 
 set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
-execute_process(COMMAND git submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
 # see https://github.com/onnx/onnx/pull/1466
 message(STATUS "Patching to external/onnx")
@@ -91,16 +96,7 @@ configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/
 
 # TODO: enable the following option when it is ready for migrating to onnx-ml
 #set(ONNX_ML 1)
-add_subdirectory(external/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
-include_directories("${ONNX_INCLUDE_DIRS}")
-
-# Setup MKLDNN
-find_package(MKLDNN "0.14")
-if (NOT MKLDNN_FOUND)
-    message(FATAL_ERROR "MKLDNN is not found")
-endif()
-
-include_directories("${MKLDNN_INCLUDE_DIR}")
+add_subdirectory(${EXTERNAL_DIR}/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
 
 if(${ENABLE_TEST})
     message(STATUS "Adding test")
@@ -117,6 +113,7 @@ if(${ENABLE_EXAMPLE})
     add_subdirectory(example)
 endif()
 
+## Build libmenoh
 message(STATUS "Adding menoh")
 add_subdirectory(menoh)
 
diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt
index 2d8d19e..ff4cb1a 100644
--- a/benchmark/CMakeLists.txt
+++ b/benchmark/CMakeLists.txt
@@ -1,2 +1,3 @@
 add_executable(vgg16_benchmark vgg16_benchmark.cpp)
+target_include_directories(vgg16_benchmark PUBLIC "${PROJECT_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}/include")
 target_link_libraries(vgg16_benchmark menoh)
diff --git a/cmake/BuildProtobuf.cmake b/cmake/BuildProtobuf.cmake
index 9c49922..36cc907 100644
--- a/cmake/BuildProtobuf.cmake
+++ b/cmake/BuildProtobuf.cmake
@@ -1,3 +1,4 @@
+include(ExternalProject)
 set(PROTOBUF_VERSION_STATIC "3.6.1")
 set(PROTOBUF_HASH MD5=406d5b8636576b1c86730ca5cbd1e576)
 
diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index 669614d..fa7cef1 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -3,16 +3,18 @@ find_package(OpenCV)
 if (NOT OpenCV_FOUND)
     message(FATAL_ERROR "OpenCV is not found. OpenCV is needed to build example.")
 endif()
-include_directories("../inlcude" ${OpenCV_INCLUDE_DIRS})
 
 # Build vgg16_example_in_c
 add_executable(vgg16_example_in_c vgg16_example_in_c.c)
+target_include_directories(vgg16_example_in_c PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
 target_link_libraries(vgg16_example_in_c menoh)
 
 # Build vgg16_example_in_cpp
 add_executable(vgg16_example_in_cpp vgg16_example_in_cpp.cpp)
+target_include_directories(vgg16_example_in_cpp PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
 target_link_libraries(vgg16_example_in_cpp menoh ${OpenCV_LIBS})
 
 # Buld general_cnn_example_in_cpp
 add_executable(general_cnn_example_in_cpp general_cnn_example_in_cpp.cpp)
+target_include_directories(general_cnn_example_in_cpp PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
 target_link_libraries(general_cnn_example_in_cpp menoh ${OpenCV_LIBS})
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index a4fe9e0..831db9f 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -1,40 +1,71 @@
-# Options
-option(LINK_STATIC_LIBGCC "Link static libgcc to libmenoh" OFF)
-option(LINK_STATIC_LIBSTDCXX "Link static libstdc++ to libmenoh" OFF)
+option(LINK_STATIC_LIBGCC OFF)
+option(LINK_STATIC_LIBSTDCXX OFF)
 
-# Note: The libraries can be static (.a) or shared (.so)
-if(NOT DEFINED PROTOBUF_INCLUDE_DIRS)
-    message(FATAL_ERROR "PROTOBUF_INCLUDE_DIRS is not found")
+## Setup MKLDNN
+find_package(MKLDNN "0.14")
+if(NOT MKLDNN_FOUND)
+    message(FATAL_ERROR "MKLDNN is not found")
 endif()
-if(NOT DEFINED MKLDNN_LIBRARIES)
-    message(FATAL_ERROR "MKLDNN_LIBRARIES is not found")
-endif()
-
-file(GLOB_RECURSE SOURCES "." "*.cpp")
 
 # Create a object library for generating shared library
-add_library(menoh_objlib OBJECT ${SOURCES})
-
+add_library(menoh_objlib OBJECT
+    dtype.cpp
+    array.cpp
+    onnx.cpp
+    composite_backend/backend/mkldnn/memory_cache.cpp
+    composite_backend/backend/mkldnn/mkldnn_context.cpp
+    composite_backend/backend/mkldnn/memory_conversion.cpp
+    composite_backend/backend/generic/generic_context.cpp
+    composite_backend/model_core.cpp
+    model_core_factory.cpp
+    dims.cpp
+    node.cpp
+    graph.cpp
+    mkldnn/utility.cpp
+    mkldnn/operator/conv_transpose.cpp
+    mkldnn/operator/softmax.cpp
+    mkldnn/operator/gemm.cpp
+    mkldnn/operator/eltwise.cpp
+    mkldnn/operator/lrn.cpp
+    mkldnn/operator/conv.cpp
+    mkldnn/operator/sum.cpp
+    mkldnn/operator/add.cpp
+    mkldnn/operator/concat.cpp
+    mkldnn/operator/pool.cpp
+    mkldnn/operator/fc.cpp
+    mkldnn/operator/batch_norm.cpp
+    mkldnn/model_core.cpp
+    menoh.cpp
+    model_core.cpp
+)
+set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})
 add_dependencies(menoh_objlib gen_onnx_proto) # custom target defined in onnx
-target_include_directories(menoh_objlib PUBLIC $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
-
-set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
-
-include(ConfigureMenoh)
+target_include_directories(menoh_objlib PUBLIC
+    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
+    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
+    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
+    $<BUILD_INTERFACE:${ONNX_INCLUDE_DIRS}>
+)
 
 # menoh
-add_library(menoh SHARED $<TARGET_OBJECTS:menoh_objlib>)
+add_library(menoh $<TARGET_OBJECTS:menoh_objlib>)
 if(NOT APPLE AND NOT MSVC)
     # Remove private symbols (Note: it works in MINGW but not in MSVC)
     set_property(
         TARGET menoh APPEND_STRING PROPERTY
             LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
 endif()
-menoh_link_libraries(menoh PRIVATE)
+target_link_libraries(menoh PUBLIC ${MKLDNN_LIBRARIES} onnx)
+if(LINK_STATIC_LIBGCC)
+    target_link_libraries(menoh PRIVATE -static-libgcc)
+endif()
+if(LINK_STATIC_LIBSTDCXX)
+    target_link_libraries(menoh PRIVATE -static-libstdc++)
+endif()
 
 # menoh_test_target: only used in `test` subdirectory
-add_library(menoh_test_target SHARED $<TARGET_OBJECTS:menoh_objlib>)
-menoh_link_libraries(menoh_test_target PRIVATE)
+add_library(menoh_test_target $<TARGET_OBJECTS:menoh_objlib>)
+target_link_libraries(menoh_test_target PUBLIC ${MKLDNN_LIBRARIES} onnx)
 
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 6224acb..9c296bb 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,8 +1,6 @@
-enable_testing()
-
 # GTest setup
 set(GTEST_DIR "lib/googletest")
-execute_process(COMMAND git submodule update --init -- test/${GTEST_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init -- "${GTEST_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 message(STATUS "Adding ${GTEST_DIR}")
 
@@ -14,8 +12,8 @@ add_subdirectory(${GTEST_DIR} EXCLUDE_FROM_ALL)
 
 # filesystem setup
 set(FILESYSTEM_DIR "lib/filesystem")
-execute_process(COMMAND git submodule update --init -- test/${FILESYSTEM_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-include_directories("${FILESYSTEM_DIR}")
+execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init -- "${FILESYSTEM_DIR}" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+#include_directories("${FILESYSTEM_DIR}")
 
 add_executable(menoh_test
     np_io.cpp
@@ -31,7 +29,11 @@ add_executable(menoh_test
     #vgg16.cpp
 )
 
-target_include_directories(menoh_test PUBLIC $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
+target_include_directories(menoh_test PUBLIC
+    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
+    "${PROJECT_SOURCE_DIR}"
+    "${PROJECT_SOURCE_DIR}/include"
+    "${FILESYSTEM_DIR}")
 
 if(LINK_STATIC_LIBPROTOBUF)
     target_link_libraries(menoh_test gtest_main menoh_test_target)
@@ -45,4 +47,4 @@ if(UNIX AND NOT APPLE)
             LINK_FLAGS "-Wl,--disable-new-dtags")
 endif()
 
-add_test(NAME menoh_test COMMAND menoh_test)
+#add_test(NAME menoh_test COMMAND menoh_test)

From 0f3f904b49323d59eeb2bcaa12b3f94dc623cef0 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 3 Dec 2018 11:28:43 +0900
Subject: [PATCH 268/321] build libonnx static

---
 CMakeLists.txt       | 4 ++++
 menoh/CMakeLists.txt | 4 ++--
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 95dd3d6..bc8a2d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,11 @@ configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/
 
 # TODO: enable the following option when it is ready for migrating to onnx-ml
 #set(ONNX_ML 1)
+
+set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
+set(BUILD_SHARED_LIBS OFF)
 add_subdirectory(${EXTERNAL_DIR}/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
+set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
 
 if(${ENABLE_TEST})
     message(STATUS "Adding test")
diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 831db9f..a96c2d4 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -55,7 +55,7 @@ if(NOT APPLE AND NOT MSVC)
         TARGET menoh APPEND_STRING PROPERTY
             LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/menoh.map")
 endif()
-target_link_libraries(menoh PUBLIC ${MKLDNN_LIBRARIES} onnx)
+target_link_libraries(menoh PRIVATE ${MKLDNN_LIBRARIES} onnx)
 if(LINK_STATIC_LIBGCC)
     target_link_libraries(menoh PRIVATE -static-libgcc)
 endif()
@@ -65,7 +65,7 @@ endif()
 
 # menoh_test_target: only used in `test` subdirectory
 add_library(menoh_test_target $<TARGET_OBJECTS:menoh_objlib>)
-target_link_libraries(menoh_test_target PUBLIC ${MKLDNN_LIBRARIES} onnx)
+target_link_libraries(menoh_test_target PRIVATE ${MKLDNN_LIBRARIES} onnx)
 
 install(TARGETS menoh
     RUNTIME DESTINATION "bin"

From 3e53590c71a2b41f1df186fb2dc326c8a1c38cde Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 3 Dec 2018 15:03:33 +0900
Subject: [PATCH 269/321] add onnx include directory for test

---
 test/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9c296bb..0876f2d 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -33,6 +33,7 @@ target_include_directories(menoh_test PUBLIC
     $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     "${PROJECT_SOURCE_DIR}"
     "${PROJECT_SOURCE_DIR}/include"
+    "${ONNX_INCLUDE_DIRS}"
     "${FILESYSTEM_DIR}")
 
 if(LINK_STATIC_LIBPROTOBUF)

From 306fd06711505b19fcbbf7ad86774ddb2b0d031f Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Dec 2018 11:14:49 +0900
Subject: [PATCH 270/321] fix menoh/CMakeLists.txt to refer MKLDNN_INCLUDE_DIR
 again

---
 menoh/CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index a96c2d4..a8d23eb 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -45,6 +45,7 @@ target_include_directories(menoh_objlib PUBLIC
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
     $<BUILD_INTERFACE:${ONNX_INCLUDE_DIRS}>
+    $<BUILD_INTERFACE:${MKLDNN_INCLUDE_DIR}>
 )
 
 # menoh

From 6574c83578c901537bc58f4753ea211fee2e40be Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 4 Dec 2018 15:54:15 +0900
Subject: [PATCH 271/321] fix ctest command

---
 CMakeLists.txt      | 1 +
 test/CMakeLists.txt | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index bc8a2d1..f8f5057 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,6 +104,7 @@ set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
 
 if(${ENABLE_TEST})
     message(STATUS "Adding test")
+    enable_testing()
     add_subdirectory(test)
 endif()
 
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 0876f2d..a13badf 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -48,4 +48,4 @@ if(UNIX AND NOT APPLE)
             LINK_FLAGS "-Wl,--disable-new-dtags")
 endif()
 
-#add_test(NAME menoh_test COMMAND menoh_test)
+add_test(NAME menoh_test COMMAND menoh_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

From c00b0a5e04a9266660cb34a27b365f4efd22160a Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Tue, 4 Dec 2018 17:08:13 +0900
Subject: [PATCH 272/321] fix include path order so that include directory have
 precedence over PROTOBUF_INCLUDE_DIRS

PROTOBUF_INCLUDE_DIRS can be a system directory such as
/usr/local/include and this change is necessary for using bundled
include files instead of the ones installed in the system directory.
---
 menoh/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index a8d23eb..756f456 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -41,9 +41,9 @@ add_library(menoh_objlib OBJECT
 set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})
 add_dependencies(menoh_objlib gen_onnx_proto) # custom target defined in onnx
 target_include_directories(menoh_objlib PUBLIC
-    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
+    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     $<BUILD_INTERFACE:${ONNX_INCLUDE_DIRS}>
     $<BUILD_INTERFACE:${MKLDNN_INCLUDE_DIR}>
 )

From 425878a86dcda708e0b83dd8e9baf5e2237adaf8 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 4 Dec 2018 17:43:29 +0900
Subject: [PATCH 273/321] fix include path order for test

---
 test/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a13badf..386cc60 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -30,9 +30,9 @@ add_executable(menoh_test
 )
 
 target_include_directories(menoh_test PUBLIC
-    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     "${PROJECT_SOURCE_DIR}"
     "${PROJECT_SOURCE_DIR}/include"
+    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     "${ONNX_INCLUDE_DIRS}"
     "${FILESYSTEM_DIR}")
 

From eefae31cdeb9d6acd4644317a5e5e5eb70325e72 Mon Sep 17 00:00:00 2001
From: Kunihiko MIYOSHI <miyoshik@gmail.com>
Date: Tue, 11 Dec 2018 23:30:56 +0900
Subject: [PATCH 274/321] remove deprecated api

---
 menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
index 49a1081..2bf2bbe 100644
--- a/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
+++ b/menoh/composite_backend/backend/mkldnn/operator/batch_norm.hpp
@@ -88,8 +88,7 @@ namespace menoh_impl {
                 mkldnn::batch_normalization_forward::desc batch_norm_desc(
                   mkldnn::prop_kind::forward_inference,
                   input_memory.get_primitive_desc().desc(), epsilon,
-                  mkldnn::use_global_stats | mkldnn::use_scale_shift |
-                    mkldnn::omit_stats);
+                  mkldnn::use_global_stats | mkldnn::use_scale_shift);
                 mkldnn::batch_normalization_forward::primitive_desc
                   batch_norm_pd(batch_norm_desc, engine);
 

From 993d2c709e668a6ba6b30f6e6eb691bc023572c6 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 2 Jan 2019 00:24:25 +0900
Subject: [PATCH 275/321] add menoh_variable_profile_table_get_dims() and
 menoh_model_get_variable_dims()

---
 include/menoh/menoh.h | 38 +++++++++++++++++++++++++++++++-------
 menoh/menoh.cpp       | 21 +++++++++++++++++++++
 2 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index 243a332..c461bd4 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -101,7 +101,8 @@ MENOH_API const char* menoh_get_last_error_message();
  */
 /*! \breaf Element size of given menoh_dtype.
  */
-menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype, int32_t *dst_size);
+menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype,
+                                            int32_t* dst_size);
 
 /*! @addtogroup model_data Model data types and operations
  * @{ */
@@ -226,7 +227,8 @@ menoh_variable_profile_table_builder_add_input_profile(
  *
  * Input profile contains name, dtype and dims (num, size). This 2D input is
  * conventional batched 1D inputs.
- * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_input_profile() instead
+ * \warning This function is depreated. Please use
+ * menoh_variable_profile_table_builder_add_input_profile() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_input_profile() instead")
@@ -240,7 +242,8 @@ menoh_variable_profile_table_builder_add_input_profile_dims_2(
  * Input profile contains name, dtype and dims (num, channel, height, width).
  * This 4D input is conventional batched image inputs. Image input is
  * 3D(channel, height, width).
- * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_input_profile() instead
+ * \warning This function is depreated. Please use
+ * menoh_variable_profile_table_builder_add_input_profile() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_input_profile() instead")
@@ -262,7 +265,8 @@ menoh_error_code MENOH_API menoh_variable_profile_table_builder_add_output_name(
  *
  * Output profile contains name and dtype. Its dims are calculated automatically
  * when calling of menoh_build_variable_profile_table.
- * \warning This function is depreated. Please use menoh_variable_profile_table_builder_add_output_name() instead
+ * \warning This function is depreated. Please use
+ * menoh_variable_profile_table_builder_add_output_name() instead
  */
 MENOH_DEPRECATED_ATTRIBUTE(
   "please use menoh_variable_profile_table_builder_add_output_name() instead. "
@@ -284,9 +288,11 @@ typedef struct menoh_variable_profile_table*
 
 /*! \brief Factory function for variable_profile_table
  *
- * \note this function throws menoh_input_not_found_error when no nodes have given input name.
- * \note this function throws menoh_output_not_found_error when no nodes have given output name.
- * \note this function throws menoh_variable_not_found_error when needed variable for model execution does not exist.
+ * \note this function throws menoh_input_not_found_error when no nodes have
+ * given input name. \note this function throws menoh_output_not_found_error
+ * when no nodes have given output name. \note this function throws
+ * menoh_variable_not_found_error when needed variable for model execution does
+ * not exist.
  */
 menoh_error_code MENOH_API menoh_build_variable_profile_table(
   const menoh_variable_profile_table_builder_handle builder,
@@ -328,6 +334,15 @@ menoh_error_code MENOH_API menoh_variable_profile_table_get_dims_at(
   const menoh_variable_profile_table_handle variable_profile_table,
   const char* variable_name, int32_t index, int32_t* dst_size);
 
+/*! \brief Accessor function for variable_profile_table
+ *
+ * Select variable name, then get its dims size and dims array
+ *
+ */
+menoh_error_code MENOH_API menoh_variable_profile_table_get_dims(
+  const menoh_variable_profile_table_handle variable_profile_table,
+  const char* variable_name, int32_t* dst_size, const int32_t** dims);
+
 /** @} */
 
 /*! @ingroup model_data
@@ -438,6 +453,15 @@ menoh_error_code MENOH_API menoh_model_get_variable_dims_at(
   const menoh_model_handle model, const char* variable_name, int32_t index,
   int32_t* dst_size);
 
+/*! \brief Get dims of target variable
+ *
+ * \sa
+ * menoh_variable_profile_table_get_dims()
+ */
+menoh_error_code MENOH_API menoh_model_get_variable_dims(
+  const menoh_model_handle model, const char* variable_name, int32_t* dst_size,
+  const int32_t** dims);
+
 /*! \brief Run model inference
  *
  * \warning This function can't be called asynchronously.
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 653ca0c..2b20d9b 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -464,6 +464,16 @@ menoh_error_code menoh_variable_profile_table_get_dims_at(
       [&](auto const& profile) { *dst_size = profile.dims().at(index); });
 }
 
+menoh_error_code menoh_variable_profile_table_get_dims(
+  const menoh_variable_profile_table_handle variable_profile_table,
+  const char* name, int32_t* dst_size, const int32_t** dims) {
+    return impl::menoh_variable_profile_table_get_variable_attribute(
+      variable_profile_table, name, [&](auto const& profile) {
+          *dst_size = profile.dims().size();
+          *dims = profile.dims().data();
+      });
+}
+
 menoh_error_code menoh_model_data_optimize(
   menoh_model_data_handle model_data,
   const menoh_variable_profile_table_handle variable_profile_table) {
@@ -655,6 +665,17 @@ menoh_model_get_variable_dims_at(const menoh_model_handle model,
       [&](menoh_impl::array const& arr) { *dst_size = arr.dims().at(index); });
 }
 
+menoh_error_code menoh_model_get_variable_dims(const menoh_model_handle model,
+                                               const char* variable_name,
+                                               int32_t* dst_size,
+                                               const int32_t** dims) {
+    return impl::menoh_model_get_variable_variable_attribute(
+      model, variable_name, [&](menoh_impl::array const& arr) {
+          *dst_size = arr.dims().size();
+          *dims = arr.dims().data();
+      });
+}
+
 menoh_error_code menoh_model_run(menoh_model_handle model) {
     return check_error([&]() {
         model->model_core->run();

From 4d3da381fbd48604b7d8facd2c71696a0ef8e3d8 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 7 Jan 2019 10:19:11 +0900
Subject: [PATCH 276/321] update vgg16_example_in_c

---
 example/vgg16_example_in_c.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index 423b4fd..ce1d796 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -1,11 +1,13 @@
 
 #if defined(_WIN32) || defined(__WIN32__)
 #include <Windows.h>
-#endif 
+#endif
 
-#include <menoh/menoh.h>
+#include <assert.h>
 #include <stdio.h>
 
+#include <menoh/menoh.h>
+
 #define ERROR_CHECK(statement)                            \
     {                                                     \
         menoh_error_code ec = statement;                  \
@@ -18,13 +20,13 @@
 int main() {
     menoh_error_code ec = menoh_error_code_success;
 
-    const char* conv1_1_in_name = "140326425860192";
-    const char* fc6_out_name = "140326200777584";
-    const char* softmax_out_name = "140326200803680";
+    const char* conv1_1_in_name = "Input_0";
+    const char* fc6_out_name = "Gemm_0";
+    const char* softmax_out_name = "Softmax_0";
 
     menoh_model_data_handle model_data;
     ERROR_CHECK(
-      menoh_make_model_data_from_onnx("../data/VGG16.onnx", &model_data));
+      menoh_make_model_data_from_onnx("../data/vgg16.onnx", &model_data));
 
     menoh_variable_profile_table_builder_handle vpt_builder;
     ERROR_CHECK(menoh_make_variable_profile_table_builder(&vpt_builder));
@@ -42,11 +44,22 @@ int main() {
     ERROR_CHECK(menoh_build_variable_profile_table(vpt_builder, model_data,
                                                    &variable_profile_table));
 
+    /*
     int32_t softmax_out_dims[2];
     ERROR_CHECK(menoh_variable_profile_table_get_dims_at(
       variable_profile_table, softmax_out_name, 0, &softmax_out_dims[0]));
     ERROR_CHECK(menoh_variable_profile_table_get_dims_at(
       variable_profile_table, softmax_out_name, 1, &softmax_out_dims[1]));
+    */
+
+    int32_t softmax_out_dims_size;
+    const int32_t* softmax_out_dims;
+    ERROR_CHECK(menoh_variable_profile_table_get_dims(
+      variable_profile_table, softmax_out_name, &softmax_out_dims_size,
+      &softmax_out_dims));
+    assert(softmax_out_dims_size == 1);
+    assert(softmax_out_dims[0]== 2);
+    assert(softmax_out_dims[1] == 1000);
 
     ERROR_CHECK(menoh_model_data_optimize(model_data, variable_profile_table));
 

From ca2a299d284970a3964f1f5af7ba2c55a88214bc Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 7 Jan 2019 10:19:31 +0900
Subject: [PATCH 277/321] fix format

---
 example/vgg16_example_in_c.c |  8 ++++----
 menoh/menoh.cpp              | 34 ++++++++++++++++++----------------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index ce1d796..e555ee0 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -79,11 +79,11 @@ int main() {
       model_data); // you can delete model_data after model building
 
     float* fc6_output_buff;
-    ERROR_CHECK(menoh_model_get_variable_buffer_handle(model, fc6_out_name,
-                                              (void**)&fc6_output_buff));
+    ERROR_CHECK(menoh_model_get_variable_buffer_handle(
+      model, fc6_out_name, (void**)&fc6_output_buff));
     float* softmax_output_buff;
-    ERROR_CHECK(menoh_model_get_variable_buffer_handle(model, softmax_out_name,
-                                              (void**)&softmax_output_buff));
+    ERROR_CHECK(menoh_model_get_variable_buffer_handle(
+      model, softmax_out_name, (void**)&softmax_output_buff));
 
     // initialie input_buf here
     for(int i = 0; i < 1 * 3 * 224 * 224; ++i) {
diff --git a/menoh/menoh.cpp b/menoh/menoh.cpp
index 2b20d9b..3f979b9 100644
--- a/menoh/menoh.cpp
+++ b/menoh/menoh.cpp
@@ -93,24 +93,26 @@ menoh_error_code check_error(Func func) {
  * dtype
  */
 
-menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype, int32_t *dst_size) {
-    switch (dtype) {
-#define MENOH_DTYPE_SIZE_CASE(dtype) \
-    case dtype: \
-        *dst_size = menoh_impl::size_in_bytes<static_cast<menoh_impl::dtype_t>(dtype)>; \
+menoh_error_code MENOH_API menoh_dtype_size(menoh_dtype dtype,
+                                            int32_t* dst_size) {
+    switch(dtype) {
+#define MENOH_DTYPE_SIZE_CASE(dtype)                                          \
+    case dtype:                                                               \
+        *dst_size =                                                           \
+          menoh_impl::size_in_bytes<static_cast<menoh_impl::dtype_t>(dtype)>; \
         break;
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float16)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_float64)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int8)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int16)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int32)
-    MENOH_DTYPE_SIZE_CASE(menoh_dtype_int64)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_float)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_float16)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_float64)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_int8)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_int16)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_int32)
+        MENOH_DTYPE_SIZE_CASE(menoh_dtype_int64)
 #undef MENOH_DTYPE_SIZE_CASE
-    default:
-        std::string msg("unknown dtype: " + std::to_string(dtype));
-        menoh_impl::set_last_error_message(msg.c_str());
-        return menoh_error_code_invalid_dtype;
+        default:
+            std::string msg("unknown dtype: " + std::to_string(dtype));
+            menoh_impl::set_last_error_message(msg.c_str());
+            return menoh_error_code_invalid_dtype;
     }
     return menoh_error_code_success;
 }

From 8e9e55bff566e7f46e7b0898bf03d8cf95b277e9 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 7 Jan 2019 10:57:38 +0900
Subject: [PATCH 278/321] modify wrong assertion

---
 example/vgg16_example_in_c.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index e555ee0..7b43bf0 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -44,6 +44,15 @@ int main() {
     ERROR_CHECK(menoh_build_variable_profile_table(vpt_builder, model_data,
                                                    &variable_profile_table));
 
+    int32_t softmax_out_dims_size;
+    const int32_t* softmax_out_dims;
+    ERROR_CHECK(menoh_variable_profile_table_get_dims(
+      variable_profile_table, softmax_out_name, &softmax_out_dims_size,
+      &softmax_out_dims));
+    assert(softmax_out_dims_size == 2);
+    assert(softmax_out_dims[0]== 1);
+    assert(softmax_out_dims[1] == 1000);
+
     /*
     int32_t softmax_out_dims[2];
     ERROR_CHECK(menoh_variable_profile_table_get_dims_at(
@@ -52,14 +61,6 @@ int main() {
       variable_profile_table, softmax_out_name, 1, &softmax_out_dims[1]));
     */
 
-    int32_t softmax_out_dims_size;
-    const int32_t* softmax_out_dims;
-    ERROR_CHECK(menoh_variable_profile_table_get_dims(
-      variable_profile_table, softmax_out_name, &softmax_out_dims_size,
-      &softmax_out_dims));
-    assert(softmax_out_dims_size == 1);
-    assert(softmax_out_dims[0]== 2);
-    assert(softmax_out_dims[1] == 1000);
 
     ERROR_CHECK(menoh_model_data_optimize(model_data, variable_profile_table));
 

From de497f6b835b7af16a76d720f2def0cba721df63 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 7 Jan 2019 11:00:02 +0900
Subject: [PATCH 279/321] add comment for get_dims_size() and get_dims_at()

---
 example/vgg16_example_in_c.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/example/vgg16_example_in_c.c b/example/vgg16_example_in_c.c
index 7b43bf0..d6e48c1 100644
--- a/example/vgg16_example_in_c.c
+++ b/example/vgg16_example_in_c.c
@@ -53,6 +53,7 @@ int main() {
     assert(softmax_out_dims[0]== 1);
     assert(softmax_out_dims[1] == 1000);
 
+    /* Another way to take dims of variables */
     /*
     int32_t softmax_out_dims[2];
     ERROR_CHECK(menoh_variable_profile_table_get_dims_at(

From e14b588b5af95553ebed43e006527e77c35ab1dc Mon Sep 17 00:00:00 2001
From: Toru Ogawa <Hakuyume@users.noreply.github.com>
Date: Mon, 14 Jan 2019 17:48:46 +0900
Subject: [PATCH 280/321] do not use max_element

---
 menoh/composite_backend/backend/generic/operator/sigmoid.hpp | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator/sigmoid.hpp b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
index 40c78e3..2f895bf 100644
--- a/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
+++ b/menoh/composite_backend/backend/generic/operator/sigmoid.hpp
@@ -21,12 +21,9 @@ namespace menoh_impl {
                 }
 
                 auto procedure = [input, output = output_list.at(0)]() {
-                    auto m = *std::max_element(fbegin(input), fend(input));
-                    auto em = std::exp(-m);
                     for(decltype(total_size(input)) i = 0;
                         i < total_size(input); ++i) {
-                        auto e = std::exp(fat(input, i) - m);
-                        fat(output, i) = e / (e + em);
+                        fat(output, i) = 1 / (1 + std::exp(-fat(input, i)));
                     }
                 };
 

From 13ef20fd1adbcbe45e8f2cde80517d0147d8dc83 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 17 Jan 2019 15:23:17 +0900
Subject: [PATCH 281/321] make POSITION_INDEPENDENT_CODE=ON default

---
 menoh/CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 756f456..8694273 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -38,7 +38,7 @@ add_library(menoh_objlib OBJECT
     menoh.cpp
     model_core.cpp
 )
-set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS})
+set_target_properties(menoh_objlib PROPERTIES POSITION_INDEPENDENT_CODE ON)
 add_dependencies(menoh_objlib gen_onnx_proto) # custom target defined in onnx
 target_include_directories(menoh_objlib PUBLIC
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>

From 0d6061c3140ecc2ccd2aee9ecd6a7413ae8336a1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 18 Jan 2019 14:29:54 +0900
Subject: [PATCH 282/321] fix example name

---
 example/CMakeLists.txt                               | 12 ++++++------
 ...16_example_in_c.c => mkldnn_vgg16_example_in_c.c} |  0
 ...le_in_cpp.cpp => mkldnn_vgg16_example_in_cpp.cpp} |  5 ++---
 3 files changed, 8 insertions(+), 9 deletions(-)
 rename example/{vgg16_example_in_c.c => mkldnn_vgg16_example_in_c.c} (100%)
 rename example/{vgg16_example_in_cpp.cpp => mkldnn_vgg16_example_in_cpp.cpp} (97%)

diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt
index fa7cef1..34c3a10 100644
--- a/example/CMakeLists.txt
+++ b/example/CMakeLists.txt
@@ -5,14 +5,14 @@ if (NOT OpenCV_FOUND)
 endif()
 
 # Build vgg16_example_in_c
-add_executable(vgg16_example_in_c vgg16_example_in_c.c)
-target_include_directories(vgg16_example_in_c PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
-target_link_libraries(vgg16_example_in_c menoh)
+add_executable(mkldnn_vgg16_example_in_c mkldnn_vgg16_example_in_c.c)
+target_include_directories(mkldnn_vgg16_example_in_c PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
+target_link_libraries(mkldnn_vgg16_example_in_c menoh)
 
 # Build vgg16_example_in_cpp
-add_executable(vgg16_example_in_cpp vgg16_example_in_cpp.cpp)
-target_include_directories(vgg16_example_in_cpp PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
-target_link_libraries(vgg16_example_in_cpp menoh ${OpenCV_LIBS})
+add_executable(mkldnn_vgg16_example_in_cpp mkldnn_vgg16_example_in_cpp.cpp)
+target_include_directories(mkldnn_vgg16_example_in_cpp PUBLIC "${PROJECT_SOURCE_DIR}/include" "${OpenCV_INCLUDE_DIRS}")
+target_link_libraries(mkldnn_vgg16_example_in_cpp menoh ${OpenCV_LIBS})
 
 # Buld general_cnn_example_in_cpp
 add_executable(general_cnn_example_in_cpp general_cnn_example_in_cpp.cpp)
diff --git a/example/vgg16_example_in_c.c b/example/mkldnn_vgg16_example_in_c.c
similarity index 100%
rename from example/vgg16_example_in_c.c
rename to example/mkldnn_vgg16_example_in_c.c
diff --git a/example/vgg16_example_in_cpp.cpp b/example/mkldnn_vgg16_example_in_cpp.cpp
similarity index 97%
rename from example/vgg16_example_in_cpp.cpp
rename to example/mkldnn_vgg16_example_in_cpp.cpp
index 962b73d..8b2512b 100644
--- a/example/vgg16_example_in_cpp.cpp
+++ b/example/mkldnn_vgg16_example_in_cpp.cpp
@@ -131,9 +131,8 @@ int main(int argc, char** argv) {
       fc6_out_name, static_cast<void*>(fc6_out_data.data()));
 
     // Build model
-    auto model = model_builder.build_model(
-      model_data, "composite_backend",
-      R"({"backends":[{"type":"mkldnn"}, {"type":"generic"}], "log_output":"stdout"})");
+    auto model =
+      model_builder.build_model(model_data, "mkldnn_with_generic_fallback");
     model_data
       .reset(); // you can delete model_data explicitly after model building
 

From 6a80cb34efc316f1ff57053d3ac4b55de3bd9d68 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 18 Jan 2019 14:30:07 +0900
Subject: [PATCH 283/321] fix format

---
 example/mkldnn_vgg16_example_in_cpp.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/example/mkldnn_vgg16_example_in_cpp.cpp b/example/mkldnn_vgg16_example_in_cpp.cpp
index 8b2512b..408964d 100644
--- a/example/mkldnn_vgg16_example_in_cpp.cpp
+++ b/example/mkldnn_vgg16_example_in_cpp.cpp
@@ -89,8 +89,7 @@ int main(int argc, char** argv) {
     auto onnx_model_path = a.get<std::string>("model");
     auto synset_words_path = a.get<std::string>("synset_words");
 
-    cv::Mat image_mat =
-      cv::imread(input_image_path.c_str(), cv::IMREAD_COLOR);
+    cv::Mat image_mat = cv::imread(input_image_path.c_str(), cv::IMREAD_COLOR);
     if(!image_mat.data) {
         throw std::runtime_error("Invalid input image path: " +
                                  input_image_path);

From 14c02b77d2593446c28a99a230efc8859dcad45c Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 22 Jan 2019 17:24:54 +0900
Subject: [PATCH 284/321] disable STATIC_LINK_LIBPROTOBUF option when menoh is
 build as static library

---
 CMakeLists.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8f5057..0b3d767 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,6 +54,9 @@ if(LINK_STATIC_LIBPROTOBUF)
     # Note: We can't use `set(PROTOBUF_BUILD_SHARED_LIBS OFF)` in `FindProtobuf` module
     # because `libprotobuf.a` produced by the package manager is not PIC. So we need to
     # build it by ourselves.
+    if(NOT BUILD_SHARED_LIBS)
+        message(FATAL_ERROR "LINK_STATIC_LIBPROTOBUF=ON is supported only when BUILD_SHARED_LIBS=ON")
+    endif()
     if(UNIX OR MINGW)
         include(BuildProtobuf)
     else()

From dc189cb2395ec6fc9138211623b310576a47f30b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 22 Jan 2019 19:18:52 +0900
Subject: [PATCH 285/321] change `onnx` namespacce `menoh_onnx`

---
 CMakeLists.txt    |  1 +
 menoh/onnx.cpp    | 26 +++++++++++++-------------
 test/operator.cpp |  6 +++---
 3 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8f5057..aee54d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -99,6 +99,7 @@ configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/
 
 set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
 set(BUILD_SHARED_LIBS OFF)
+set(ONNX_NAMESPACE "menoh_onnx")
 add_subdirectory(${EXTERNAL_DIR}/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
 set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
 
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 58afd28..323e6ec 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -21,22 +21,22 @@
 
 namespace menoh_impl {
 
-    dtype_t tensor_proto_data_type_to_dtype(onnx::TensorProto_DataType tpdt) {
-        if(tpdt == onnx::TensorProto_DataType_FLOAT) {
+    dtype_t tensor_proto_data_type_to_dtype(menoh_onnx::TensorProto_DataType tpdt) {
+        if(tpdt == menoh_onnx::TensorProto_DataType_FLOAT) {
             return dtype_t::float_;
-        } else if(tpdt == onnx::TensorProto_DataType_INT8) {
+        } else if(tpdt == menoh_onnx::TensorProto_DataType_INT8) {
             return dtype_t::int8;
-        } else if(tpdt == onnx::TensorProto_DataType_INT16) {
+        } else if(tpdt == menoh_onnx::TensorProto_DataType_INT16) {
             return dtype_t::int16;
-        } else if(tpdt == onnx::TensorProto_DataType_INT32) {
+        } else if(tpdt == menoh_onnx::TensorProto_DataType_INT32) {
             return dtype_t::int32;
-        } else if(tpdt == onnx::TensorProto_DataType_INT64) {
+        } else if(tpdt == menoh_onnx::TensorProto_DataType_INT64) {
             return dtype_t::int64;
         }
         throw invalid_dtype(std::to_string(tpdt));
     }
 
-    auto extract_parameter_name_set(onnx::GraphProto const& graph) {
+    auto extract_parameter_name_set(menoh_onnx::GraphProto const& graph) {
         std::set<std::string> parameter_name_set;
         for(int i = 0; i < graph.initializer_size(); ++i) {
             auto& tensor = graph.initializer(i);
@@ -83,7 +83,7 @@ namespace menoh_impl {
     }
 
     template <menoh_impl::dtype_t dtype>
-    auto move_tensor_from_onnx_data(int total_size, onnx::TensorProto& tensor) {
+    auto move_tensor_from_onnx_data(int total_size, menoh_onnx::TensorProto& tensor) {
         // libc++ workaround
         // Below 2 lines are equal to `data =
         // std::unique_ptr<float_t[]>(new float_t[total_size]);`
@@ -102,7 +102,7 @@ namespace menoh_impl {
     }
 
     auto extract_parameter_name_and_array_list_from_onnx_graph(
-      onnx::GraphProto& graph,
+      menoh_onnx::GraphProto& graph,
       std::vector<std::string> const& needed_parameter_name_list) {
         std::vector<std::pair<std::string, menoh_impl::array>>
           parameter_name_and_array_list;
@@ -147,7 +147,7 @@ namespace menoh_impl {
         return parameter_name_and_array_list;
     }
 
-    auto extract_node_list_from_onnx_graph(onnx::GraphProto const& graph) {
+    auto extract_node_list_from_onnx_graph(menoh_onnx::GraphProto const& graph) {
         std::vector<node> node_list;
         for(auto const& onnx_node : graph.node()) {
             std::unordered_map<std::string, attribute> attribute_table;
@@ -183,7 +183,7 @@ namespace menoh_impl {
         return node_list;
     }
 
-    model_data make_model_from_onnx(onnx::ModelProto& onnx_model) {
+    model_data make_model_from_onnx(menoh_onnx::ModelProto& onnx_model) {
         // onnx opset version check
         if(onnx_model.opset_import_size() != 0) {
             int version = onnx_model.opset_import(0).version();
@@ -233,7 +233,7 @@ namespace menoh_impl {
         gpio::CodedInputStream cis(&iis);
         cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
                                std::numeric_limits<int>::max());
-        onnx::ModelProto onnx_model;
+        menoh_onnx::ModelProto onnx_model;
         if(!onnx_model.ParseFromCodedStream(&cis)) {
             throw onnx_parse_error(filename);
         }
@@ -248,7 +248,7 @@ namespace menoh_impl {
         gpio::CodedInputStream cis(&ais);
         cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
                                std::numeric_limits<int>::max());
-        onnx::ModelProto onnx_model;
+        menoh_onnx::ModelProto onnx_model;
         if(!onnx_model.ParseFromCodedStream(&cis) ||
            !cis.ConsumedEntireMessage()) {
             throw onnx_parse_error("parse binary onnx data on memory");
diff --git a/test/operator.cpp b/test/operator.cpp
index aa31d95..81aa43c 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -35,7 +35,7 @@ namespace {
         gpio::CodedInputStream cis(&iis);
         cis.SetTotalBytesLimit(std::numeric_limits<int>::max(),
                                std::numeric_limits<int>::max());
-        onnx::TensorProto tensor;
+        menoh_onnx::TensorProto tensor;
         if(!tensor.ParseFromCodedStream(&cis)) {
             std::cout << "invalid filename" << std::endl;
             throw "onnx_parse_error";
@@ -52,7 +52,7 @@ namespace {
         auto total_size =
           std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int>());
         assert(tensor.has_raw_data());
-        if(tensor.data_type() == onnx::TensorProto_DataType_FLOAT) {
+        if(tensor.data_type() == menoh_onnx::TensorProto_DataType_FLOAT) {
             assert(tensor.raw_data().length() ==
                    static_cast<decltype(tensor.raw_data().length())>(
                      total_size * 4));
@@ -64,7 +64,7 @@ namespace {
             return named_array_data{tensor.name(), menoh::dtype_t::float32,
                                     std::move(dims), std::move(data)};
         }
-        if(tensor.data_type() == onnx::TensorProto_DataType_INT64) {
+        if(tensor.data_type() == menoh_onnx::TensorProto_DataType_INT64) {
             assert(tensor.raw_data().length() ==
                    static_cast<decltype(tensor.raw_data().length())>(
                      total_size * 8));

From d12fe2913b268b1661897840d26a5300b500543f Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 22 Jan 2019 19:19:19 +0900
Subject: [PATCH 286/321] rename libonnx and libonnx_proto -> libmenoh_onnx and
 libmenoh_onnx_proto

---
 CMakeLists.txt | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index aee54d5..7b785bd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -101,6 +101,13 @@ set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
 set(BUILD_SHARED_LIBS OFF)
 set(ONNX_NAMESPACE "menoh_onnx")
 add_subdirectory(${EXTERNAL_DIR}/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
+if(NOT ${BUILD_SHARED_LIBS_SAVED}) # install libmenoh_onnx and lib_menoh_onnx_proto
+    set_target_properties(onnx_proto PROPERTIES OUTPUT_NAME "menoh_onnx_proto")
+    set_target_properties(onnx PROPERTIES OUTPUT_NAME "menoh_onnx")
+    find_library(MENOH_ONNX_PROTO_LIB "menoh_onnx_proto" "${CMAKE_CURRENT_BINARY_DIR}/external/onnx")
+    find_library(MENOH_ONNX_LIB "menoh_onnx" "${CMAKE_CURRENT_BINARY_DIR}/external/onnx")
+    install(FILES "${MENOH_ONNX_LIB}" "${MENOH_ONNX_PROTO_LIB}" DESTINATION "lib")
+endif()
 set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
 
 if(${ENABLE_TEST})

From bfa7bd9bab8973469e03db8eff99d20f1500841a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 22 Jan 2019 19:29:25 +0900
Subject: [PATCH 287/321] add Libs.private

---
 include/menoh.pc.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/menoh.pc.in b/include/menoh.pc.in
index f07440f..cff44bf 100644
--- a/include/menoh.pc.in
+++ b/include/menoh.pc.in
@@ -6,6 +6,6 @@ includedir=${prefix}/include
 Name: Menoh
 Description: DNN inference library written in C++
 Version: @MENOH_MAJOR_VERSION@.@MENOH_MINOR_VERSION@.@MENOH_PATCH_VERSION@
-
 Libs: -L${libdir} -lmenoh
+Libs.private: -lmenoh_onnx -lmenoh_onnx_proto
 Cflags: -I${includedir}

From 19194e0a399daec55a93ad50c46eb5407cc1b655 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 22 Jan 2019 19:34:47 +0900
Subject: [PATCH 288/321] add option INSTALL_PKGCONFIG_DIR

---
 CMakeLists.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7b785bd..1f2a533 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -16,6 +16,8 @@ option(ENABLE_EXAMPLE "Build example" ON)
 
 option(BUILD_SHARED_LIBS "Build shared libs" ON)
 
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "installation path for pkg-config(.pc) file")
+
 option(SHOW_ALL_VARIABLES "Debug: show all variables" OFF)
 
 ## C++ setup

From 7b882c4961519f9ce7c5220bab35ae9bcefe7d2b Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 30 Jan 2019 18:16:41 +0900
Subject: [PATCH 289/321] travis: configure static library builds

---
 .travis.yml                 |  4 ++++
 .travis/init-build-linux.sh | 14 ++++++++++++--
 .travis/init-build-osx.sh   | 14 ++++++++++++--
 scripts/build-menoh.sh      |  6 ++++++
 4 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index ac28c6d..ed255fe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -26,10 +26,14 @@ matrix:
           env: PLATFORM=macosx-x86_64
         - os: osx
           env: PLATFORM=macosx-x86_64 LINK_STATIC=true
+        - os: osx
+          env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 LINK_STATIC=true
+        - os: linux
+          env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6 BUILD_STATIC_LIBS=true
         # Use Travis directly instead of container to run static code analysis using Coverity
         - if: branch = coverity_scan
           os: linux
diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index ae5f0db..a4cdb42 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -4,6 +4,7 @@ test -n "${MKLDNN_VERSION}" || { echo "MKLDNN_VERSION can't be empty" 1>&2; exit
 test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
 
 test -n "${LINK_STATIC}" || LINK_STATIC=false
+test -n "${BUILD_STATIC_LIBS}" || BUILD_STATIC_LIBS=false
 
 # TODO: make them configurable for outside Travis
 export WORK_DIR=${HOME}
@@ -74,7 +75,14 @@ function prepare_menoh_data() {
 }
 
 function build_menoh() {
-    if [ "${LINK_STATIC}" != "true" ]; then
+    if [ "${BUILD_STATIC_LIBS}" = "true" ]; then
+        docker_exec_script \
+            "${PROJ_DIR}/scripts/build-menoh.sh" \
+                --build-type Release \
+                --source-dir "${PROJ_DIR}" \
+                --python-executable python3 \
+                --build-shared-libs OFF
+    elif [ "${LINK_STATIC}" != "true" ]; then
         docker_exec_script \
             "${PROJ_DIR}/scripts/build-menoh.sh" \
                 --build-type Release \
@@ -97,5 +105,7 @@ function test_menoh() {
 }
 
 function check_menoh_artifact() {
-    docker_exec "ldd \"${PROJ_DIR}/build/menoh/libmenoh.so\""
+    if [ "${BUILD_STATIC_LIBS}" != "true" ]; then
+        docker_exec "ldd \"${PROJ_DIR}/build/menoh/libmenoh.so\""
+    fi
 }
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index afe593a..4a40497 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -1,6 +1,8 @@
 # check if variables are set
 test -n "${MAKE_JOBS}" || { echo "MAKE_JOBS can't be empty" 1>&2; exit 1; }
 
+test -n "${BUILD_STATIC_LIBS}" || BUILD_STATIC_LIBS=false
+
 # TODO: make them configurable for outside Travis
 export WORK_DIR=${HOME}
 export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
@@ -14,7 +16,13 @@ function prepare_menoh_data() {
 }
 
 function build_menoh() {
-    if [ "${LINK_STATIC}" != "true" ]; then
+    if [ "${BUILD_STATIC_LIBS}" = "true" ]; then
+        bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
+            --build-type Release \
+            --source-dir "${PROJ_DIR}" \
+            --python-executable python \
+            --build-shared-libs OFF
+    elif [ "${LINK_STATIC}" != "true" ]; then
         bash -ex "${PROJ_DIR}/scripts/build-menoh.sh" \
             --build-type Release \
             --source-dir "${PROJ_DIR}" \
@@ -35,5 +43,7 @@ function test_menoh() {
 }
 
 function check_menoh_artifact() {
-    otool -L "${PROJ_DIR}/build/menoh/libmenoh.dylib"
+    if [ "${BUILD_STATIC_LIBS}" != "true" ]; then
+      otool -L "${PROJ_DIR}/build/menoh/libmenoh.dylib"
+    fi
 }
diff --git a/scripts/build-menoh.sh b/scripts/build-menoh.sh
index 5184c4e..3af9cd6 100755
--- a/scripts/build-menoh.sh
+++ b/scripts/build-menoh.sh
@@ -45,6 +45,10 @@ while [[ $# != 0 ]]; do
             readonly ARG_LINK_STATIC_LIBPROTOBUF="$2"
             shift 2
             ;;
+        --build-shared-libs)
+            readonly ARG_BUILD_SHARED_LIBS="$2"
+            shift 2
+	    ;;
         -*)
             echo Unknown option \"$1\" 1>&2
             exit
@@ -71,6 +75,7 @@ test -n "${ARG_PYTHON_EXECUTABLE}" || readonly ARG_PYTHON_EXECUTABLE=python
 test -n "${ARG_LINK_STATIC_LIBGCC}" || readonly ARG_LINK_STATIC_LIBGCC='OFF'
 test -n "${ARG_LINK_STATIC_LIBSTDCXX}" || readonly ARG_LINK_STATIC_LIBSTDCXX='OFF'
 test -n "${ARG_LINK_STATIC_LIBPROTOBUF}" || readonly ARG_LINK_STATIC_LIBPROTOBUF='OFF'
+test -n "${ARG_BUILD_SHARED_LIBS}" || readonly ARG_BUILD_SHARED_LIBS='ON'
 
 echo -e "\e[33;1mBuilding Menoh\e[0m"
 
@@ -86,6 +91,7 @@ cmake \
     -DLINK_STATIC_LIBGCC=${ARG_LINK_STATIC_LIBGCC} \
     -DLINK_STATIC_LIBSTDCXX=${ARG_LINK_STATIC_LIBSTDCXX} \
     -DLINK_STATIC_LIBPROTOBUF=${ARG_LINK_STATIC_LIBPROTOBUF} \
+    -DBUILD_SHARED_LIBS=${ARG_BUILD_SHARED_LIBS} \
     -DENABLE_TEST=ON \
     "${ARG_SOURCE_DIR}"
 

From e8774681afb51380f4d87bba679fce9ed080309b Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 30 Jan 2019 18:18:15 +0900
Subject: [PATCH 290/321] appveyor: configure static library builds

---
 appveyor.yml | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/appveyor.yml b/appveyor.yml
index 49cd17e..6e7ffe0 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -16,6 +16,8 @@ environment:
     - TARGET: mingw
     - TARGET: mingw
       STATIC: 1
+    - TARGET: mingw
+      BUILD_SHARED_LIBS: 0
     - TARGET: msvc
 
 install:
@@ -73,7 +75,14 @@ build_script:
     )
   )
 - if [%TARGET%]==[mingw] (
-    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 -DPYTHON_EXECUTABLE=/mingw64/bin/python3 .. &&
+    if [%BUILD_SHARED_LIBS%]==[0] (
+      set BUILD_SHARED_LIBS_OPTION="-DBUILD_SHARED_LIBS=OFF"
+    ) else (
+      set BUILD_SHARED_LIBS_OPTION=""
+    )
+  )
+- if [%TARGET%]==[mingw] (
+    cmake -G "MSYS Makefiles" -DENABLE_TEST=ON %STATIC_OPTION% %BUILD_SHARED_LIBS_OPTION% -DCMAKE_INSTALL_PREFIX=/mingw64 -DPYTHON_EXECUTABLE=/mingw64/bin/python3 .. &&
     make
   ) else (
     cmake -G "Visual Studio 14 Win64" -DENABLE_TEST=OFF -DENABLE_BENCHMARK=OFF -DENABLE_EXAMPLE=OFF -DCMAKE_INSTALL_PREFIX=c:\menoh-%MENOH_REV%-msvc .. &&
@@ -84,8 +93,12 @@ test_script:
 # to find libmenoh.dll, libgtest.dll and libgtest_main.dll
 - if [%TARGET%]==[mingw] set PATH=C:\projects\menoh\build\menoh;C:\projects\menoh\build\test\lib\googletest\googlemock\gtest;C:\msys64\mkl-dnn-86b7129-mingw\bin;%PATH%
 - if [%TARGET%]==[mingw] (
-    echo "ldd libmenoh.dll" &&
-    ldd /c/projects/menoh/build/menoh/libmenoh.dll &&
+    if not [%BUILD_SHARED_LIBS%]==[0] (
+      echo "ldd libmenoh.dll" &&
+      ldd /c/projects/menoh/build/menoh/libmenoh.dll
+    )
+  )
+- if [%TARGET%]==[mingw] (
     echo "ldd libmkldnn.dll" &&
     ldd /mingw64/bin/libmkldnn.dll &&
     echo "ldd menoh_test.exe" &&

From 3ea570eafdce03baedd6a32a1050a6bf492cf3d7 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 30 Jan 2019 19:43:47 +0900
Subject: [PATCH 291/321] add version check for gcc

---
 CMakeLists.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b3d767..8b1bff1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,6 +35,9 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") # check Clang and AppleClang
     set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
 elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
     # using GCC
+    if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9)
+        message(FATAL_ERROR "GCC is too old. Please use GCC version >= 4.9")
+    endif()
     set(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0 -pg -Wall -Wextra")
     set(CMAKE_CXX_FLAGS_RELEASE "-O2 -s -DNDEBUG")
 endif()

From 400350c289b8bf93ee35ecca39c2a788f8dbeeba Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 5 Feb 2019 11:36:40 +0900
Subject: [PATCH 292/321] make set() about ONNX_NAMESPACE CACHE INTERNAL

---
 CMakeLists.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1f2a533..2acd3ff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -101,7 +101,7 @@ configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/
 
 set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
 set(BUILD_SHARED_LIBS OFF)
-set(ONNX_NAMESPACE "menoh_onnx")
+set(ONNX_NAMESPACE "menoh_onnx" CACHE INTERNAL "onnx namespace")
 add_subdirectory(${EXTERNAL_DIR}/onnx EXCLUDE_FROM_ALL) # Note: BUILD_SHARED_LIBS must be OFF in this place
 if(NOT ${BUILD_SHARED_LIBS_SAVED}) # install libmenoh_onnx and lib_menoh_onnx_proto
     set_target_properties(onnx_proto PROPERTIES OUTPUT_NAME "menoh_onnx_proto")

From 440a6fc81d797743724a014b5cc6cd6170cce5f8 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 1 Feb 2019 17:48:00 +0900
Subject: [PATCH 293/321] update onnx v1.4.1

---
 external/onnx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/external/onnx b/external/onnx
index bae6333..9e55ace 160000
--- a/external/onnx
+++ b/external/onnx
@@ -1 +1 @@
-Subproject commit bae6333e149a59a3faa9c4d9c44974373dcf5256
+Subproject commit 9e55ace55aad1ada27516038dfbdc66a8a0763db

From 98ca16c23b0e17465fc2a5601d718984103b10dc Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 4 Feb 2019 22:43:49 +0900
Subject: [PATCH 294/321] modify type of DataType (see
 https://github.com/onnx/onnx/pull/1626)

---
 menoh/onnx.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 323e6ec..385b9f7 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -21,7 +21,7 @@
 
 namespace menoh_impl {
 
-    dtype_t tensor_proto_data_type_to_dtype(menoh_onnx::TensorProto_DataType tpdt) {
+    dtype_t tensor_proto_data_type_to_dtype(google::protobuf::int32 tpdt) {
         if(tpdt == menoh_onnx::TensorProto_DataType_FLOAT) {
             return dtype_t::float_;
         } else if(tpdt == menoh_onnx::TensorProto_DataType_INT8) {

From fdad56a5cf605f3f854896f96105606b6a9e1df0 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 5 Feb 2019 11:16:28 +0900
Subject: [PATCH 295/321] MENOH_SUPPORTED_ONNX_OPSET_VERSION 8 -> 9

---
 include/menoh/menoh.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/menoh/menoh.h b/include/menoh/menoh.h
index c461bd4..f62b2fa 100644
--- a/include/menoh/menoh.h
+++ b/include/menoh/menoh.h
@@ -11,7 +11,7 @@
 #define MENOH_API
 #endif
 
-#define MENOH_SUPPORTED_ONNX_OPSET_VERSION 8
+#define MENOH_SUPPORTED_ONNX_OPSET_VERSION 9
 
 #ifndef MENOH_ERROR_MESSAGE_MAX_LENGTH
 #define MENOH_ERROR_MESSAGE_MAX_LENGTH 1024

From 59f8d760ec0eddffac893d8161c33396972f62ab Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 5 Feb 2019 14:29:05 +0900
Subject: [PATCH 296/321] replace including onnx.pb.h onnx_pb.h

latter defines ONNX_API
---
 menoh/CMakeLists.txt | 1 +
 menoh/onnx.cpp       | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/menoh/CMakeLists.txt b/menoh/CMakeLists.txt
index 8694273..7794e4c 100644
--- a/menoh/CMakeLists.txt
+++ b/menoh/CMakeLists.txt
@@ -45,6 +45,7 @@ target_include_directories(menoh_objlib PUBLIC
     $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
     $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>
     $<BUILD_INTERFACE:${ONNX_INCLUDE_DIRS}>
+    $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/external/onnx>
     $<BUILD_INTERFACE:${MKLDNN_INCLUDE_DIR}>
 )
 
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 385b9f7..993a438 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -11,7 +11,7 @@
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 
-#include <onnx/onnx.pb.h>
+#include <onnx/onnx_pb.h>
 
 #include <menoh/array.hpp>
 #include <menoh/exception.hpp>

From a1b2b5c3a3b0828f607de220375512742ac42dc4 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Tue, 5 Feb 2019 15:27:04 +0900
Subject: [PATCH 297/321] remove code for patching old onnx

---
 CMakeLists.txt                            |   4 -
 external/onnx-v1.3.0-patch_CMakeLists.txt | 565 ----------------------
 2 files changed, 569 deletions(-)
 delete mode 100644 external/onnx-v1.3.0-patch_CMakeLists.txt

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8598517..96a4425 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -98,10 +98,6 @@ message(STATUS "Adding external/onnx")
 set(ONNX_SRC_DIR ${EXTERNAL_DIR}/onnx)
 execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init -- ${ONNX_SRC_DIR} WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
 
-# see https://github.com/onnx/onnx/pull/1466
-message(STATUS "Patching to external/onnx")
-configure_file(${EXTERNAL_DIR}/onnx-v1.3.0-patch_CMakeLists.txt ${EXTERNAL_DIR}/onnx/CMakeLists.txt COPYONLY)
-
 # TODO: enable the following option when it is ready for migrating to onnx-ml
 #set(ONNX_ML 1)
 
diff --git a/external/onnx-v1.3.0-patch_CMakeLists.txt b/external/onnx-v1.3.0-patch_CMakeLists.txt
deleted file mode 100644
index 23ec68b..0000000
--- a/external/onnx-v1.3.0-patch_CMakeLists.txt
+++ /dev/null
@@ -1,565 +0,0 @@
-# Minimum CMake required
-cmake_minimum_required(VERSION 3.1)
-include(cmake/Utils.cmake)
-# Set default build type
-if(NOT CMAKE_BUILD_TYPE)
-  message(STATUS "Build type not set - defaulting to Release")
-  set(
-    CMAKE_BUILD_TYPE "Release"
-    CACHE
-      STRING
-      "Choose the type of build from: Debug Release RelWithDebInfo MinSizeRel Coverage."
-    FORCE)
-endif()
-cmake_policy(SET CMP0063 NEW)
-
-# Project
-project(onnx C CXX)
-option(ONNX_BUILD_BENCHMARKS "Build ONNX micro-benchmarks" OFF)
-
-option(BUILD_ONNX_PYTHON "Build Python binaries" OFF)
-option(ONNX_GEN_PB_TYPE_STUBS "Generate protobuf python type stubs" ON)
-option(ONNX_WERROR "Build with Werror" OFF)
-option(ONNX_COVERAGE "Build with coverage instrumentation" OFF)
-option(ONNX_BUILD_TESTS "Build ONNX C++ APIs Tests" OFF)
-option(ONNX_USE_LITE_PROTO "Use lite protobuf instead of full." OFF)
-
-set(ONNX_NAMESPACE "onnx" CACHE STRING "onnx namespace")
-
-# Set C++11 as standard for the whole project
-if(NOT MSVC)
-  set(CMAKE_CXX_STANDARD 11)
-endif(NOT MSVC)
-
-set(ONNX_ROOT ${PROJECT_SOURCE_DIR})
-
-# Read ONNX version
-file(READ "${PROJECT_SOURCE_DIR}/VERSION_NUMBER" ONNX_VERSION)
-string(STRIP "${ONNX_VERSION}" ONNX_VERSION)
-
-if(NOT MSVC)
-  set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
-  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
-  if(ONNX_COVERAGE)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
-  endif()
-endif()
-
-if(ONNX_BUILD_TESTS)
-  list(APPEND CMAKE_MODULE_PATH ${ONNX_ROOT}/cmake/external)
-  include(googletest)
-endif()
-
-if((ONNX_USE_LITE_PROTO AND TARGET protobuf::libprotobuf-lite) OR ((NOT ONNX_USE_LITE_PROTO) AND TARGET protobuf::libprotobuf))
-  # Sometimes we need to use protoc compiled for host architecture while linking
-  # libprotobuf against target architecture. See https://github.com/caffe2/caffe
-  # 2/blob/96f35ad75480b25c1a23d6e9e97bccae9f7a7f9c/cmake/ProtoBuf.cmake#L92-L99
-  if(EXISTS "${ONNX_CUSTOM_PROTOC_EXECUTABLE}")
-    message(STATUS "Using custom protoc executable")
-    set(ONNX_PROTOC_EXECUTABLE ${ONNX_CUSTOM_PROTOC_EXECUTABLE})
-  else()
-    set(ONNX_PROTOC_EXECUTABLE $<TARGET_FILE:protobuf::protoc>)
-  endif()
-else()
-  # Customized version of find Protobuf. We need to avoid situations mentioned
-  # in https://github.com/caffe2/caffe2/blob/b7d983f255ef5496474f1ea188edb5e0ac4
-  # 42761/cmake/ProtoBuf.cmake#L82-L92 The following section is stolen from
-  # cmake/ProtoBuf.cmake in Caffe2
-  find_program(Protobuf_PROTOC_EXECUTABLE
-               NAMES protoc
-               DOC "The Google Protocol Buffers Compiler")
-
-  # Only if protoc was found, seed the include directories and libraries. We
-  # assume that protoc is installed at PREFIX/bin. We use get_filename_component
-  # to resolve PREFIX.
-  if(Protobuf_PROTOC_EXECUTABLE)
-    set(ONNX_PROTOC_EXECUTABLE ${Protobuf_PROTOC_EXECUTABLE})
-    get_filename_component(_PROTOBUF_INSTALL_PREFIX
-                           ${Protobuf_PROTOC_EXECUTABLE} DIRECTORY)
-    get_filename_component(_PROTOBUF_INSTALL_PREFIX
-                           ${_PROTOBUF_INSTALL_PREFIX}/.. REALPATH)
-    find_library(Protobuf_PROTOC_LIBRARY
-                 NAMES protoc
-                 PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
-                 NO_DEFAULT_PATH)
-    if(ONNX_USE_LITE_PROTO)
-      find_library(Protobuf_LITE_LIBRARY
-        NAMES protobuf-lite
-        PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
-        NO_DEFAULT_PATH)
-    else(ONNX_USE_LITE_PROTO)
-      find_library(Protobuf_LIBRARY
-        NAMES protobuf
-        PATHS ${_PROTOBUF_INSTALL_PREFIX}/lib
-        NO_DEFAULT_PATH)
-    endif(ONNX_USE_LITE_PROTO)
-    find_path(Protobuf_INCLUDE_DIR google/protobuf/service.h
-              PATHS ${_PROTOBUF_INSTALL_PREFIX}/include
-              NO_DEFAULT_PATH)
-    find_package(Protobuf REQUIRED)
-  endif()
-endif()
-
-# Build the libraries with -fPIC
-set(CMAKE_POSITION_INDEPENDENT_CODE ON)
-
-# function(RELATIVE_PROTOBUF_GENERATE_CPP SRCS HDRS ROOT_DIR) from https://githu
-# b.com/tensorflow/tensorflow/blob/d2c3b873c6f8ff999a2e4ee707a84ff00d9c15a5/tens
-# orflow/contrib/cmake/tf_core_framework.cmake to solve the problem that
-# customized dir can't be specified when calling PROTOBUF_GENERATE_CPP.
-function(RELATIVE_PROTOBUF_GENERATE_CPP NAME SRCS HDRS ROOT_DIR DEPEND)
-  if(NOT ARGN)
-    message(
-      SEND_ERROR
-        "Error: RELATIVE_PROTOBUF_GENERATE_CPP() called without any proto files"
-      )
-    return()
-  endif()
-
-  if(MSVC AND BUILD_SHARED_LIBS)
-    set(ONNX_DLLEXPORT_STR "dllexport_decl=ONNX_API:")
-  else()
-    set(ONNX_DLLEXPORT_STR "")
-  endif()
-
-  set(${SRCS})
-  set(${HDRS})
-
-  set(GEN_PROTO_PY ${ROOT_DIR}/onnx/gen_proto.py)
-  foreach(INFILE ${ARGN})
-    set(ABS_FILE ${ROOT_DIR}/${INFILE})
-    get_filename_component(FILE_DIR ${ABS_FILE} DIRECTORY)
-    get_filename_component(FILE_WE ${INFILE} NAME_WE)
-    if(ONNX_ML)
-      if(ONNX_NAMESPACE STREQUAL "onnx")
-        set(GENERATED_FILE_WE "${FILE_WE}-ml")
-      else()
-        set(GENERATED_FILE_WE "${FILE_WE}_${ONNX_NAMESPACE}-ml")
-      endif()
-    else()
-      if(ONNX_NAMESPACE STREQUAL "onnx")
-        set(GENERATED_FILE_WE "${FILE_WE}")
-      else()
-        set(GENERATED_FILE_WE "${FILE_WE}_${ONNX_NAMESPACE}")
-      endif()
-    endif()
-    file(RELATIVE_PATH REL_DIR ${ROOT_DIR} ${FILE_DIR})
-    set(OUTPUT_PROTO_DIR "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}")
-
-    set(OUTPUT_PB_HEADER "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.h")
-    set(OUTPUT_PB_SRC "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.cc")
-    set(GENERATED_PROTO "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.proto")
-    if(NOT (ONNX_NAMESPACE STREQUAL "onnx"))
-      # We need this dummy header generated by gen_proto.py when ONNX_NAMESPACE
-      # is not onnx
-      list(APPEND ${HDRS} "${OUTPUT_PROTO_DIR}/${GENERATED_FILE_WE}.pb.h")
-    endif()
-    list(APPEND ${SRCS} "${OUTPUT_PB_SRC}")
-    list(APPEND ${HDRS} "${OUTPUT_PB_HEADER}")
-
-    if(NOT EXISTS "${OUTPUT_PROTO_DIR}")
-      file(MAKE_DIRECTORY "${OUTPUT_PROTO_DIR}")
-    endif()
-
-    if("${PYTHON_EXECUTABLE}" STREQUAL "")
-      set(_python_exe "python")
-    else()
-      set(_python_exe "${PYTHON_EXECUTABLE}")
-    endif()
-    set(GEN_PROTO_ARGS
-        -p
-        "${ONNX_NAMESPACE}"
-        -o
-        "${OUTPUT_PROTO_DIR}"
-        "${FILE_WE}")
-    if(ONNX_ML)
-      list(APPEND GEN_PROTO_ARGS -m)
-    endif()
-    if(ONNX_USE_LITE_PROTO)
-      list(APPEND GEN_PROTO_ARGS -l)
-    endif()
-    add_custom_command(OUTPUT "${GENERATED_PROTO}"
-                       COMMAND "${_python_exe}" "${GEN_PROTO_PY}"
-                               ARGS ${GEN_PROTO_ARGS}
-                       DEPENDS ${INFILE}
-                       COMMENT "Running gen_proto.py on ${INFILE}"
-                       VERBATIM)
-
-    set(PROTOC_ARGS
-        ${GENERATED_PROTO}
-        -I
-        ${CMAKE_CURRENT_BINARY_DIR}
-        --cpp_out
-        ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
-    if(BUILD_ONNX_PYTHON)
-      list(APPEND PROTOC_ARGS --python_out
-                  ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
-      if(ONNX_GEN_PB_TYPE_STUBS)
-        # Haven't figured out how to generate mypy stubs on Windows yet
-        if(NOT WIN32)
-          # If onnx was packaged to pypi from Windows, protoc-gen-mypy.py is
-          # missing the +x flag. Add it.
-          execute_process(COMMAND chmod +x ${ROOT_DIR}/tools/protoc-gen-mypy.py)
-          set(PROTOC_MYPY_PLUGIN_FILE ${ROOT_DIR}/tools/protoc-gen-mypy.py)
-        else(NOT WIN32)
-          set(PROTOC_MYPY_PLUGIN_FILE ${ROOT_DIR}/tools/protoc-gen-mypy.bat)
-        endif()
-        list(APPEND PROTOC_ARGS
-                    --plugin
-                    protoc-gen-mypy=${PROTOC_MYPY_PLUGIN_FILE}
-                    --mypy_out
-                    ${ONNX_DLLEXPORT_STR}${CMAKE_CURRENT_BINARY_DIR})
-      endif()
-    endif()
-    if(NOT ONNX_PROTOC_EXECUTABLE)
-      message(FATAL_ERROR "Protobuf compiler not found")
-    endif()
-    if(ONNX_PROTO_POST_BUILD_SCRIPT)
-      add_custom_command(
-        OUTPUT "${OUTPUT_PB_SRC}" "${OUTPUT_PB_HEADER}"
-        COMMAND ${ONNX_PROTOC_EXECUTABLE} ARGS ${PROTOC_ARGS}
-        COMMAND "${CMAKE_COMMAND}" -DFILENAME=${OUTPUT_PB_HEADER}
-                -DNAMESPACES=${ONNX_NAMESPACE} -P
-                ${ONNX_PROTO_POST_BUILD_SCRIPT}
-        COMMAND "${CMAKE_COMMAND}" -DFILENAME=${OUTPUT_PB_SRC}
-                -DNAMESPACES=${ONNX_NAMESPACE} -P
-                ${ONNX_PROTO_POST_BUILD_SCRIPT}
-        DEPENDS ${GENERATED_PROTO} ${DEPEND}
-        COMMENT "Running C++ protocol buffer compiler on ${GENERATED_PROTO}"
-        VERBATIM)
-    else()
-      add_custom_command(
-        OUTPUT "${OUTPUT_PB_SRC}" "${OUTPUT_PB_HEADER}"
-        COMMAND ${ONNX_PROTOC_EXECUTABLE} ARGS ${PROTOC_ARGS}
-        DEPENDS ${GENERATED_PROTO} ${DEPEND}
-        COMMENT "Running C++ protocol buffer compiler on ${GENERATED_PROTO}"
-        VERBATIM)
-    endif()
-    add_custom_target(${NAME} DEPENDS ${OUTPUT_PB_SRC} ${OUTPUT_PB_HEADER})
-  endforeach()
-
-  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
-  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
-  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
-endfunction()
-
-relative_protobuf_generate_cpp(gen_onnx_proto
-                               PROTO_SRCS
-                               PROTO_HDRS
-                               ${ONNX_ROOT}
-                               ""
-                               onnx/onnx.in.proto)
-relative_protobuf_generate_cpp(gen_onnx_operators_proto
-                               PROTO_SRCS2
-                               PROTO_HDRS2
-                               ${ONNX_ROOT}
-                               gen_onnx_proto
-                               onnx/onnx-operators.in.proto)
-list(APPEND PROTO_SRCS ${PROTO_SRCS2})
-list(APPEND PROTO_HDRS ${PROTO_HDRS2})
-
-file(GLOB_RECURSE onnx_src "${ONNX_ROOT}/onnx/*.h" "${ONNX_ROOT}/onnx/*.cc")
-file(GLOB_RECURSE onnx_gtests_src "${ONNX_ROOT}/onnx/test/cpp/*.h"
-                  "${ONNX_ROOT}/onnx/test/cpp/*.cc")
-list(REMOVE_ITEM onnx_src "${ONNX_ROOT}/onnx/cpp2py_export.cc")
-list(REMOVE_ITEM onnx_src ${onnx_gtests_src})
-
-add_library(onnx_proto ${PROTO_SRCS} ${PROTO_HDRS})
-target_include_directories(onnx_proto PUBLIC
-  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-  $<INSTALL_INTERFACE:include>
-  $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
-
-
-if(ONNX_USE_LITE_PROTO)
-  if(TARGET protobuf::libprotobuf-lite)
-    target_link_libraries(onnx_proto PUBLIC protobuf::libprotobuf-lite)
-  else()
-    target_link_libraries(onnx_proto PUBLIC ${PROTOBUF_LITE_LIBRARIES})
-  endif()
-else()
-  if(TARGET protobuf::libprotobuf)
-    target_link_libraries(onnx_proto PUBLIC protobuf::libprotobuf)
-  else()
-    target_link_libraries(onnx_proto PUBLIC ${PROTOBUF_LIBRARIES})
-  endif()
-endif()
-add_onnx_global_defines(onnx_proto)
-
-add_library(onnx ${onnx_src})
-target_include_directories(onnx PUBLIC
-  $<BUILD_INTERFACE:${ONNX_ROOT}>
-  $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-  $<INSTALL_INTERFACE:include>)
-target_link_libraries(onnx PUBLIC onnx_proto)
-add_onnx_global_defines(onnx)
-
-if(BUILD_ONNX_PYTHON)
-  if("${PY_EXT_SUFFIX}" STREQUAL "")
-    if(MSVC)
-      set(PY_EXT_SUFFIX ".pyd")
-    else()
-      set(PY_EXT_SUFFIX ".so")
-    endif()
-  endif()
-
-  add_library(onnx_cpp2py_export MODULE "${ONNX_ROOT}/onnx/cpp2py_export.cc")
-  set_target_properties(onnx_cpp2py_export PROPERTIES PREFIX "")
-  set_target_properties(onnx_cpp2py_export
-                        PROPERTIES COMPILE_FLAGS "-fvisibility=hidden")
-  set_target_properties(onnx_cpp2py_export PROPERTIES SUFFIX ${PY_EXT_SUFFIX})
-  set_target_properties(onnx_cpp2py_export
-                        PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
-  target_include_directories(onnx_cpp2py_export PRIVATE
-                             $<BUILD_INTERFACE:${ONNX_ROOT}>
-                             $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-                             $<INSTALL_INTERFACE:include>
-                             ${PYTHON_INCLUDE_DIR})
-
-  # pybind11 is a header only lib
-  find_package(pybind11 2.2)
-  if(pybind11_FOUND)
-    target_include_directories(onnx_cpp2py_export PUBLIC
-      ${pybind11_INCLUDE_DIRS})
-  else()
-    if(EXISTS ${ONNX_ROOT}/third_party/pybind11/include/pybind11/pybind11.h)
-      target_include_directories(onnx_cpp2py_export PUBLIC
-        ${ONNX_ROOT}/third_party/pybind11/include)
-    else()
-      message(FATAL_ERROR "cannot find pybind")
-    endif()
-  endif()
-
-  if(APPLE)
-    set_target_properties(onnx_cpp2py_export
-                          PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
-    target_link_libraries(onnx_cpp2py_export
-                          PRIVATE -Wl,-force_load,$<TARGET_FILE:onnx>)
-  elseif(MSVC)
-    # In MSVC, we will add whole archive in default
-    target_link_libraries(onnx_cpp2py_export
-                          PRIVATE -WHOLEARCHIVE:$<TARGET_FILE:onnx>)
-  else()
-    # Assume everything else is like gcc
-    target_link_libraries(onnx_cpp2py_export
-                          PRIVATE "-Wl,--whole-archive" $<TARGET_FILE:onnx>
-                                  "-Wl,--no-whole-archive")
-  endif()
-
-  target_link_libraries(onnx_cpp2py_export PRIVATE onnx)
-
-  if(MSVC)
-    if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-      set(MP_FLAG "-Xclang" "-fopenmp")
-      set(EXTRA_FLAGS
-          "-Wno-implicit-function-declaration"
-          "-Wno-undefined-inline"
-          "-Wno-incompatible-pointer-types"
-          "-Wno-dllexport-explicit-instantiation-decl"
-          "-Wno-microsoft-unqualified-friend"
-          "-Wno-absolute-value"
-          "-Wno-unused-variable"
-          "-Wno-writable-strings"
-          "-Qunused-arguments")
-    else()
-      set(MP_FLAG "/MP")
-      set(EXTRA_FLAGS "")
-    endif()
-    find_package(PythonInterp ${PY_VERSION} REQUIRED)
-    find_package(PythonLibs ${PY_VERSION} REQUIRED)
-    target_link_libraries(onnx_cpp2py_export PRIVATE ${PYTHON_LIBRARIES})
-    target_compile_options(onnx_cpp2py_export
-                           PRIVATE ${MP_FLAG}
-                                   /WX
-                                   /wd4800 # disable warning type' : forcing
-                                           # value to bool 'true' or 'false'
-                                           # (performance warning)
-                                   /wd4503 # identifier' : decorated name length
-                                           # exceeded, name was truncated
-                                   /wd4146 # unary minus operator applied to
-                                           # unsigned type, result still
-                                           # unsigned from include\google\protob
-                                           # uf\wire_format_lite.h
-                                   ${EXTRA_FLAGS})
-    target_compile_options(onnx_cpp2py_export PRIVATE /MT)
-    add_onnx_global_defines(onnx_cpp2py_export)
-  endif()
-endif()
-
-if(ONNX_BUILD_BENCHMARKS)
-  if(NOT TARGET benchmark)
-    # We will not need to test benchmark lib itself.
-    set(BENCHMARK_ENABLE_TESTING OFF
-        CACHE BOOL "Disable benchmark testing as we don't need it.")
-    # We will not need to install benchmark since we link it statically.
-    set(BENCHMARK_ENABLE_INSTALL OFF
-        CACHE BOOL
-              "Disable benchmark install to avoid overwriting vendor install.")
-    add_subdirectory(${PROJECT_SOURCE_DIR}/third_party/benchmark)
-  endif()
-
-  add_executable(protobuf-bench tools/protobuf-bench.cc)
-  target_include_directories(protobuf-bench PUBLIC
-    $<BUILD_INTERFACE:${ONNX_ROOT}>
-    $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
-    $<INSTALL_INTERFACE:include>
-    $<BUILD_INTERFACE:${PROTOBUF_INCLUDE_DIRS}>)
-  target_link_libraries(protobuf-bench onnx_proto benchmark)
-endif()
-
-# Export include directories
-set(ONNX_INCLUDE_DIRS "${ONNX_ROOT}" "${CMAKE_CURRENT_BINARY_DIR}")
-get_directory_property(hasParent PARENT_DIRECTORY)
-if(hasParent)
-  set(ONNX_INCLUDE_DIRS ${ONNX_INCLUDE_DIRS} PARENT_SCOPE)
-endif()
-
-if(MSVC)
-  target_compile_options(onnx_proto
-                         PRIVATE ${MP_FLAG}
-                                 /WX
-                                 /wd4800 # disable warning type' : forcing value
-                                         # to bool 'true' or 'false'
-                                         # (performance warning)
-                                 /wd4503 # identifier' : decorated name length
-                                         # exceeded, name was truncated
-                                 /wd4146 # unary minus operator applied to
-                                         # unsigned type, result still unsigned:
-                                         # include\google\protobuf\wire_format_l
-                                         # ite.h
-                                 ${EXTRA_FLAGS})
-  target_compile_options(onnx
-                         PRIVATE ${MP_FLAG}
-                                 /WX
-                                 /wd4800 # disable warning type' : forcing value
-                                         # to bool 'true' or 'false'
-                                         # (performance warning)
-                                 /wd4503 # identifier' : decorated name length
-                                         # exceeded, name was truncated
-                                 /wd4146 # unary minus operator applied to
-                                         # unsigned type, result still unsigned
-                                 ${EXTRA_FLAGS})
-  add_msvc_runtime_flag(onnx_proto)
-  add_msvc_runtime_flag(onnx)
-  set(onnx_static_library_flags
-      -IGNORE:4221 # LNK4221: This object file does not define any previously
-                   # undefined public symbols, so it will not be used by any
-                   # link operation that consumes this library
-      )
-  set_target_properties(onnx
-                        PROPERTIES STATIC_LIBRARY_FLAGS
-                                   "${onnx_static_library_flags}")
-elseif(APPLE)
-
-else()
-  if(${ONNX_WERROR})
-    target_compile_options(onnx PRIVATE -Werror=sign-compare -Werror=conversion)
-  endif()
-endif()
-
-if(APPLE)
-  set_target_properties(onnx PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
-endif()
-
-# ---[ ONNX Interface for Framework Integratin (ONNXIFI)
-add_library(onnxifi INTERFACE)
-target_include_directories(onnxifi INTERFACE
-  $<BUILD_INTERFACE:${ONNX_ROOT}>
-  $<INSTALL_INTERFACE:include>)
-
-# ---[ ONNXIFI loader
-add_library(onnxifi_loader STATIC onnx/onnxifi_loader.c)
-target_include_directories(onnxifi_loader PUBLIC
-  $<BUILD_INTERFACE:${ONNX_ROOT}>
-  $<INSTALL_INTERFACE:include>)
-# Users of ONNX backend API would compile it with their toolchain, so it is
-# implemented in standard C89 for maximum compatibility
-set_target_properties(onnxifi_loader
-                      PROPERTIES C_STANDARD
-                                 90
-                                 C_EXTENSIONS
-                                 NO)
-target_link_libraries(onnxifi_loader PUBLIC onnxifi ${CMAKE_DL_LIBS})
-if(MSVC)
-  add_msvc_runtime_flag(onnxifi_loader)
-endif()
-
-if (NOT ANDROID AND NOT IOS)
-  # ---[ ONNXIFI wrapper
-  add_library(onnxifi_wrapper MODULE onnx/onnxifi_wrapper.c)
-  target_include_directories(onnxifi_wrapper PRIVATE
-    $<BUILD_INTERFACE:${ONNX_ROOT}>
-    $<INSTALL_INTERFACE:include>)
-  set_target_properties(onnxifi_wrapper PROPERTIES
-    C_STANDARD 99
-    C_EXTENSIONS NO
-    OUTPUT_NAME "onnxifi"
-    POSITION_INDEPENDENT_CODE YES)
-  target_link_libraries(onnxifi_wrapper PRIVATE onnxifi_loader onnxifi)
-  if(DEFINED ONNXIFI_SEARCH_DIR)
-    target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_SEARCH_DIR=\"${ONNXIFI_SEARCH_DIR}\"")
-  endif()
-  if(WIN32)
-    if(MSVC)
-      target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_PUBLIC=__declspec(dllexport)")
-    else()
-      target_compile_definitions(onnxifi_wrapper PRIVATE "ONNXIFI_PUBLIC=__attribute__((__dllexport__))")
-    endif()
-  endif()
-  if(APPLE)
-    # By default CMake would use .so suffix on Mac
-    set_target_properties(onnxifi_wrapper PROPERTIES SUFFIX ".dylib")
-  endif()
-endif()
-
-# ---[ ONNXIFI dummy backend
-add_library(onnxifi_dummy SHARED onnx/onnxifi_dummy.c)
-target_include_directories(onnxifi_dummy PRIVATE
-  $<BUILD_INTERFACE:${ONNX_ROOT}>
-  $<INSTALL_INTERFACE:include>)
-target_link_libraries(onnxifi_dummy PUBLIC onnxifi ${CMAKE_DL_LIBS})
-target_compile_definitions(onnxifi_dummy PRIVATE ONNXIFI_BUILD_LIBRARY=TRUE)
-if(MSVC)
-  add_msvc_runtime_flag(onnxifi_dummy)
-endif()
-
-install(DIRECTORY ${ONNX_ROOT}/onnx
-        DESTINATION include
-        FILES_MATCHING
-        PATTERN "*.h")
-install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/onnx
-        DESTINATION include
-        FILES_MATCHING
-        PATTERN "*.h")
-
-configure_file(
-  ${PROJECT_SOURCE_DIR}/cmake/ONNXConfigVersion.cmake.in
-  ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
-  @ONLY)
-configure_file(
-  ${PROJECT_SOURCE_DIR}/cmake/ONNXConfig.cmake.in
-  ${PROJECT_BINARY_DIR}/ONNXConfig.cmake
-  @ONLY)
-install(FILES
-  ${PROJECT_BINARY_DIR}/ONNXConfigVersion.cmake
-  ${PROJECT_BINARY_DIR}/ONNXConfig.cmake
-  DESTINATION share/cmake/ONNX
-  COMPONENT dev)
-install(EXPORT ONNXTargets DESTINATION share/cmake/ONNX)
-install(TARGETS
-  onnx onnx_proto
-  onnxifi onnxifi_dummy onnxifi_loader
-  EXPORT ONNXTargets DESTINATION lib)
-
-if(NOT ANDROID AND NOT IOS)
-  install(TARGETS onnxifi_wrapper
-    EXPORT ONNXTargets DESTINATION lib)
-endif()
-
-if(ONNX_BUILD_TESTS)
-  include(${ONNX_ROOT}/cmake/unittest.cmake)
-endif()
-
-include(cmake/summary.cmake)
-onnx_print_configuration_summary()

From b6cdacbc7d139d364f81b4d9a522889c34a65067 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Thu, 7 Feb 2019 11:07:00 +0900
Subject: [PATCH 298/321] fix compilation error due to ONNX_API macro being not
 defined

---
 test/operator.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/operator.cpp b/test/operator.cpp
index 81aa43c..1eb998a 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -7,7 +7,7 @@
 #include <filesystem/path.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <onnx/onnx.pb.h>
+#include <onnx/onnx_pb.h>
 
 #include <menoh/menoh.hpp>
 

From 40a5853f7858bdfd91e0b920a35518f106f25e3b Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Thu, 7 Feb 2019 15:14:41 +0900
Subject: [PATCH 299/321] fix "control may reach end of non-void function"
 warning

---
 test/operator.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/test/operator.cpp b/test/operator.cpp
index 1eb998a..b07bf65 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -76,6 +76,7 @@ namespace {
             return named_array_data{tensor.name(), menoh::dtype_t::int64,
                                     std::move(dims), std::move(data)};
         }
+        throw "unexpected tensor data type";
     }
 
     class OperatorTest : public ::testing::Test {

From 6b34b28c309517c26cb362a29a0ddd8c3920eeae Mon Sep 17 00:00:00 2001
From: Kenichi Maehashi <webmaster@kenichimaehashi.com>
Date: Fri, 8 Feb 2019 20:03:38 +0900
Subject: [PATCH 300/321] fix typo

---
 include/menoh/menoh.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/menoh/menoh.hpp b/include/menoh/menoh.hpp
index 0807b94..d2d6670 100644
--- a/include/menoh/menoh.hpp
+++ b/include/menoh/menoh.hpp
@@ -301,7 +301,7 @@ namespace menoh {
         //! Add output profile. That profile contains name and dtype
         /*! dims of output are calculated automatically.
          * \note This function is deprecated. Given dtype is totally ignored and
-         * inferenced by dtype of input. Use add_output_name() instead.
+         * inferred by dtype of input. Use add_output_name() instead.
          */
         [[deprecated("Use add_output_name() instead")]]
         void add_output_profile(std::string const& name, dtype_t) {

From 52d8b78e8a016ca5e642f477ecad51523c5fabcf Mon Sep 17 00:00:00 2001
From: Kenichi Maehashi <webmaster@kenichimaehashi.com>
Date: Tue, 12 Feb 2019 19:36:20 +0900
Subject: [PATCH 301/321] Fix Java wrapper missing from README

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 5fbfded..e7c6965 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ This codebase contains C API and C++ API.
 - Ruby wrapper : [menoh-ruby](https://github.com/pfnet-research/menoh-ruby)
 - Rust wrapper : [menoh-rs](https://github.com/pfnet-research/menoh-rs)
   - There is also [unofficial Rust wrapper by Y-Nak san](https://github.com/Y-Nak/menoh-rs)
+- Java wrapper : [menoh-java](https://github.com/pfnet-research/menoh-java)
 - [Unofficial] ROS interface by Akio Ochiai san : [menoh_ros](https://github.com/akio/menoh_ros)
 - [Unofficial] OCaml wrapper by wkwkes san : [Menohcaml](https://github.com/wkwkes/Menohcaml)
 

From 46a6786fecc9521befa3eb3209575341c6920794 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 1 Mar 2019 23:37:15 +0900
Subject: [PATCH 302/321] add constant node

---
 menoh/array.hpp                               |  4 +
 ...tribute_completion_and_shape_inference.hpp | 26 +++++
 .../backend/generic/generic_context.cpp       |  1 +
 .../backend/generic/operator.hpp              |  1 +
 .../backend/generic/operator/constant.hpp     | 34 +++++++
 menoh/node.cpp                                |  4 +
 menoh/node.hpp                                |  6 +-
 menoh/onnx.cpp                                | 96 +++++++++++--------
 ...bute_completion_and_shape_inference_hpp.py |  6 ++
 test/operator.cpp                             |  2 +
 10 files changed, 140 insertions(+), 40 deletions(-)
 create mode 100644 menoh/composite_backend/backend/generic/operator/constant.hpp

diff --git a/menoh/array.hpp b/menoh/array.hpp
index 8f7435c..d2a8b72 100644
--- a/menoh/array.hpp
+++ b/menoh/array.hpp
@@ -60,6 +60,10 @@ namespace menoh_impl {
         void* data_handle_ = nullptr;
     };
 
+    inline bool operator==(array const& lhs, array const& rhs) {
+        return lhs.data() == rhs.data();
+    }
+
     std::size_t total_size(array const& a);
 
     float* fbegin(array const& a);
diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index dbd2453..f8da5a0 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -280,6 +280,32 @@ add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 else
 
 
+if(node.op_type == "Constant") {
+    
+    
+{
+    auto found = node.attribute_table.find("value");
+    if(found == node.attribute_table.end()) {
+        
+assert(!"attribute not found: value");
+
+    }
+}
+
+    
+    {
+        
+auto value = get<array>(node.attribute_table.at("value"));
+static_cast<void>(value); // maybe unused
+
+        
+add_variable_to_table(output(0), value.dtype(), value.dims());
+
+    }
+}
+else
+
+
 if(node.op_type == "Conv") {
     
 auto kernel_ndims = ndims_of(input(1))-2;
diff --git a/menoh/composite_backend/backend/generic/generic_context.cpp b/menoh/composite_backend/backend/generic/generic_context.cpp
index 2f4fbb4..b05a66c 100644
--- a/menoh/composite_backend/backend/generic/generic_context.cpp
+++ b/menoh/composite_backend/backend/generic/generic_context.cpp
@@ -6,6 +6,7 @@ namespace menoh_impl {
         namespace generic_backend {
 
             generic_context::generic_context() : context() {
+                procedure_factory_table_.emplace("Constant", make_constant);
                 procedure_factory_table_.emplace("Relu", make_relu);
                 procedure_factory_table_.emplace("Reshape", make_reshape);
                 procedure_factory_table_.emplace("Mul", make_mul);
diff --git a/menoh/composite_backend/backend/generic/operator.hpp b/menoh/composite_backend/backend/generic/operator.hpp
index dfbd0aa..e7d2b9a 100644
--- a/menoh/composite_backend/backend/generic/operator.hpp
+++ b/menoh/composite_backend/backend/generic/operator.hpp
@@ -1,6 +1,7 @@
 #ifndef MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
 #define MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
 
+#include <menoh/composite_backend/backend/generic/operator/constant.hpp>
 #include <menoh/composite_backend/backend/generic/operator/mul.hpp>
 #include <menoh/composite_backend/backend/generic/operator/relu.hpp>
 #include <menoh/composite_backend/backend/generic/operator/reshape.hpp>
diff --git a/menoh/composite_backend/backend/generic/operator/constant.hpp b/menoh/composite_backend/backend/generic/operator/constant.hpp
new file mode 100644
index 0000000..b70c45f
--- /dev/null
+++ b/menoh/composite_backend/backend/generic/operator/constant.hpp
@@ -0,0 +1,34 @@
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_CONSTANT_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_CONSTANT_HPP
+
+#include <menoh/array.hpp>
+#include <menoh/composite_backend/procedure.hpp>
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace composite_backend {
+        namespace generic_backend {
+            inline procedure
+            make_constant(node const& node,
+                          std::vector<array> const& input_list,
+                          std::vector<array> const& output_list) {
+                assert(input_list.size() == 0);
+                assert(output_list.size() == 1);
+                array value = attribute_tensor(node, "value");
+                std::cout << total_size(value) << std::endl;
+                for(decltype(total_size(value)) i = 0; i < total_size(value);
+                    ++i) {
+                    std::cout << fat(value, i) << std::endl;
+                    fat(output_list[0], i) = fat(value, i);
+                }
+                auto procedure = []() {};
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace composite_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_CONSTANT_HPP
diff --git a/menoh/node.cpp b/menoh/node.cpp
index 354e0f1..f82899f 100644
--- a/menoh/node.cpp
+++ b/menoh/node.cpp
@@ -50,6 +50,10 @@ namespace menoh_impl {
         return menoh_impl::get<float>(find_value(n.attribute_table, attr_name));
     }
 
+    array const& attribute_tensor(node const& n, std::string const& attr_name) {
+        return menoh_impl::get<array>(find_value(n.attribute_table, attr_name));
+    }
+
     std::vector<int>
     optional_attribute_ints(node const& n, std::string const& attr_name,
                             std::vector<int> const& default_value) {
diff --git a/menoh/node.hpp b/menoh/node.hpp
index 4849d6d..4bf0129 100644
--- a/menoh/node.hpp
+++ b/menoh/node.hpp
@@ -5,12 +5,13 @@
 #include <unordered_map>
 #include <vector>
 
+#include <menoh/array.hpp>
 #include <menoh/variant.hpp>
 
 namespace menoh_impl {
 
-    using attribute =
-      menoh_impl::variant<int, float, std::vector<int>, std::vector<float>>;
+    using attribute = menoh_impl::variant<int, float, std::vector<int>,
+                                          std::vector<float>, array>;
 
     struct node {
         std::string op_type;
@@ -38,6 +39,7 @@ namespace menoh_impl {
                               std::vector<float> const& default_value);
     std::vector<float> const& attribute_floats(node const& n,
                                                std::string const& attr_name);
+    array const& attribute_tensor(node const& n, std::string const& attr_name);
 
     std::tuple<std::vector<int>, std::vector<int>, std::vector<int>>
     attributes_for_2d_data_processing(node const& n);
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 993a438..324c429 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -83,24 +83,69 @@ namespace menoh_impl {
     }
 
     template <menoh_impl::dtype_t dtype>
-    auto move_tensor_from_onnx_data(int total_size, menoh_onnx::TensorProto& tensor) {
+    auto move_tensor_from_onnx_data(int total_size,
+                                    menoh_onnx::TensorProto const& tensor) {
         // libc++ workaround
         // Below 2 lines are equal to `data =
         // std::unique_ptr<float_t[]>(new float_t[total_size]);`
         using dtype_type = dtype_to_type_t<dtype>;
         auto u = std::make_unique<dtype_type[]>(total_size);
         auto data = std::shared_ptr<void>(u.release(), u.get_deleter());
-        // TODO other format: float_data
-        assert(tensor.has_raw_data());
-        assert(tensor.raw_data().length() ==
-               static_cast<decltype(tensor.raw_data().length())>(
-                 total_size * size_in_bytes<dtype>));
-        std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
-                  static_cast<char*>(data.get()));
-        delete tensor.release_raw_data();
+        if(tensor.has_raw_data()) {
+            assert(tensor.raw_data().length() ==
+                   static_cast<decltype(tensor.raw_data().length())>(
+                     total_size * size_in_bytes<dtype>));
+            std::copy(tensor.raw_data().begin(), tensor.raw_data().end(),
+                      static_cast<char*>(data.get()));
+        } else if(dtype == dtype_t::float_) {
+            assert(tensor.float_data_size());
+            std::copy(tensor.float_data().begin(), tensor.float_data().end(),
+                      static_cast<float*>(data.get()));
+        } else if(dtype == dtype_t::int32) {
+            assert(tensor.int32_data_size());
+            std::copy(tensor.int32_data().begin(), tensor.int32_data().end(),
+                      static_cast<std::int32_t*>(data.get()));
+        } else if(dtype == dtype_t::int64) {
+            assert(tensor.int64_data_size());
+            std::copy(tensor.int64_data().begin(), tensor.int64_data().end(),
+                      static_cast<std::int64_t*>(data.get()));
+        } else {
+            throw invalid_dtype(std::to_string(tensor.data_type()));
+        }
         return data;
     }
 
+    auto tensor_to_array(menoh_onnx::TensorProto const& tensor) {
+        assert(tensor.has_data_type());
+
+        std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
+        auto total_size =
+          std::accumulate(dims.begin(), dims.end(), 1, std::multiplies<int>());
+
+        dtype_t d = tensor_proto_data_type_to_dtype(tensor.data_type());
+
+        std::shared_ptr<void> data;
+        if(d == menoh_impl::dtype_t::float_) {
+            data = move_tensor_from_onnx_data<menoh_impl::dtype_t::float_>(
+              total_size, tensor);
+        } else if(d == menoh_impl::dtype_t::int8) {
+            data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int8>(
+              total_size, tensor);
+        } else if(d == menoh_impl::dtype_t::int16) {
+            data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int16>(
+              total_size, tensor);
+        } else if(d == menoh_impl::dtype_t::int32) {
+            data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int32>(
+              total_size, tensor);
+        } else if(d == menoh_impl::dtype_t::int64) {
+            data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int64>(
+              total_size, tensor);
+        } else {
+            throw invalid_dtype(std::to_string(tensor.data_type()));
+        }
+        return menoh_impl::array(d, std::move(dims), std::move(data));
+    }
+
     auto extract_parameter_name_and_array_list_from_onnx_graph(
       menoh_onnx::GraphProto& graph,
       std::vector<std::string> const& needed_parameter_name_list) {
@@ -113,36 +158,8 @@ namespace menoh_impl {
                          tensor.name()) == needed_parameter_name_list.end()) {
                 continue;
             }
-            assert(tensor.has_data_type());
-
-            std::vector<int> dims(tensor.dims().begin(), tensor.dims().end());
-            auto total_size = std::accumulate(dims.begin(), dims.end(), 1,
-                                              std::multiplies<int>());
-
-            dtype_t d = tensor_proto_data_type_to_dtype(tensor.data_type());
-
-            std::shared_ptr<void> data;
-            if(d == menoh_impl::dtype_t::float_) {
-                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::float_>(
-                  total_size, tensor);
-            } else if(d == menoh_impl::dtype_t::int8) {
-                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int8>(
-                  total_size, tensor);
-            } else if(d == menoh_impl::dtype_t::int16) {
-                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int16>(
-                  total_size, tensor);
-            } else if(d == menoh_impl::dtype_t::int32) {
-                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int32>(
-                  total_size, tensor);
-            } else if(d == menoh_impl::dtype_t::int64) {
-                data = move_tensor_from_onnx_data<menoh_impl::dtype_t::int64>(
-                  total_size, tensor);
-            } else {
-                throw invalid_dtype(std::to_string(tensor.data_type()));
-            }
             parameter_name_and_array_list.push_back(
-              {tensor.name(),
-               menoh_impl::array(d, std::move(dims), std::move(data))});
+              {tensor.name(), tensor_to_array(tensor)});
         }
         return parameter_name_and_array_list;
     }
@@ -165,6 +182,9 @@ namespace menoh_impl {
                     attribute_table.insert(
                       {attr.name(), std::vector<float>(attr.floats().begin(),
                                                        attr.floats().end())});
+                } else if(attr.has_t()) {
+                    attribute_table.insert(
+                      {attr.name(), tensor_to_array(attr.t())});
                 } else {
                     throw invalid_attribute_type(
                       attr.name(),
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 86571e0..7a655fa 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -191,6 +191,12 @@ def main():
     output_dims.at(axis) += dims_of(input(i)).at(axis);
 }
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
+'''))
+    code_list.append(
+        make_completion_code("Constant", [
+            ("value", "array", None),
+        ], '''
+add_variable_to_table(output(0), value.dtype(), value.dims());
 '''))
     code_list.append(
         make_completion_code(
diff --git a/test/operator.cpp b/test/operator.cpp
index b07bf65..e4a1264 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -249,6 +249,8 @@ namespace {
     TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_and_asymmetric_padding, eps);
     TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_no_padding, eps);
     TEST_OP(mkldnn_with_generic_fallback, test_conv_with_strides_padding, eps);
+
+    TEST_OP(mkldnn_with_generic_fallback, test_constant, eps);
   
     // Eltwise
     TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_abs, eps);

From 88167529ccfd35c8c81244bb02ca28d3bbcceec5 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 1 Mar 2019 23:42:23 +0900
Subject: [PATCH 303/321] fix format and replace `insert` with `emplace`

---
 menoh/node.cpp |  8 ++++----
 menoh/onnx.cpp | 25 +++++++++++++------------
 2 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/menoh/node.cpp b/menoh/node.cpp
index f82899f..36dd1f3 100644
--- a/menoh/node.cpp
+++ b/menoh/node.cpp
@@ -100,10 +100,10 @@ namespace menoh_impl {
           output_channel_num, kernel_shape, strides, pads);
     }
 
-    std::vector<int>
-    calc_2d_output_dims_for_conv_transpose(menoh_impl::node const& node, int output_channel_num,
-                        std::unordered_map<std::string, std::vector<int>> const&
-                          variable_dims_table) {
+    std::vector<int> calc_2d_output_dims_for_conv_transpose(
+      menoh_impl::node const& node, int output_channel_num,
+      std::unordered_map<std::string, std::vector<int>> const&
+        variable_dims_table) {
         std::vector<int> strides, kernel_shape, pads;
         std::tie(strides, kernel_shape, pads) =
           attributes_for_2d_data_processing(node);
diff --git a/menoh/onnx.cpp b/menoh/onnx.cpp
index 324c429..b51772a 100644
--- a/menoh/onnx.cpp
+++ b/menoh/onnx.cpp
@@ -164,27 +164,28 @@ namespace menoh_impl {
         return parameter_name_and_array_list;
     }
 
-    auto extract_node_list_from_onnx_graph(menoh_onnx::GraphProto const& graph) {
+    auto
+    extract_node_list_from_onnx_graph(menoh_onnx::GraphProto const& graph) {
         std::vector<node> node_list;
         for(auto const& onnx_node : graph.node()) {
             std::unordered_map<std::string, attribute> attribute_table;
             for(auto const& attr : onnx_node.attribute()) {
                 if(attr.has_i()) {
-                    attribute_table.insert(
-                      {attr.name(), static_cast<int>(attr.i())}); // TODO int64
+                    attribute_table.emplace(
+                      attr.name(), static_cast<int>(attr.i())); // TODO int64
                 } else if(attr.has_f()) {
-                    attribute_table.insert({attr.name(), attr.f()});
+                    attribute_table.emplace(attr.name(), attr.f());
                 } else if(attr.ints_size()) {
-                    attribute_table.insert(
-                      {attr.name(), std::vector<int>(attr.ints().begin(),
-                                                     attr.ints().end())});
+                    attribute_table.emplace(
+                      attr.name(),
+                      std::vector<int>(attr.ints().begin(), attr.ints().end()));
                 } else if(attr.floats_size()) {
-                    attribute_table.insert(
-                      {attr.name(), std::vector<float>(attr.floats().begin(),
-                                                       attr.floats().end())});
+                    attribute_table.emplace(
+                      attr.name(), std::vector<float>(attr.floats().begin(),
+                                                      attr.floats().end()));
                 } else if(attr.has_t()) {
-                    attribute_table.insert(
-                      {attr.name(), tensor_to_array(attr.t())});
+                    attribute_table.emplace(attr.name(),
+                                            tensor_to_array(attr.t()));
                 } else {
                     throw invalid_attribute_type(
                       attr.name(),

From 46197293140a5fe7e3aeba740231c302f313db52 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 15:48:20 +0900
Subject: [PATCH 304/321] fix constant

---
 .../backend/generic/operator/constant.hpp     | 12 ++++-----
 menoh/dtype.hpp                               | 25 +++++++++++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator/constant.hpp b/menoh/composite_backend/backend/generic/operator/constant.hpp
index b70c45f..0b0f6e3 100644
--- a/menoh/composite_backend/backend/generic/operator/constant.hpp
+++ b/menoh/composite_backend/backend/generic/operator/constant.hpp
@@ -1,6 +1,8 @@
 #ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_CONSTANT_HPP
 #define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_CONSTANT_HPP
 
+#include <algorithm>
+
 #include <menoh/array.hpp>
 #include <menoh/composite_backend/procedure.hpp>
 
@@ -16,12 +18,10 @@ namespace menoh_impl {
                 assert(input_list.size() == 0);
                 assert(output_list.size() == 1);
                 array value = attribute_tensor(node, "value");
-                std::cout << total_size(value) << std::endl;
-                for(decltype(total_size(value)) i = 0; i < total_size(value);
-                    ++i) {
-                    std::cout << fat(value, i) << std::endl;
-                    fat(output_list[0], i) = fat(value, i);
-                }
+                std::copy(static_cast<char*>(value.data()),
+                          static_cast<char*>(value.data()) +
+                            total_size(value) * get_size_in_bytes(value.dtype()),
+                          static_cast<char*>(output_list[0].data()));
                 auto procedure = []() {};
 
                 return procedure;
diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index 78d555c..50b77d6 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -85,6 +85,31 @@ namespace menoh_impl {
     template <dtype_t d>
     constexpr int size_in_bytes = sizeof(dtype_to_type_t<d>);
 
+    constexpr int get_size_in_bytes(dtype_t d) {
+        if(d == dtype_t::float16) {
+            return size_in_bytes<dtype_t::float16>;
+        } else
+        if(d == dtype_t::float32) {
+            return size_in_bytes<dtype_t::float32>;
+        }else
+        if(d == dtype_t::float64) {
+            return size_in_bytes<dtype_t::float64>;
+        } else
+        if(d == dtype_t::int8) {
+            return size_in_bytes<dtype_t::int8>;
+        } else
+        if(d == dtype_t::int16) {
+            return size_in_bytes<dtype_t::int16>;
+        } else
+        if(d == dtype_t::int32) {
+            return size_in_bytes<dtype_t::int32>;
+        } else
+        if(d == dtype_t::int64) {
+            return size_in_bytes<dtype_t::int64>;
+        }
+        assert(!"not come here");
+    }
+
 } // namespace menoh_impl
 
 #endif // MENOH_DTYPE_HPP

From db660391fd1cf16bc4d7eb6959f9e091e1ebb109 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 15:48:37 +0900
Subject: [PATCH 305/321] fix format

---
 .../backend/mkldnn/mkldnn_context.cpp              | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp b/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
index 024f852..7bbab0e 100644
--- a/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
+++ b/menoh/composite_backend/backend/mkldnn/mkldnn_context.cpp
@@ -9,16 +9,15 @@ namespace menoh_impl {
         namespace mkldnn_backend {
 
             mkldnn_context::mkldnn_context() : context() {
-                using namespace composite_backend::
-                  mkldnn_backend;
-              
+                using namespace composite_backend::mkldnn_backend;
+
                 // BatchNormalization
                 procedure_factory_table_.emplace(
                   "BatchNormalization", mkldnn_backend::make_batch_norm);
 
                 // Conv
                 procedure_factory_table_.emplace("Conv", make_conv);
-              
+
                 // Gemm
                 procedure_factory_table_.emplace("Gemm", make_gemm);
 
@@ -29,11 +28,12 @@ namespace menoh_impl {
                 procedure_factory_table_.emplace("Relu", make_relu);
                 procedure_factory_table_.emplace("Sqrt", make_sqrt);
                 procedure_factory_table_.emplace("Tanh", make_tanh);
-              
+
                 // Pool
-                procedure_factory_table_.emplace("AveragePool", make_average_pool);
+                procedure_factory_table_.emplace("AveragePool",
+                                                 make_average_pool);
                 procedure_factory_table_.emplace("MaxPool", make_max_pool);
-              
+
                 // Softmax
                 procedure_factory_table_.emplace("Softmax", make_softmax);
 

From f87dd3b7f8e5a5c5ca330f1fbd807554d12d022d Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 15:50:11 +0900
Subject: [PATCH 306/321] remove iostream header include

---
 menoh/composite_backend/backend/generic/operator/constant.hpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator/constant.hpp b/menoh/composite_backend/backend/generic/operator/constant.hpp
index 0b0f6e3..e771953 100644
--- a/menoh/composite_backend/backend/generic/operator/constant.hpp
+++ b/menoh/composite_backend/backend/generic/operator/constant.hpp
@@ -6,8 +6,6 @@
 #include <menoh/array.hpp>
 #include <menoh/composite_backend/procedure.hpp>
 
-#include <iostream>
-
 namespace menoh_impl {
     namespace composite_backend {
         namespace generic_backend {

From 86ad58106a24497f31abd2daae2498112ac1dde7 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 17:01:18 +0900
Subject: [PATCH 307/321] remove constexpr keyword

---
 menoh/dtype.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index 50b77d6..04915af 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -85,7 +85,7 @@ namespace menoh_impl {
     template <dtype_t d>
     constexpr int size_in_bytes = sizeof(dtype_to_type_t<d>);
 
-    constexpr int get_size_in_bytes(dtype_t d) {
+    int get_size_in_bytes(dtype_t d) {
         if(d == dtype_t::float16) {
             return size_in_bytes<dtype_t::float16>;
         } else

From 83e304c4e4ad4e7f56898a27135017f2ce706f0a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 17:01:28 +0900
Subject: [PATCH 308/321] replace assert with throw

---
 menoh/dtype.hpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index 04915af..e813998 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -107,7 +107,7 @@ namespace menoh_impl {
         if(d == dtype_t::int64) {
             return size_in_bytes<dtype_t::int64>;
         }
-        assert(!"not come here");
+        throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
     }
 
 } // namespace menoh_impl

From f8aebde768763e80c024d1ea4403d586a5916817 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 18:26:02 +0900
Subject: [PATCH 309/321] fix bug

---
 menoh/dtype.cpp | 25 +++++++++++++++++++++++++
 menoh/dtype.hpp | 25 +------------------------
 2 files changed, 26 insertions(+), 24 deletions(-)

diff --git a/menoh/dtype.cpp b/menoh/dtype.cpp
index d5ce88a..a49259f 100644
--- a/menoh/dtype.cpp
+++ b/menoh/dtype.cpp
@@ -11,4 +11,29 @@ namespace menoh_impl {
         throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
     }
 
+    int get_size_in_bytes(dtype_t d) {
+        if(d == dtype_t::float16) {
+            return size_in_bytes<dtype_t::float16>;
+        } else
+        if(d == dtype_t::float32) {
+            return size_in_bytes<dtype_t::float32>;
+        }else
+        if(d == dtype_t::float64) {
+            return size_in_bytes<dtype_t::float64>;
+        } else
+        if(d == dtype_t::int8) {
+            return size_in_bytes<dtype_t::int8>;
+        } else
+        if(d == dtype_t::int16) {
+            return size_in_bytes<dtype_t::int16>;
+        } else
+        if(d == dtype_t::int32) {
+            return size_in_bytes<dtype_t::int32>;
+        } else
+        if(d == dtype_t::int64) {
+            return size_in_bytes<dtype_t::int64>;
+        }
+        throw invalid_dtype(std::to_string(static_cast<int>(d)));
+    }
+
 } // namespace menoh_impl
diff --git a/menoh/dtype.hpp b/menoh/dtype.hpp
index e813998..6716336 100644
--- a/menoh/dtype.hpp
+++ b/menoh/dtype.hpp
@@ -85,30 +85,7 @@ namespace menoh_impl {
     template <dtype_t d>
     constexpr int size_in_bytes = sizeof(dtype_to_type_t<d>);
 
-    int get_size_in_bytes(dtype_t d) {
-        if(d == dtype_t::float16) {
-            return size_in_bytes<dtype_t::float16>;
-        } else
-        if(d == dtype_t::float32) {
-            return size_in_bytes<dtype_t::float32>;
-        }else
-        if(d == dtype_t::float64) {
-            return size_in_bytes<dtype_t::float64>;
-        } else
-        if(d == dtype_t::int8) {
-            return size_in_bytes<dtype_t::int8>;
-        } else
-        if(d == dtype_t::int16) {
-            return size_in_bytes<dtype_t::int16>;
-        } else
-        if(d == dtype_t::int32) {
-            return size_in_bytes<dtype_t::int32>;
-        } else
-        if(d == dtype_t::int64) {
-            return size_in_bytes<dtype_t::int64>;
-        }
-        throw invalid_dtype(std::to_string(static_cast<int>(dtype)));
-    }
+    int get_size_in_bytes(dtype_t d);
 
 } // namespace menoh_impl
 

From 71af2e2e5b21b43e99e72550cf9cf0400c8a2ff1 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 20:25:46 +0900
Subject: [PATCH 310/321] add Identity operator

---
 ...tribute_completion_and_shape_inference.hpp | 16 +++++++++
 .../backend/generic/generic_context.cpp       |  1 +
 .../backend/generic/operator.hpp              |  1 +
 .../backend/generic/operator/identity.hpp     | 34 +++++++++++++++++++
 ...bute_completion_and_shape_inference_hpp.py |  1 +
 test/operator.cpp                             |  2 ++
 6 files changed, 55 insertions(+)
 create mode 100644 menoh/composite_backend/backend/generic/operator/identity.hpp

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index f8da5a0..bacb5c7 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -693,6 +693,22 @@ add_variable_to_table(output(0), dtype_of(input(0)),
 else
 
 
+if(node.op_type == "Identity") {
+    
+    
+    
+    {
+        
+        
+assert(node.input_name_list.size() > 0);
+assert(node.output_name_list.size() > 0);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+
+    }
+}
+else
+
+
 if(node.op_type == "LeakyRelu") {
     
     
diff --git a/menoh/composite_backend/backend/generic/generic_context.cpp b/menoh/composite_backend/backend/generic/generic_context.cpp
index b05a66c..09ab4ee 100644
--- a/menoh/composite_backend/backend/generic/generic_context.cpp
+++ b/menoh/composite_backend/backend/generic/generic_context.cpp
@@ -7,6 +7,7 @@ namespace menoh_impl {
 
             generic_context::generic_context() : context() {
                 procedure_factory_table_.emplace("Constant", make_constant);
+                procedure_factory_table_.emplace("Identity", make_identity);
                 procedure_factory_table_.emplace("Relu", make_relu);
                 procedure_factory_table_.emplace("Reshape", make_reshape);
                 procedure_factory_table_.emplace("Mul", make_mul);
diff --git a/menoh/composite_backend/backend/generic/operator.hpp b/menoh/composite_backend/backend/generic/operator.hpp
index e7d2b9a..646adf3 100644
--- a/menoh/composite_backend/backend/generic/operator.hpp
+++ b/menoh/composite_backend/backend/generic/operator.hpp
@@ -2,6 +2,7 @@
 #define MENOH_IMPL_COMPOSITE_BACKEND_GENERIC_OPERATOR_HPP
 
 #include <menoh/composite_backend/backend/generic/operator/constant.hpp>
+#include <menoh/composite_backend/backend/generic/operator/identity.hpp>
 #include <menoh/composite_backend/backend/generic/operator/mul.hpp>
 #include <menoh/composite_backend/backend/generic/operator/relu.hpp>
 #include <menoh/composite_backend/backend/generic/operator/reshape.hpp>
diff --git a/menoh/composite_backend/backend/generic/operator/identity.hpp b/menoh/composite_backend/backend/generic/operator/identity.hpp
new file mode 100644
index 0000000..4a5e543
--- /dev/null
+++ b/menoh/composite_backend/backend/generic/operator/identity.hpp
@@ -0,0 +1,34 @@
+#ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_IDENTITY_HPP
+#define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_IDENTITY_HPP
+
+#include <menoh/array.hpp>
+#include <menoh/composite_backend/procedure.hpp>
+
+#include <iostream>
+
+namespace menoh_impl {
+    namespace composite_backend {
+        namespace generic_backend {
+            inline procedure
+            make_identity(node const& node,
+                          std::vector<array> const& input_list,
+                          std::vector<array> const& output_list) {
+                assert(input_list.size() == 1);
+                assert(output_list.size() == 1);
+
+                auto procedure = [input = input_list.at(0),
+                                  output = output_list.at(0)]() {
+                    for(decltype(total_size(input)) i = 0;
+                        i < total_size(input); ++i) {
+                        fat(output, i) = fat(input, i);
+                    }
+                };
+
+                return procedure;
+            }
+
+        } // namespace generic_backend
+    }     // namespace composite_backend
+} // namespace menoh_impl
+
+#endif // MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_IDENTITY_HPP
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 7a655fa..1587d5c 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -320,6 +320,7 @@ def main():
 add_variable_to_table(output(0), dtype_of(input(0)),
     output_dims);
 '''))
+    code_list.append(make_completion_code("Identity"))
     code_list.append(
         make_completion_code("LeakyRelu", [("alpha", "float", "0.01f")]))
     code_list.append(
diff --git a/test/operator.cpp b/test/operator.cpp
index e4a1264..410edff 100644
--- a/test/operator.cpp
+++ b/test/operator.cpp
@@ -263,6 +263,8 @@ namespace {
     TEST_OP_SQUASH_DIMS(mkldnn_with_generic_fallback, test_tanh, eps);
 
     //TEST_OP(mkldnn_with_generic_fallback, test_gemm_nobroadcast, eps);
+    
+    TEST_OP(mkldnn_with_generic_fallback, test_identity, eps);
 
     // Mul
     TEST_OP(mkldnn_with_generic_fallback, test_mul, eps);

From a93e1b70ae623766e6397e5fe699bae72dffbf77 Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 17:00:32 +0900
Subject: [PATCH 311/321] fix identity

---
 .../backend/generic/operator/identity.hpp              | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator/identity.hpp b/menoh/composite_backend/backend/generic/operator/identity.hpp
index 4a5e543..67ebf92 100644
--- a/menoh/composite_backend/backend/generic/operator/identity.hpp
+++ b/menoh/composite_backend/backend/generic/operator/identity.hpp
@@ -1,11 +1,11 @@
 #ifndef MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_IDENTITY_HPP
 #define MENOH_IMPL_COMPOSITE_BACKEND_BACKEND_GENERIC_OPERATOR_IDENTITY_HPP
 
+#include <algorithm>
+
 #include <menoh/array.hpp>
 #include <menoh/composite_backend/procedure.hpp>
 
-#include <iostream>
-
 namespace menoh_impl {
     namespace composite_backend {
         namespace generic_backend {
@@ -21,6 +21,12 @@ namespace menoh_impl {
                     for(decltype(total_size(input)) i = 0;
                         i < total_size(input); ++i) {
                         fat(output, i) = fat(input, i);
+                        std::copy(
+                          static_cast<char*>(input.data()),
+                          static_cast<char*>(
+                            input.data() + total_size(input) *
+                                             get_size_in_bytes(input.dtype())),
+                          static_cast<char*>(output.data()));
                     }
                 };
 

From cacde207e7fb442cb086a78fd01ec886c4f30b3c Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 20:46:32 +0900
Subject: [PATCH 312/321] fix assert for identity

---
 menoh/attribute_completion_and_shape_inference.hpp |  5 ++---
 ...attribute_completion_and_shape_inference_hpp.py | 14 +++++++++++---
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index bacb5c7..bb3f8c4 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -700,9 +700,8 @@ if(node.op_type == "Identity") {
     {
         
         
-assert(node.input_name_list.size() > 0);
-assert(node.output_name_list.size() > 0);
-add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
 
     }
 }
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 1587d5c..f5d57b9 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -307,20 +307,28 @@ def main():
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 '''))
     code_list.append(
-        make_completion_code("GlobalAveragePool", [], '''
+        make_completion_code(
+            "GlobalAveragePool", [], '''
 auto input_dims = dims_of(input(0));
 auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
 add_variable_to_table(output(0), dtype_of(input(0)),
     output_dims);
 '''))
     code_list.append(
-        make_completion_code("GlobalMaxPool", [], '''
+        make_completion_code(
+            "GlobalMaxPool", [], '''
 auto input_dims = dims_of(input(0));
 auto output_dims = ints({input_dims[0], input_dims[1], 1, 1});
 add_variable_to_table(output(0), dtype_of(input(0)),
     output_dims);
 '''))
-    code_list.append(make_completion_code("Identity"))
+    code_list.append(
+        make_completion_code(
+            "Identity",
+            shape_inference_code='''
+assert(node.input_name_list.size() == 1);
+assert(node.output_name_list.size() == 1);
+'''))
     code_list.append(
         make_completion_code("LeakyRelu", [("alpha", "float", "0.01f")]))
     code_list.append(

From 5e15f125ac44f1d1889661c51a0b28a156add47c Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Thu, 14 Mar 2019 20:47:38 +0900
Subject: [PATCH 313/321] fix format

---
 ...bute_completion_and_shape_inference_hpp.py | 99 ++++++++++++-------
 1 file changed, 62 insertions(+), 37 deletions(-)

diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index f5d57b9..28f129a 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -61,8 +61,7 @@ def make_completion_code(op_name,
         attribute_definition="\n".join(attribute_definition_list),
         shape_inference_code=shape_inference_code,
         postprocess=postprocess,
-        attribute_completion_code="\n".join(
-            attribute_completion_code_list))
+        attribute_completion_code="\n".join(attribute_completion_code_list))
 
 
 def main():
@@ -162,17 +161,22 @@ def main():
     code_list.append(make_completion_code("Abs"))
     code_list.append(make_completion_code("Add"))
     code_list.append(
-        make_completion_code("AveragePool", [
-            ("count_include_pad", "int", "0"),
-            ("kernel_shape", "ints", None),
-            ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
-            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"),  # WORKAROUND: None is correct # NOQA
-        ], '''
+        make_completion_code(
+            "AveragePool",
+            [
+                ("count_include_pad", "int", "0"),
+                ("kernel_shape", "ints", None),
+                ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
+                ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"
+                 ),  # WORKAROUND: None is correct # NOQA
+            ],
+            '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims(
         dims_of(input(0)), dims_of(input(0)).at(1),
         kernel_shape, strides, pads));
-''', preprocess='''
+''',
+            preprocess='''
 assert(2 <= ndims_of(input(0)));
 '''))
     code_list.append(
@@ -182,9 +186,10 @@ def main():
             ("spatial", "int", "1"),
         ]))
     code_list.append(
-        make_completion_code("Concat", [
-            ("axis", "int", None),
-        ], '''
+        make_completion_code(
+            "Concat", [
+                ("axis", "int", None),
+            ], '''
 auto output_dims = dims_of(input(0));
 for(unsigned int i = 1; i < node.input_name_list.size(); ++i) {
     // TODO dim check
@@ -193,9 +198,10 @@ def main():
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
 '''))
     code_list.append(
-        make_completion_code("Constant", [
-            ("value", "array", None),
-        ], '''
+        make_completion_code(
+            "Constant", [
+                ("value", "array", None),
+            ], '''
 add_variable_to_table(output(0), value.dtype(), value.dims());
 '''))
     code_list.append(
@@ -206,7 +212,8 @@ def main():
                 ("kernel_shape", "ints", "kernel_shape"),
                 ("pads", "ints", "ints(kernel_ndims*2, 0)"),
                 ("strides", "ints", "ints(kernel_ndims, 1)"),
-            ], '''
+            ],
+            '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims(
         dims_of(input(0)), dims_of(input(1)).at(0),
@@ -228,7 +235,8 @@ def main():
                 # ("output_shape", "ints", None),
                 # ("pads", "ints", None),
                 ("strides", "ints", "ints(kernel_ndims, 1)"),
-            ], '''
+            ],
+            '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims_for_conv_transpose(
         dims_of(input(0)), dims_of(input(1)).at(0),
@@ -268,18 +276,20 @@ def main():
 '''))
     code_list.append(make_completion_code("Elu", [("alpha", "float", "1.f")]))
     code_list.append(
-        make_completion_code("FC", [], '''
+        make_completion_code(
+            "FC", [], '''
 auto output_dims = ints({dims_of(input(0)).at(0), dims_of(input(1)).at(0)});
 add_variable_to_table(output(0), dtype_of(input(0)),
     output_dims);
 '''))
     code_list.append(
-        make_completion_code("Gemm", [
-            ("alpha", "float", "1.f"),
-            ("beta", "float", "1.f"),
-            ("transA", "int", "0"),
-            ("transB", "int", "0"),
-        ], '''
+        make_completion_code(
+            "Gemm", [
+                ("alpha", "float", "1.f"),
+                ("beta", "float", "1.f"),
+                ("transA", "int", "0"),
+                ("transB", "int", "0"),
+            ], '''
 auto a_dims = dims_of(input(0));
 if(ndims_of(input(0)) != 2) {
     int feature_size = std::accumulate(
@@ -339,24 +349,32 @@ def main():
             ("size", "float", None),
         ]))
     code_list.append(
-        make_completion_code("MaxPool", [
-            ("kernel_shape", "ints", None),
-            ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
-            ("storage_order", "int", "0"),
-            ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"), # WORKAROUND: None is correct # NOQA
-        ], '''
+        make_completion_code(
+            "MaxPool",
+            [
+                ("kernel_shape", "ints", None),
+                ("pads", "ints", "ints(2*(ndims_of(input(0))-2), 0)"),
+                ("storage_order", "int", "0"),
+                ("strides", "ints", "ints(ndims_of(input(0))-2, 1)"
+                 ),  # WORKAROUND: None is correct # NOQA
+            ],
+            '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     calc_2d_output_dims(
         dims_of(input(0)), dims_of(input(0)).at(1),
         kernel_shape, strides, pads));
 '''))
-    code_list.append(make_completion_code("Mul", [], '''
+    code_list.append(
+        make_completion_code(
+            "Mul", [], '''
 add_variable_to_table(output(0), dtype_of(input(0)),
     broadcast_shape(
         dims_of(input(0)), dims_of(input(1))));
 '''))
     code_list.append(make_completion_code("Relu"))
-    code_list.append(make_completion_code("Reshape", [], '''
+    code_list.append(
+        make_completion_code(
+            "Reshape", [], '''
 auto found = std::find_if(model_data.parameter_name_and_array_list.begin(),
                           model_data.parameter_name_and_array_list.end(),
                           [shape_name=node.input_name_list.at(1)](
@@ -389,22 +407,29 @@ def main():
     code_list.append(make_completion_code("Sqrt"))
     code_list.append(make_completion_code("Tanh"))
     code_list.append(
-        make_completion_code("Transpose", [
-            ("perm", "ints", "perm"),
-        ], '''
+        make_completion_code(
+            "Transpose", [
+                ("perm", "ints", "perm"),
+            ],
+            '''
 auto input_dims = dims_of(input(0));
 ints output_dims(input_dims.size());
 for(unsigned int i = 0; i < input_dims.size(); ++i) {
     output_dims.at(i) = input_dims.at(perm.at(i));
 }
 add_variable_to_table(output(0), dtype_of(input(0)), output_dims);
-''', preprocess="""
+''',
+            preprocess="""
 ints perm(ndims_of(input(0)));
 for(unsigned int i = 0; i < perm.size(); ++i) {{
     perm.at(i) = perm.size()-i-1;
 }}
 """))
-    print(template.format(script_name=os.path.basename(__file__), code="\n".join(code_list), unsupported_operator='''
+    print(
+        template.format(
+            script_name=os.path.basename(__file__),
+            code="\n".join(code_list),
+            unsupported_operator='''
 {
     throw unsupported_operator(node.op_type);
 }

From 93ac9b612d0b491f20e0286c0ad006ec51058dde Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Fri, 15 Mar 2019 14:17:15 +0900
Subject: [PATCH 314/321] fix

---
 .../backend/generic/operator/identity.hpp           | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/menoh/composite_backend/backend/generic/operator/identity.hpp b/menoh/composite_backend/backend/generic/operator/identity.hpp
index 67ebf92..c08275c 100644
--- a/menoh/composite_backend/backend/generic/operator/identity.hpp
+++ b/menoh/composite_backend/backend/generic/operator/identity.hpp
@@ -10,7 +10,7 @@ namespace menoh_impl {
     namespace composite_backend {
         namespace generic_backend {
             inline procedure
-            make_identity(node const& node,
+            make_identity(node const& /*node*/,
                           std::vector<array> const& input_list,
                           std::vector<array> const& output_list) {
                 assert(input_list.size() == 1);
@@ -21,12 +21,11 @@ namespace menoh_impl {
                     for(decltype(total_size(input)) i = 0;
                         i < total_size(input); ++i) {
                         fat(output, i) = fat(input, i);
-                        std::copy(
-                          static_cast<char*>(input.data()),
-                          static_cast<char*>(
-                            input.data() + total_size(input) *
-                                             get_size_in_bytes(input.dtype())),
-                          static_cast<char*>(output.data()));
+                        std::copy(static_cast<char*>(input.data()),
+                                  static_cast<char*>(input.data()) +
+                                    total_size(input) *
+                                      get_size_in_bytes(input.dtype()),
+                                  static_cast<char*>(output.data()));
                     }
                 };
 

From e099159d9425dfb148d95d24e858056feb9e090a Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Mon, 1 Apr 2019 16:53:31 +0900
Subject: [PATCH 315/321] fix shape inference for Identity

---
 menoh/attribute_completion_and_shape_inference.hpp          | 1 +
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 1 +
 2 files changed, 2 insertions(+)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index bb3f8c4..198da32 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -702,6 +702,7 @@ if(node.op_type == "Identity") {
         
 assert(node.input_name_list.size() == 1);
 assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 
     }
 }
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 28f129a..acdd2cc 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -338,6 +338,7 @@ def main():
             shape_inference_code='''
 assert(node.input_name_list.size() == 1);
 assert(node.output_name_list.size() == 1);
+add_variable_to_table(output(0), dtype_of(input(0)), dims_of(input(0)));
 '''))
     code_list.append(
         make_completion_code("LeakyRelu", [("alpha", "float", "0.01f")]))

From 4d225295baf53b566e247eaabb5bd29fc95f793b Mon Sep 17 00:00:00 2001
From: okdshin <kokuzen@gmail.com>
Date: Wed, 17 Apr 2019 12:25:40 +0900
Subject: [PATCH 316/321] fix

---
 menoh/attribute_completion_and_shape_inference.hpp          | 2 +-
 scripts/gen_attribute_completion_and_shape_inference_hpp.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/menoh/attribute_completion_and_shape_inference.hpp b/menoh/attribute_completion_and_shape_inference.hpp
index f8da5a0..0fe52cf 100644
--- a/menoh/attribute_completion_and_shape_inference.hpp
+++ b/menoh/attribute_completion_and_shape_inference.hpp
@@ -647,7 +647,7 @@ if(transB) {
 
 if(a_dims.at(1) != b_dims.at(0)) {
     throw dimension_mismatch(
-        node.op_type, input(0), "trans(A)[1] and trans(B)[0])",
+        node.op_type, output(0), "trans(A)[1] and trans(B)[0])",
         std::to_string(a_dims.at(1)), std::to_string(b_dims.at(0)));
 }
 
diff --git a/scripts/gen_attribute_completion_and_shape_inference_hpp.py b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
index 7a655fa..4c5d974 100644
--- a/scripts/gen_attribute_completion_and_shape_inference_hpp.py
+++ b/scripts/gen_attribute_completion_and_shape_inference_hpp.py
@@ -299,7 +299,7 @@ def main():
 
 if(a_dims.at(1) != b_dims.at(0)) {
     throw dimension_mismatch(
-        node.op_type, input(0), "trans(A)[1] and trans(B)[0])",
+        node.op_type, output(0), "trans(A)[1] and trans(B)[0])",
         std::to_string(a_dims.at(1)), std::to_string(b_dims.at(0)));
 }
 

From 234b5f12cb9f63e2e09df92dbd15d7d51fc966c0 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 12 Aug 2020 00:17:08 +0900
Subject: [PATCH 317/321] disable osx builds on Travis-CI

Because Menoh does not yet support newer mkl-dnn (oneDNN) installed by current Homebrew.
---
 .travis.yml | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index ed255fe..b01f7d0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,12 +22,13 @@ cache:
 
 matrix:
     include:
-        - os: osx
-          env: PLATFORM=macosx-x86_64
-        - os: osx
-          env: PLATFORM=macosx-x86_64 LINK_STATIC=true
-        - os: osx
-          env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
+        # osx builds were disabled, because Menoh does not yet support newer mkl-dnn (oneDNN) installed by current Homebrew.
+        # - os: osx
+        #   env: PLATFORM=macosx-x86_64
+        # - os: osx
+        #   env: PLATFORM=macosx-x86_64 LINK_STATIC=true
+        # - os: osx
+        #   env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
         - os: linux

From 868929ad8c9ddf9a9f6063cb2298f78789ab3421 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 12 Aug 2020 00:08:33 +0900
Subject: [PATCH 318/321] use the name oneDNN instead of mkl-dnn in build
 scripts

Because tarball downloaded from github constians 'oneDNN' directory
even if the tarball is for the release before the rename.
---
 .travis/init-build-linux.sh | 2 +-
 scripts/build-mkldnn.sh     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.travis/init-build-linux.sh b/.travis/init-build-linux.sh
index a4cdb42..0840439 100644
--- a/.travis/init-build-linux.sh
+++ b/.travis/init-build-linux.sh
@@ -64,7 +64,7 @@ function build_mkldnn() {
 function install_mkldnn() {
     docker_exec_script \
         "${PROJ_DIR}/scripts/install-mkldnn.sh" \
-            --build-dir "${WORK_DIR}/build/mkl-dnn-${MKLDNN_VERSION}/build"
+            --build-dir "${WORK_DIR}/build/oneDNN-${MKLDNN_VERSION}/build"
 }
 
 function prepare_menoh_data() {
diff --git a/scripts/build-mkldnn.sh b/scripts/build-mkldnn.sh
index 52ed504..479db4c 100755
--- a/scripts/build-mkldnn.sh
+++ b/scripts/build-mkldnn.sh
@@ -48,7 +48,7 @@ test -n "${ARG_EXTRACT_DIR}" || { echo "--extract-dir is not specified" 1>&2; ex
 # options that have default value
 test -n "${ARG_VERSION}" || readonly ARG_VERSION=0.16
 
-readonly LIBRARY_NAME=mkl-dnn-${ARG_VERSION}
+readonly LIBRARY_NAME=oneDNN-${ARG_VERSION}
 readonly SOURCE_DIR="${ARG_EXTRACT_DIR}/${LIBRARY_NAME}"
 
 test -n "${ARG_BUILD_DIR}" || readonly ARG_BUILD_DIR="${SOURCE_DIR}/build"

From 42578b1e8653afadc13be04b3e9b5c72fd96d1e7 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Wed, 12 Aug 2020 09:27:39 +0900
Subject: [PATCH 319/321] Adding notice to README.md that Menoh is no longer
 maintained

---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
index e7c6965..b1abb45 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+**Notice: Menoh is no longer maintained. Part of its functionality is inherited by [chainer-compiler](https://github.com/pfnet-research/chainer-compiler).**
+
+
 # Menoh
 
 [![travis](https://img.shields.io/travis/pfnet-research/menoh/master.svg)](https://travis-ci.org/pfnet-research/menoh) [![Build status](https://ci.appveyor.com/api/projects/status/luo2m9p5fg9jxjsh/branch/master?svg=true)](https://ci.appveyor.com/project/pfnet-research/menoh/branch/master)

From c7e89f5bdcadd700b1226446cd2a2d8f74d17760 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Fri, 14 Aug 2020 14:51:11 +0900
Subject: [PATCH 320/321] re-enable Travis-CI builds for osx by not using
 mkl-dnn provided by Homebrew

---
 .travis.yml                    | 13 ++++++-------
 .travis/init-build-osx.sh      | 16 ++++++++++++++++
 .travis/macosx-x86_64/build.sh |  6 +++++-
 3 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index b01f7d0..ed255fe 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,13 +22,12 @@ cache:
 
 matrix:
     include:
-        # osx builds were disabled, because Menoh does not yet support newer mkl-dnn (oneDNN) installed by current Homebrew.
-        # - os: osx
-        #   env: PLATFORM=macosx-x86_64
-        # - os: osx
-        #   env: PLATFORM=macosx-x86_64 LINK_STATIC=true
-        # - os: osx
-        #   env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
+        - os: osx
+          env: PLATFORM=macosx-x86_64
+        - os: osx
+          env: PLATFORM=macosx-x86_64 LINK_STATIC=true
+        - os: osx
+          env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6
         - os: linux
diff --git a/.travis/init-build-osx.sh b/.travis/init-build-osx.sh
index 4a40497..cf5f415 100644
--- a/.travis/init-build-osx.sh
+++ b/.travis/init-build-osx.sh
@@ -7,8 +7,24 @@ test -n "${BUILD_STATIC_LIBS}" || BUILD_STATIC_LIBS=false
 export WORK_DIR=${HOME}
 export PROJ_DIR=${TRAVIS_BUILD_DIR} # = ${HOME}/build/${TRAVIS_REPO_SLUG}
 
+export MKLDNN_INSTALL_DIR=/usr/local
+
 ## define shared functions for macOS (OSX) platforms
 
+function build_mkldnn() {
+    bash -ex "${PROJ_DIR}/scripts/build-mkldnn.sh" \
+        --version ${MKLDNN_VERSION} \
+        --download-dir "${WORK_DIR}/downloads" \
+        --extract-dir "${WORK_DIR}/build" \
+        --install-dir "${MKLDNN_INSTALL_DIR}" \
+        --parallel ${MAKE_JOBS}
+}
+
+function install_mkldnn() {
+    bash -ex "${PROJ_DIR}/scripts/install-mkldnn.sh" \
+        --build-dir "${WORK_DIR}/build/oneDNN-${MKLDNN_VERSION}/build"
+}
+
 function prepare_menoh_data() {
     bash -ex "${PROJ_DIR}/scripts/prepare-menoh-data.sh" \
         --source-dir "${PROJ_DIR}" \
diff --git a/.travis/macosx-x86_64/build.sh b/.travis/macosx-x86_64/build.sh
index ec672cc..db45b97 100644
--- a/.travis/macosx-x86_64/build.sh
+++ b/.travis/macosx-x86_64/build.sh
@@ -22,7 +22,7 @@ brew upgrade python
 export PATH=/usr/local/opt/python/libexec/bin:$PATH
 
 brew install numpy || true
-brew install opencv mkl-dnn
+brew install opencv
 
 if [ "$LINK_STATIC" != "true" ]; then brew install protobuf; fi
 
@@ -31,6 +31,10 @@ pip install --user chainer # for generating test data
 brew list --versions
 pip list
 
+# build and install prerequisites
+build_mkldnn
+install_mkldnn
+
 # build and test menoh
 build_menoh
 prepare_menoh_data

From 5ed64207429e2176757cad165d852d3c61fbd2c3 Mon Sep 17 00:00:00 2001
From: Masahiro Sakai <masahiro.sakai@gmail.com>
Date: Thu, 24 Dec 2020 09:21:09 +0900
Subject: [PATCH 321/321] travis: use macOS Mojave (10.14) for macOS build

---
 .travis.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index ed255fe..417e1eb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,10 +23,13 @@ cache:
 matrix:
     include:
         - os: osx
+          osx_image: xcode10.2
           env: PLATFORM=macosx-x86_64
         - os: osx
+          osx_image: xcode10.2
           env: PLATFORM=macosx-x86_64 LINK_STATIC=true
         - os: osx
+          osx_image: xcode10.2
           env: PLATFORM=macosx-x86_64 BUILD_STATIC_LIBS=true
         - os: linux
           env: PLATFORM=linux-x86_64 BUILDENV_IMAGE=okapies/buildenv:linux-x64-devtoolset-6