Commit 28e8f373 authored by Evgeny Kusmenko's avatar Evgeny Kusmenko

Merge branch 'use_streamtest' into 'master'

Use streamtest

See merge request !11
parents 5f85b2ae 62924b55
Pipeline #276491 failed with stage
in 23 minutes and 20 seconds
......@@ -44,3 +44,10 @@ TestTENSORFLOW:
- 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;"
TestMnistCalculator-II:
stage: linux
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/applications/mnistcalculator/mxnet:v0.0.3
script:
- cd mnist-calculator
- mvn streamtest:streamtest-build -s settings.xml
train.log
target/
.idea
model/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.monticore.lang.monticar.application</groupId>
<artifactId>mnist-calculator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<!-- .. SE-Libraries .................................................. -->
<streamtest.version>0.0.11-SNAPSHOT</streamtest.version>
<!-- .. Misc .......................................................... -->
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<dependency>
<groupId>de.monticore.lang.monticar.utilities</groupId>
<artifactId>maven-streamtest</artifactId>
<version>0.0.14-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mnist-calculator</artifactId>
<version>0.0.1-SNAPSHOT</version>
<classifier>training-weight</classifier>
<type>jar</type>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-shared-resources</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>generate-resources</phase>
<configuration>
<outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
<includeArtifacIds>mnist-calculator</includeArtifacIds>
<includeGroupIds>${project.groupId}</includeGroupIds>
<excludeTransitive>true</excludeTransitive>
<!--use as much as needed to be specific...also scope,type,classifier etc-->
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>de.monticore.lang.monticar.utilities</groupId>
<artifactId>maven-streamtest</artifactId>
<version>0.0.14-SNAPSHOT</version>
<configuration>
<pathMain>./src/main/ema/emadl/models</pathMain>
<pathTest>./src/main/ema/emadl/models</pathTest>
<pathTmpOut>./target/tmp</pathTmpOut>
<runStreamTestBefore>false</runStreamTestBefore>
<generator>MinGW</generator>
<backend>GLUON</backend>
<trainingNeeded>true</trainingNeeded>
<rootModel>cNNCalculator.Connector</rootModel>
</configuration>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>streamtest-build</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.4</version>
<configuration>
<descriptor>src/main/assembly/weight-assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>training-data</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<finalName>${project.artifactId}-${project.version}</finalName>
<formats>
<format>jar</format>
</formats>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<distributionManagement>
<repository>
<id>se-nexus</id>
<url>https://nexus.se.rwth-aachen.de/content/repositories/embeddedmontiarc-releases/</url>
</repository>
<snapshotRepository>
<id>se-nexus</id>
<url>https://nexus.se.rwth-aachen.de/content/repositories/embeddedmontiarc-snapshots/</url>
</snapshotRepository>
</distributionManagement>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<!-- (c) https://github.com/MontiCore/monticore -->
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<pluginGroups>
<pluginGroup>org.mortbay.jetty</pluginGroup>
<pluginGroup>de.topobyte</pluginGroup>
</pluginGroups>
<proxies>
</proxies>
<servers>
<server>
<id>se-nexus</id>
<username>cibuild</username>
<password>${env.cibuild}</password>
</server>
</servers>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- Optional URL to server. Default value is http://localhost:9000 -->
<sonar.host.url>
https://metric.se.rwth-aachen.de
</sonar.host.url>
<sonar.login>
jenkins
</sonar.login>
<sonar.password>
${env.sonar}
</sonar.password>
</properties>
</profile>
<profile>
<id>se-nexus</id>
<repositories>
<repository>
<id>se-nexus</id>
<url>https://nexus.se.rwth-aachen.de/content/groups/public</url>
<releases><enabled>true</enabled> </releases>
<snapshots><enabled>true</enabled> </snapshots>
</repository>
<repository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2/</url>
<releases><enabled /></releases>
<snapshots><enabled /></snapshots>
</repository>
<repository>
<id>icm</id>
<url>http://maven.icm.edu.pl/artifactory/repo/</url>
<releases><enabled /></releases>
<snapshots><enabled /></snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>central</id>
<url>https://repo.maven.apache.org/maven2/</url>
<releases><enabled /></releases>
<snapshots><enabled /></snapshots>
</pluginRepository>
<pluginRepository>
<id>se-nexus</id>
<url>https://nexus.se.rwth-aachen.de/content/groups/public</url>
<releases><enabled>true</enabled> </releases>
<snapshots><enabled>true</enabled> </snapshots>
</pluginRepository>
<pluginRepository>
<id>icm</id>
<url>http://maven.icm.edu.pl/artifactory/repo/</url>
<releases><enabled /></releases>
<snapshots><enabled /></snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>se-nexus</activeProfile>
</activeProfiles>
</settings>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>training-weight</id>
<includeBaseDirectory>false</includeBaseDirectory>
<includeSiteDirectory>false</includeSiteDirectory>
<fileSets>
<fileSet>
<directory>src/main/resources/training_data</directory>
<includes>
<include>**/*.h5</include>
</includes>
</fileSet>
</fileSets>
</assembly>
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)
/* (c) https://github.com/MontiCore/monticore */
#include "CNNTranslator.h"
#include "cNNCalculator_connector.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <armadillo>
#include <string> //Check if it can be removed
#include <iostream>
#include <map>
int main(int argc, char* argv[]) {
if(argc < 7){ //Note: argc=1 if no arguments are provided
std::cout << "Missing argument: Path to 6 test images must be provided " << std::endl;
exit(1);
}
cNNCalculator_connector connector;
connector.init();
for(int n = 0; n < 6; n++) {
std::string filePath = argv[n+1];
if (!std::ifstream(filePath).good()) {
std::cerr << "Image loading failure, test image '" << filePath << "' does not exist." << std::endl;
exit(1);
}
cv::Mat img = cv::imread(filePath);
std::cout << "== original image size: " << img.size() << " ==" << std::endl;
// scale image to fit
cv::Size scale(28,28);
cv::resize(img, img, scale);
std::cout << "== simply resize: " << img.size() << " ==" << std::endl;
size_t channels = 1;
size_t height = img.rows;
size_t width = img.cols;
vector<float> data(channels*height*width);
for(size_t j=0; j<height; j++){
for(size_t k=0; k<width; k++){
cv::Vec3b intensity = img.at<cv::Vec3b>(j, k);
for(size_t i=0; i<channels; i++){
data[i*height*width + j*height + k] = (float) intensity[i];
}
}
}
if(n == 0)
connector.image1 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
if(n == 1)
connector.image2 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
if(n == 2)
connector.image3 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
if(n == 3)
connector.image4 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
if(n == 4)
connector.image5 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
if(n == 5)
connector.image6 = conv_to< icube >::from( CNNTranslator::translateToCube(data, vector<size_t> {channels,height,width}) );
}
connector.execute();
int classIndex = (int)connector.res;
std::cout << "== SUM: " << classIndex << std::endl;
return 0;
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component Add{
ports
in Z(0:999) num1,
in Z(0:999) num2,
out Z(0:1998) sum;
implementation Math{
sum = num1 + num2;
}
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component ArgMax<Z(1:oo) n = 2>{
ports in Q^{n} inputVector,
out Z(0:oo) maxIndex,
out Q maxValue;
implementation Math{
maxIndex = 0;
maxValue = inputVector(1);
for i = 2:n
if inputVector(i) > maxValue
maxIndex = i - 1;
maxValue = inputVector(i);
end
end
}
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component Calculator {
ports
in Q(0:1)^10 in1_1,
in Q(0:1)^10 in1_2,
in Q(0:1)^10 in1_3,
in Q(0:1)^10 in2_1,
in Q(0:1)^10 in2_2,
in Q(0:1)^10 in2_3,
out Z(0:1998) out1;
instance ArgMax<10> number1_ones;
instance ArgMax<10> number1_tens;
instance ArgMax<10> number1_hundreds;
instance ArgMax<10> number2_ones;
instance ArgMax<10> number2_tens;
instance ArgMax<10> number2_hundreds;
instance DigitCombiner number1;
instance DigitCombiner number2;
instance Add add;
connect in1_1 -> number1_hundreds.inputVector;
connect in1_2 -> number1_tens.inputVector;
connect in1_3 -> number1_ones.inputVector;
connect in2_1 -> number2_hundreds.inputVector;
connect in2_2 -> number2_tens.inputVector;
connect in2_3 -> number2_ones.inputVector;
connect number1_ones.maxIndex -> number1.ones;
connect number1_tens.maxIndex -> number1.tens;
connect number1_hundreds.maxIndex -> number1.hundreds;
connect number2_ones.maxIndex -> number2.ones;
connect number2_tens.maxIndex -> number2.tens;
connect number2_hundreds.maxIndex -> number2.hundreds;
connect number1.number -> add.num1;
connect number2.number -> add.num2;
connect add.sum -> out1;
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component Connector {
ports in Z(0:255)^{1, 28, 28} image1,
in Z(0:255)^{1, 28, 28} image2,
in Z(0:255)^{1, 28, 28} image3,
in Z(0:255)^{1, 28, 28} image4,
in Z(0:255)^{1, 28, 28} image5,
in Z(0:255)^{1, 28, 28} image6,
out Z(0:1998) res;
instance Network<10> predictor1;
instance Network<10> predictor2;
instance Network<10> predictor3;
instance Network<10> predictor4;
instance Network<10> predictor5;
instance Network<10> predictor6;
instance Calculator cal;
connect image1 -> predictor1.data;
connect image2 -> predictor2.data;
connect image3 -> predictor3.data;
connect image4 -> predictor4.data;
connect image5 -> predictor5.data;
connect image6 -> predictor6.data;
connect predictor1.softmax -> cal.in1_1;
connect predictor2.softmax -> cal.in1_2;
connect predictor3.softmax -> cal.in1_3;
connect predictor4.softmax -> cal.in2_1;
connect predictor5.softmax -> cal.in2_2;
connect predictor6.softmax -> cal.in2_3;
connect cal.out1 -> res;
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component DigitCombiner{
ports
in Z(0:9) hundreds,
in Z(0:9) tens,
in Z(0:9) ones,
out Z(0:999) number;
implementation Math{
number = ones + 10 * tens + 100 * hundreds;
}
}
package cNNCalculator;
stream DigitCombinerTest for DigitCombiner{
// Input
hundreds: 1;
tens: 1;
ones: 1;
// Output
// - means: all values are allowed
// 100 +/- 1 means: all values from 99 to 101 are allowed
number: 111;
}
/* (c) https://github.com/MontiCore/monticore */
configuration Network{
num_epoch:1
batch_size:10
normalize:false
context:cpu
load_checkpoint:false
optimizer:sgd{
learning_rate:0.1
learning_rate_decay:0.85
step_size:1000
weight_decay:0.0
}
}
/* (c) https://github.com/MontiCore/monticore */
package cNNCalculator;
component Network<Z(2:oo) classes = 10>{
ports in Z(0:255)^{1, 28, 28} data,
out Q(0:1)^{classes} softmax;
implementation CNN {
def conv(channels, kernel=1, stride=1){
Convolution(kernel=(kernel,kernel),channels=channels) ->
Relu() ->
Pooling(pool_type="max", kernel=(2,2), stride=(stride,stride))
}
data ->
conv(kernel=5, channels=20, stride=2) ->
conv(kernel=5, channels=50, stride=2) ->
FullyConnected(units=500) ->
Relu() ->
Dropout() ->
FullyConnected(units=classes) ->
Softmax() ->
softmax;
}
}
cNNCalculator.Network src/main/resources/training_data
FROM registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/integrationtests/mxnet:v0.0.3
RUN pip install opencv-python
# Install Open CV - Warning, this takes absolutely forever
RUN apt-get update && apt-get install -y libgdal-dev
RUN mkdir -p ~/opencv cd ~/opencv && \
wget https://github.com/Itseez/opencv/archive/3.0.0.zip && \
unzip 3.0.0.zip && \
rm 3.0.0.zip && \
mv opencv-3.0.0 OpenCV
RUN apt-get install -y qtbase5-dev
RUN apt-get install -y build-essential
ENV PATH="${PATH}:/usr/include/"
RUN cd OpenCV && \
mkdir build && \
cd build && \
cmake \
-DWITH_QT=ON \
-DWITH_OPENGL=ON \
-DFORCE_VTK=ON \
-DWITH_TBB=ON \
-DWITH_GDAL=ON \
-DWITH_XINE=ON \
-DBUILD_EXAMPLES=ON \
-D ENABLE_PRECOMPILED_HEADERS=OFF ..
RUN cd OpenCV/build && make -j4
RUN cd OpenCV/build && make install
RUN cd OpenCV/build && ldconfig
RUN apt-get install -y libopenblas-dev