diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5969181d82318bfc04a48970bcd9c7fc8ae8de4a..70644054256d4f6372603dfece2df2f29f8e9c03 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -90,3 +90,30 @@ TestMNISTwithCustomLayer:
- cd mnist-custom-layer
- mvn dependency:resolve emadl:train -s settings.xml
+TrainTensorflowONNX:
+ stage: linux
+ image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/tensorflow-onnx:latest
+ artifacts:
+ paths:
+ - onnx/tensorflow-pretrained/model/
+ expire_in: 1 day
+ script:
+ - cd onnx/tensorflow-pretrained
+ - mvn dependency:resolve emadl:train -s settings.xml
+
+TestGluonONNX:
+ stage: linux
+ image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet170-onnx:v0.0.1
+ needs:
+ - TrainTensorflowONNX
+ script:
+ - mv /mxnet/build/libmxnet.so /mxnet/build/libmxnet.a /usr/lib/
+ - cd onnx/tensorflow-pretrained
+ - ls model/cNNCalculator.Network/
+ - mvn emadl:install-pretrained -e -s ./settings.xml
+ - cd ../gluon-load
+ - mvn emadl:train -s settings.xml
+ - chmod +x build.sh
+ - ./build.sh
+ - RES=$(./build/src/cpp/DigitCalculator resources/images/1.png resources/images/2.png resources/images/3.png resources/images/4.png resources/images/5.png resources/images/6.png)
+ - "if [[ $RES != *\"SUM: 579\"* ]]; then echo \"Wrong result:\" $RES; exit 1; fi;"
\ No newline at end of file
diff --git a/onnx/.gitignore b/onnx/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..446764f1b69883078a7530c4dc43e4dc222a68f8
--- /dev/null
+++ b/onnx/.gitignore
@@ -0,0 +1,6 @@
+train.log
+target/
+model/
+build/
+
+model_0-0000.onnx
\ No newline at end of file
diff --git a/onnx/README.md b/onnx/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f798788eeec4f6d7c994458eadc481d356023972
--- /dev/null
+++ b/onnx/README.md
@@ -0,0 +1,40 @@
+
+# Calculator TENSORFLOW-ONNX-GLUON
+
+In this folder demonstration of sharing model between tensorflow and mxnet frameworks.
+During the run, the MNISTCalculator model will be trained in tensorflow backend and then exported to mxnet backend via ONNX.
+
+## Prerequisites
+1. Ubuntu Linux 16.04 LTS or 18.04 LTS (experimental)
+2. Deep Learning Frameworks **Tensorlfow** and **MXNet**
+3. Armadillo (at least armadillo version 6.600 must be used) [Official instructions at Armadillo Website](http://arma.sourceforge.net/download.html).
+4. OpenCV
+
+
+## How to Run
+Generate and build the code for the EMADL model by executing:
+
+```
+bash build.sh
+```
+
+Finally, go to `gluon-load` folder run the calculator as follows:
+```
+./build/src/cpp/DigitCalculator resources/images/1.png resources/images/2.png resources/images/3.png resources/images/4.png resources/images/5.png resources/images/6.png
+```
+
+You can try different images from the provided `/resources/images` directory or even create your own images for testing. Note that the application program DigitCalculator will automatically rescale the given input image to the size 32x32.
+
+
+
+## Troubleshooting Help
+
+ERROR: HelperA.h:79:28: error: ‘sqrtmat’ was not declared in this scope.
+
+FIX:
+Copy compiled armadillo lib and include files to usr/lib and usr/include respectively. Replace YOUR_ARMADILLO_REPOSITORY and VERSION (e.g. 8.500.1) with your corresponding information:
+```
+cd YOUR_ARMADILLO_REPOSITORY/armadillo-VERSION
+sudo cp libarmadillo* /usr/lib
+cd YOUR_ARMADILLO_REPOSITORY/armadillo-VERSION/include
+sudo cp -r * /usr/include
diff --git a/onnx/build.sh b/onnx/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..871401a22f6e098eaea0983c0d490b553965333f
--- /dev/null
+++ b/onnx/build.sh
@@ -0,0 +1,37 @@
+MXNET_PATH=$(python3 -c "import mxnet; print(mxnet.__file__)")
+# (c) https://github.com/MontiCore/monticore
+MXNET_FOLDER=$(dirname $MXNET_PATH)
+echo $MXNET_FOLDER
+
+if [ ! -f $MXNET_FOLDER/libmxnet.so ]; then
+ echo "libmxnet.so not found at default location" $MXNET_FOLDER
+ echo "It should be there if the python mxnet package is installed"
+ echo "Either fix the installation, or adapt the ./build.sh script to locate libmxnet.so correctly"
+ exit 1
+fi
+
+# cd ./gluon-pretrained
+# rm -rf ./target
+# rm -rf ./model
+# java -jar ../embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar -m ./src/emadl/models/ -r cNNCalculator.Connector -o target -b GLUON -p /usr/bin/python3
+
+# cp ./model/cNNCalculator.Network/model_0_newest.onnx ../model_0-0000.onnx
+
+cd ./tensorflow-pretrained
+rm -rf ./target
+rm -rf ./model
+java -jar ../embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar -m ./src/emadl/models/ -r cNNCalculator.Connector -o target -b TENSORFLOW -c n -p /usr/bin/python3
+
+cp ./model/cNNCalculator.Network/model.onnx ../model_0-0000.onnx
+
+cd ../gluon-load
+rm -rf ./target
+rm -rf ./model
+java -jar ../embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar -m ./src/emadl/models/ -r cNNCalculator.Connector -o target -b GLUON -p /usr/bin/python3
+
+rm -rf build
+mkdir build && cd build
+
+echo "Building DigitClassifier.."
+cmake -D MXNET_PATH=$MXNET_FOLDER/libmxnet.so ..
+make
\ No newline at end of file
diff --git a/onnx/embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar b/onnx/embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar
new file mode 100644
index 0000000000000000000000000000000000000000..f175978259487f0f5b12e905b3dd8e66158cf786
Binary files /dev/null and b/onnx/embedded-montiarc-emadl-generator-0.5.5-SNAPSHOT-jar-with-dependencies.jar differ
diff --git a/onnx/gluon-load/.gitignore b/onnx/gluon-load/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4ac7b8e1c76dbc2772679380c9340fa32b393b4f
--- /dev/null
+++ b/onnx/gluon-load/.gitignore
@@ -0,0 +1,4 @@
+train.log
+target/
+model/
+build/
diff --git a/onnx/gluon-load/CMakeLists.txt b/onnx/gluon-load/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4ff64561b4c7881e51152b96935befac7c5cec54
--- /dev/null
+++ b/onnx/gluon-load/CMakeLists.txt
@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.5)
+project (default)
+set (CMAKE_CXX_STANDARD 11)
+add_subdirectory(src/cpp)
+add_subdirectory(target/tmp/cpp/cNNCalculator.Connector)
diff --git a/onnx/gluon-load/build.sh b/onnx/gluon-load/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ccfb121b237434e03178d4f6bb5a88985c7fbf10
--- /dev/null
+++ b/onnx/gluon-load/build.sh
@@ -0,0 +1,18 @@
+MXNET_PATH=$(python3 -c "import mxnet; print(mxnet.__file__)")
+# (c) https://github.com/MontiCore/monticore
+MXNET_FOLDER=$(dirname $MXNET_PATH)
+echo $MXNET_FOLDER
+
+if [ ! -f $MXNET_FOLDER/libmxnet.so ]; then
+ echo "libmxnet.so not found at default location" $MXNET_FOLDER
+ echo "It should be there if the python mxnet package is installed"
+ echo "Either fix the installation, or adapt the ./build.sh script to locate libmxnet.so correctly"
+ exit 1
+fi
+
+rm -rf build
+mkdir build && cd build
+
+echo "Building DigitClassifier.."
+cmake -D MXNET_PATH=$MXNET_FOLDER/libmxnet.so ..
+make
\ No newline at end of file
diff --git a/onnx/gluon-load/pom.xml b/onnx/gluon-load/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6cbb94f48d86215bda6fbfabf3bfc88e287afbd8
--- /dev/null
+++ b/onnx/gluon-load/pom.xml
@@ -0,0 +1,62 @@
+
+
+
+ 4.0.0
+
+ de.monticore.lang.monticar.application
+ mnist-calculator
+ 0.0.2-SNAPSHOT
+
+
+
+
+ 1.8
+
+ UTF-8
+ UTF-8
+
+
+
+
+ de.monticore.lang.monticar.pretrained
+ mnistcalc-tensorflow
+ 1
+ pretrained
+
+
+
+
+
+
+
+ de.monticore.lang.monticar.utilities
+ emadl-maven-plugin
+ 0.0.6-SNAPSHOT
+
+
+ GLUON
+ cNNCalculator.Connector
+ src/emadl/models
+ src/emadl/models
+ /usr/bin/python3
+
+
+
+
+
+
+
+
+
+ se-nexus
+ https://nexus.se.rwth-aachen.de/content/repositories/embeddedmontiarc-releases/
+
+
+ se-nexus
+ https://nexus.se.rwth-aachen.de/content/repositories/embeddedmontiarc-snapshots/
+
+
+
+
diff --git a/onnx/gluon-load/resources/images/0.png b/onnx/gluon-load/resources/images/0.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf99edfe4e51cbc376c7ce6f9a6e0655b281595e
Binary files /dev/null and b/onnx/gluon-load/resources/images/0.png differ
diff --git a/onnx/gluon-load/resources/images/1.png b/onnx/gluon-load/resources/images/1.png
new file mode 100644
index 0000000000000000000000000000000000000000..69031fbac2bd2acecf7da6d1676a984e85898beb
Binary files /dev/null and b/onnx/gluon-load/resources/images/1.png differ
diff --git a/onnx/gluon-load/resources/images/2.png b/onnx/gluon-load/resources/images/2.png
new file mode 100644
index 0000000000000000000000000000000000000000..95c34b43b20c58e120fdc07d803968b2608770ba
Binary files /dev/null and b/onnx/gluon-load/resources/images/2.png differ
diff --git a/onnx/gluon-load/resources/images/3.png b/onnx/gluon-load/resources/images/3.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa5b172bfa28d2f612312cc079d86eee66190b50
Binary files /dev/null and b/onnx/gluon-load/resources/images/3.png differ
diff --git a/onnx/gluon-load/resources/images/4.png b/onnx/gluon-load/resources/images/4.png
new file mode 100644
index 0000000000000000000000000000000000000000..32ad0dd9193a1c44f3b8723a1e19bfdd904415f2
Binary files /dev/null and b/onnx/gluon-load/resources/images/4.png differ
diff --git a/onnx/gluon-load/resources/images/5.png b/onnx/gluon-load/resources/images/5.png
new file mode 100644
index 0000000000000000000000000000000000000000..caf30c84a3a38d7087d383cf5de7983bfae56f4d
Binary files /dev/null and b/onnx/gluon-load/resources/images/5.png differ
diff --git a/onnx/gluon-load/resources/images/6.png b/onnx/gluon-load/resources/images/6.png
new file mode 100644
index 0000000000000000000000000000000000000000..6fcabc1c50b0ef249d16d1888f789cd659249c1f
Binary files /dev/null and b/onnx/gluon-load/resources/images/6.png differ
diff --git a/onnx/gluon-load/resources/images/7.png b/onnx/gluon-load/resources/images/7.png
new file mode 100644
index 0000000000000000000000000000000000000000..eec96053eab30a5b3b9e76221ad8b8a970036a45
Binary files /dev/null and b/onnx/gluon-load/resources/images/7.png differ
diff --git a/onnx/gluon-load/resources/images/8.png b/onnx/gluon-load/resources/images/8.png
new file mode 100644
index 0000000000000000000000000000000000000000..85009f41d0ef9b2e282ce4e068abd5cdc83d62c8
Binary files /dev/null and b/onnx/gluon-load/resources/images/8.png differ
diff --git a/onnx/gluon-load/resources/images/9.png b/onnx/gluon-load/resources/images/9.png
new file mode 100644
index 0000000000000000000000000000000000000000..1ccdc4b892292c02cf7d8bc05434c75e0dd94d5b
Binary files /dev/null and b/onnx/gluon-load/resources/images/9.png differ
diff --git a/onnx/gluon-load/resources/imgDir-to-h5.py b/onnx/gluon-load/resources/imgDir-to-h5.py
new file mode 100644
index 0000000000000000000000000000000000000000..f51585a2d584b9cbbe178619697ff23b3333d7e9
--- /dev/null
+++ b/onnx/gluon-load/resources/imgDir-to-h5.py
@@ -0,0 +1,89 @@
+# (c) https://github.com/MontiCore/monticore
+from __future__ import print_function
+from __future__ import division
+import h5py
+import numpy as np
+import cv2
+import os
+import argparse
+import errno
+import random
+import sys
+
+
+def create_img_list(name, data_path):
+ dir_name = data_path + "/" + name
+
+ image_paths = []
+ image_class_indices = []
+ print(dir_name)
+ for class_index_name in os.listdir(dir_name):
+ class_dir_path = dir_name + "/" + class_index_name
+ if os.path.isdir(class_dir_path):
+ for image_name in os.listdir(class_dir_path):
+ image_path = class_dir_path + "/" + image_name
+ image_paths.append(image_path)
+ class_index = float(class_index_name)
+ image_class_indices.append(class_index)
+ return image_paths, image_class_indices
+
+def create_h5_from_list(image_paths, image_class_indices, target_dir, target_file_name, input_port_name, output_port_name, shuffle=True):
+ img = cv2.imread(image_paths[0])
+ t_img = np.transpose(img, (2,0,1)).astype(np.float32)
+ #t_img = t_img[-1:,:,:]
+ #print(t_img)
+ channels = t_img.shape[0]
+ height = t_img.shape[1]
+ width = t_img.shape[2]
+ data_size = len(image_paths)
+
+ target_file = target_dir + "/" + target_file_name + ".h5"
+ if os.path.isfile(target_file):
+ print("File", target_file, "already exists. Skipping data file creation.")
+ return
+ try:
+ os.makedirs(target_dir)
+ except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise
+
+ if shuffle:
+ combined = list(zip(image_paths, image_class_indices))
+ random.shuffle(combined)
+ image_paths[:], image_class_indices[:] = zip(*combined)
+
+ print("Creating " + target_file + " (images:" + str(data_size) + ", channels:" + str(channels) + ", height:" + str(height) + ", width:" + str(width) + "):")
+ with h5py.File(target_file, "w") as ofile:
+ in_dset = ofile.create_dataset(input_port_name, (data_size,channels, height, width), dtype=np.float32)
+ out_dset = ofile.create_dataset(output_port_name + "_label", (data_size,), dtype=np.float32)
+ for i in range(data_size):
+ img = cv2.imread(image_paths[i])
+ t_img = np.transpose(img, (2,0,1)).astype(np.float32)
+ #t_img = t_img[-1:,:,:]
+ in_dset[i] = t_img
+ out_dset[i] = image_class_indices[i]
+
+ #print progress
+ if i % 100 == 0:
+ percentage = 100*i / data_size
+ sys.stdout.write("\r{:0.1f}%".format(percentage))
+ sys.stdout.flush()
+ sys.stdout.write("\r100.0%\n")
+ sys.stdout.flush()
+
+
+
+if __name__ == "__main__":
+ parser = argparse.ArgumentParser(description='Translate image directories into hdf5 training sets for EMADL.')
+ parser.add_argument("--in_port", action="store", dest="in_port", default="data")
+ parser.add_argument("--out_port", action="store", dest="out_port", default="softmax")
+ parser.add_argument("--data_path", action="store", dest="data_path", default=".")
+ parser.add_argument("--target_path", action="store", dest="target_path", default=".")
+ args = parser.parse_args()
+ for file_name in os.listdir(args.data_path):
+ if file_name == "train":
+ image_paths, image_class_indices = create_img_list(file_name, args.data_path)
+ create_h5_from_list(image_paths, image_class_indices, args.target_path, file_name, args.in_port, args.out_port)
+ if file_name == "test":
+ image_paths, image_class_indices = create_img_list(file_name, args.data_path)
+ create_h5_from_list(image_paths, image_class_indices, args.target_path, file_name, args.in_port, args.out_port)
diff --git a/onnx/gluon-load/resources/training_data/test.h5 b/onnx/gluon-load/resources/training_data/test.h5
new file mode 100644
index 0000000000000000000000000000000000000000..2441fa8a99e54e8d3a7ba06ecde5521997399c0b
Binary files /dev/null and b/onnx/gluon-load/resources/training_data/test.h5 differ
diff --git a/onnx/gluon-load/resources/training_data/train.h5 b/onnx/gluon-load/resources/training_data/train.h5
new file mode 100644
index 0000000000000000000000000000000000000000..d525ad53f03d0cd84a14ad177215fc64b8c3b667
Binary files /dev/null and b/onnx/gluon-load/resources/training_data/train.h5 differ
diff --git a/onnx/gluon-load/settings.xml b/onnx/gluon-load/settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cfe7735c7b26edfb1c0a15130da3e22e1759b4c5
--- /dev/null
+++ b/onnx/gluon-load/settings.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+ org.mortbay.jetty
+ de.topobyte
+
+
+
+
+
+
+
+ se-nexus
+ cibuild
+ ${env.cibuild}
+
+
+
+ github
+ travisbuilduser
+ ${env.travisbuilduserpassword}
+
+
+
+ gitlab-maven
+
+
+
+ Deploy-Token
+ KJkmCZosey-A8XBES2Fy
+
+
+
+
+
+
+
+
+
+
+
+ sonar
+
+ true
+
+
+
+
+ https://metric.se.rwth-aachen.de
+
+
+ jenkins
+
+
+ ${env.sonar}
+
+
+
+
+
+ se-nexus
+
+
+ central
+ https://repo1.maven.org/maven2/
+
+
+
+
+
+
+
+
+ nexus
+ https://nexus.se.rwth-aachen.de/content/groups/public
+
+ true
+
+
+ true
+
+
+
+ gitlab-maven
+ https://git.rwth-aachen.de/api/v4/projects/57999/packages/maven
+
+
+
+
+ jena
+ https://bio.informatik.uni-jena.de/repository/libs-release-oss
+
+
+
+
+
+
+
+
+ eclipse
+ https://repo.eclipse.org/content/groups/releases/
+
+ true
+
+
+ true
+
+
+
+ jcenter
+ https://jcenter.bintray.com/
+
+ true
+
+
+ true
+
+
+
+
+ topobyte
+ http://mvn.topobyte.de/
+
+ true
+
+
+ true
+
+
+
+
+ spring
+ https://repo.spring.io/libs-release/
+
+ true
+
+
+ true
+
+
+
+
+ rosjava_mvn
+ Public Rosjava repository
+ https://github.com/rosjava/rosjava_mvn_repo
+
+
+
+ icm
+ icm
+ http://maven.icm.edu.pl/artifactory/repo/
+
+
+
+
+
+
+ central
+ http://central
+
+
+
+
+
+
+
+
+ nexus
+ https://nexus.se.rwth-aachen.de/content/groups/public
+
+ true
+
+
+ true
+
+
+
+ central
+ https://repo1.maven.org/maven2
+
+ true
+
+
+ true
+
+
+
+ eclipse
+ https://repo.eclipse.org/content/groups/releases/
+
+ true
+
+
+ true
+
+
+
+ jcenter
+ https://jcenter.bintray.com/
+
+ true
+
+
+ true
+
+
+
+
+ topobyte
+ http://mvn.topobyte.de/
+
+ true
+
+
+ true
+
+
+
+ jena
+ https://bio.informatik.uni-jena.de/repository/libs-release-oss
+
+
+
+
+
+
+
+
+
+
+
+
+
+ se-nexus
+
+
diff --git a/onnx/gluon-load/src/cpp/CMakeLists.txt b/onnx/gluon-load/src/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f8bdb5d96acde4b5ab5f22e5925b3c3fbf365d35
--- /dev/null
+++ b/onnx/gluon-load/src/cpp/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.5)
+project(DigitCalculator CXX)
+set(CMAKE_CXX_STANDARD 11)
+
+option(MXNET_PATH "Path to libmxnet.so")
+
+
+add_executable(DigitCalculator DigitCalculator.cpp)
+
+set_target_properties(DigitCalculator PROPERTIES LINKER_LANGUAGE CXX)
+find_package(OpenCV REQUIRED)
+target_link_libraries(DigitCalculator ${MXNET_PATH})
+set(INCLUDE_DIRS ${INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})
+set(LIBS ${LIBS} ${OpenCV_LIBS})
+target_link_libraries(DigitCalculator cNNCalculator_connector ${LIBS} -lblas -lopenblas)
+target_include_directories(DigitCalculator PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
+export(TARGETS DigitCalculator FILE DigitCalculator.cmake)
diff --git a/onnx/gluon-load/src/cpp/DigitCalculator.cpp b/onnx/gluon-load/src/cpp/DigitCalculator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01fa60d1e2b1923a7d1b9c09899bb2625f2c43ef
--- /dev/null
+++ b/onnx/gluon-load/src/cpp/DigitCalculator.cpp
@@ -0,0 +1,73 @@
+/* (c) https://github.com/MontiCore/monticore */
+#include "CNNTranslator.h"
+#include "cNNCalculator_connector.h"
+#include
+#include
+#include
+
+#include
+#include //Check if it can be removed
+#include
+#include