Commit 3d7cb11c authored by Evgeny Kusmenko's avatar Evgeny Kusmenko
Browse files

Merge branch 'ba_kisov' into 'master'

Ba kisov

See merge request !52
parents 690d6a5a a6a0e4e4
Pipeline #466559 failed with stage
in 1 minute and 4 seconds
......@@ -71,7 +71,7 @@ integrationGluonJobLinux:
stage: linux
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet150:v0.0.5
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B -U clean install --settings settings.xml -Dtest=IntegrationGluonTest
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B -U clean install --settings settings.xml -Dtest=IntegrationGluonTest
except:
changes:
- .gitlab-ci.yml
......
......@@ -9,7 +9,7 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-emadl-generator</artifactId>
<version>0.4.9-SNAPSHOT</version>
<version>0.5.0-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
......@@ -19,6 +19,7 @@
<emadl.version>0.4.5-SNAPSHOT</emadl.version>
<CNNTrain.version>0.4.4-SNAPSHOT</CNNTrain.version>
<CNNArch.version>0.4.6-SNAPSHOT</CNNArch.version>
<cnnarch-generator.version>0.4.7-SNAPSHOT</cnnarch-generator.version>
<cnnarch-mxnet-generator.version>0.4.6</cnnarch-mxnet-generator.version>
<cnnarch-caffe2-generator.version>0.4.6</cnnarch-caffe2-generator.version>
......@@ -99,6 +100,12 @@
<version>${CNNTrain.version}</version>
</dependency>
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnn-arch</artifactId>
<version>${CNNArch.version}</version>
</dependency>
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-deeplearning</artifactId>
......
......@@ -6,6 +6,7 @@ import de.monticore.io.paths.ModelPath;
import de.monticore.lang.embeddedmontiarc.LogConfig;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarcmath._symboltable.EmbeddedMontiArcMathLanguage;
import de.monticore.lang.embeddedmontiarc.helper.ConstantPortHelper;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.emadl._symboltable.EMADLLanguage;
import de.monticore.lang.monticar.emadl.tagging.artifacttag.DatasetArtifactTagSchema;
import de.monticore.lang.monticar.emadl.tagging.artifacttag.LayerArtifactParameterTagSchema;
......@@ -26,14 +27,35 @@ import de.monticore.lang.monticar.struct._symboltable.StructLanguage;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.monticore.symboltable.GlobalScope;
import de.monticore.symboltable.Scope;
import de.monticore.symboltable.CommonSymbolTableCreator;
import org.apache.commons.lang3.SystemUtils;
import javax.print.AttributeException;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.*;
import java.io.*;
public class EMADLAbstractSymtab {
public EMADLAbstractSymtab() {
}
public static TaggingResolver createSymTabAndTaggingResolver(String customFilesPath, Backend backend, String... modelPath) {
Scope scope = createSymTab(customFilesPath, backend, modelPath);
TaggingResolver tagging = new TaggingResolver(scope, Arrays.asList(modelPath));
TagMinMaxTagSchema.registerTagTypes(tagging);
TagTableTagSchema.registerTagTypes(tagging);
TagBreakpointsTagSchema.registerTagTypes(tagging);
TagExecutionOrderTagSchema.registerTagTypes(tagging);
TagInitTagSchema.registerTagTypes(tagging);
TagThresholdTagSchema.registerTagTypes(tagging);
TagDelayTagSchema.registerTagTypes(tagging);
DataPathTagSchema.registerTagTypes(tagging);
LayerPathParameterTagSchema.registerTagTypes(tagging);
return tagging;
}
public static TaggingResolver createSymTabAndTaggingResolver(String... modelPath) {
Scope scope = createSymTab(modelPath);
TaggingResolver tagging = new TaggingResolver(scope, Arrays.asList(modelPath));
......@@ -51,11 +73,36 @@ public class EMADLAbstractSymtab {
return tagging;
}
public static Scope createSymTab(String customFilesPath, Backend backend, String... modelPath) {
ConstantPortHelper.resetLastID();
MathConverter.resetIDs();
ThreadingOptimizer.resetID();
ModelingLanguageFamily fam = new ModelingLanguageFamily();
EMADLLanguage montiArcLanguage = new EMADLLanguage(customFilesPath, backend.getBackendString(backend).toLowerCase());
fam.addModelingLanguage(montiArcLanguage);
fam.addModelingLanguage(new EmbeddedMontiArcMathLanguage());
fam.addModelingLanguage(new StreamUnitsLanguage());
fam.addModelingLanguage(new StructLanguage());
fam.addModelingLanguage(new EnumLangLanguage());
final ModelPath mp = new ModelPath();
for (String m : modelPath) {
mp.addEntry(Paths.get(m));
}
LogConfig.init();//TODO comment for debug output
GlobalScope scope = new GlobalScope(mp, fam);
de.monticore.lang.monticar.Utils.addBuiltInTypes(scope);
return scope;
}
public static Scope createSymTab(String... modelPath) {
ConstantPortHelper.resetLastID();
MathConverter.resetIDs();
ThreadingOptimizer.resetID();
ModelingLanguageFamily fam = new ModelingLanguageFamily();
EMADLLanguage montiArcLanguage = new EMADLLanguage();
fam.addModelingLanguage(montiArcLanguage);
......@@ -72,4 +119,5 @@ public class EMADLAbstractSymtab {
de.monticore.lang.monticar.Utils.addBuiltInTypes(scope);
return scope;
}
}
......@@ -74,6 +74,7 @@ public class EMADLGenerator implements EMAMGenerator {
private Backend backend;
private String modelsPath;
private String customFilesPath = "";
private Map<String, ArchitectureSymbol> processedArchitecture;
......@@ -101,6 +102,18 @@ public class EMADLGenerator implements EMAMGenerator {
}
}
public String getCustomFilesPath() { return customFilesPath; }
public void setCustomFilesPath(String customPythonFilesPath) {
if (!(customPythonFilesPath.endsWith("/"))){
this.customFilesPath = customPythonFilesPath + "/";
}
else {
this.customFilesPath = customPythonFilesPath;
}
}
public void setGenerationTargetPath(String generationTargetPath){
if (!(generationTargetPath.substring(generationTargetPath.length() - 1).equals("/"))){
getEmamGen().setGenerationTargetPath(generationTargetPath + "/");
......@@ -137,7 +150,7 @@ public class EMADLGenerator implements EMAMGenerator {
private TaggingResolver getSymTabAndTaggingResolver() {
BasicLibrary.extract();
return EMADLAbstractSymtab.createSymTabAndTaggingResolver(getModelsPath(),
return EMADLAbstractSymtab.createSymTabAndTaggingResolver(getCustomFilesPath(), this.backend, getModelsPath(),
Constants.SYNTHESIZED_COMPONENTS_ROOT, BasicLibrary.BASIC_LIBRARY_ROOT);
}
......@@ -713,6 +726,9 @@ public class EMADLGenerator implements EMAMGenerator {
architecture.get().setWeightsPath(wPath);
architecture.get().processLayerPathParameterTags(layerPathParameterTags);
architecture.get().setComponentName(EMAComponentSymbol.getFullName());
if(!getCustomFilesPath().equals("")) {
architecture.get().setCustomPyFilesPath(getCustomFilesPath() + "python/" + Backend.getBackendString(this.backend).toLowerCase());
}
generateCNN(fileContents, taggingResolver, componentInstanceSymbol, architecture.get());
if (processedArchitecture != null) {
processedArchitecture.put(architecture.get().getComponentName(), architecture.get());
......
......@@ -52,6 +52,12 @@ public class EMADLGeneratorCli {
.required(false)
.build();
public static final Option OPTION_CUSTOM_FILES_PATH = Option.builder("cfp")
.longOpt("custom-files-path")
.desc("full path to directory with language folders with custom files C::\\Users\\vpupkin\\prok\\My>AwsomeAutopilot\\src")
.hasArg(true)
.required(false)
.build();
public static final Option OPTION_HELP = Option.builder("h")
.longOpt("help")
.desc("Show CLI parameters")
......@@ -86,6 +92,7 @@ public class EMADLGeneratorCli {
options.addOption(OPTION_RESTRAINED_TRAINING);
options.addOption(OPTION_TRAINING_PYTHON_PATH);
options.addOption(OPTION_COMPILE);
options.addOption(OPTION_CUSTOM_FILES_PATH);
options.addOption(OPTION_HELP);
}
......@@ -167,6 +174,9 @@ public class EMADLGeneratorCli {
// EMAM2CPP options
GeneratorCPP emamGen = generator.getEmamGen();
Path modelsDirPath = Paths.get(cliArgs.getOptionValue(OPTION_MODELS_PATH.getOpt()));
if (cliArgs.hasOption(OPTION_CUSTOM_FILES_PATH.getOpt())) {
generator.setCustomFilesPath(cliArgs.getOptionValue(OPTION_CUSTOM_FILES_PATH.getOpt()));
}
emamGen.setUseAlgebraicOptimizations(false);
emamGen.setUseThreadingOptimization(false);
emamGen.setModelsDirPath(modelsDirPath);
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.emadl;
import de.monticore.lang.monticar.emadl.generator.Backend;
import de.monticore.lang.monticar.emadl.generator.EMADLAbstractSymtab;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.se_rwth.commons.logging.Log;
import org.junit.Assert;
import javax.swing.text.html.HTML;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
......@@ -22,6 +24,10 @@ public class AbstractSymtabTest {
return EMADLAbstractSymtab.createSymTabAndTaggingResolver(modelPath);
}
protected static TaggingResolver createSymTab(String customFilesPath, Backend backend, String... modelPath){
return EMADLAbstractSymtab.createSymTabAndTaggingResolver(customFilesPath, backend, modelPath);
}
public static void checkFilesAreEqual(Path generationPath, Path resultsPath, List<String> fileNames) {
for (String fileName : fileNames){
File genFile = new File(generationPath.toString() + "/" + fileName);
......
package de.monticore.lang.monticar.emadl;
import de.monticore.lang.monticar.emadl.generator.EMADLGeneratorCli;
import de.se_rwth.commons.logging.Log;
import org.junit.Test;
import java.util.NoSuchElementException;
import static org.junit.Assert.assertEquals;
public class CustomLayerTest {
@Test(expected = NoSuchElementException.class)
public void NegativeCustomLayerTest (){
Log.getFindings().clear();
String[] args = {"-m", "src/test/resources/models/customMNISTCalculator", "-r", "cNNCalculator.Connector", "-b", "GLUON", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
}
}
......@@ -408,4 +408,19 @@ public class GenerationTest extends AbstractSymtabTest {
"n", "-c", "n" };
EMADLGeneratorCli.main(args);
}
@Test
public void testMnistCalculatorWithCustomLayerForGluon() throws IOException, TemplateException {
Log.getFindings().clear();
String[] args = {"-m", "src/test/resources/models/customMNISTCalculator", "-r", "cNNCalculator.Connector", "-b", "GLUON", "-cfp", "src/test/resources/custom_files", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
checkFindingsCount();
checkFilesAreEqual(
Paths.get("./target/generated-sources-emadl"),
Paths.get("./src/test/resources/target_code/gluon/customMNISTCalculator"),
Arrays.asList(
"CNNNet_cNNCalculator_connector_predictor1.py",
"CNNCreator_cNNCalculator_connector_predictor1.py",
"CNNTrainer_cNNCalculator_connector_predictor1.py"));
}
}
......@@ -4,12 +4,14 @@ package de.monticore.lang.monticar.emadl;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.cncModel.EMAComponentSymbol;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.emadl._parser.EMADLParser;
import de.monticore.lang.monticar.emadl.generator.Backend;
import de.monticore.symboltable.Scope;
import de.se_rwth.commons.logging.Log;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class SymtabTest extends AbstractSymtabTest {
......@@ -35,5 +37,11 @@ public class SymtabTest extends AbstractSymtabTest {
assertNotNull(a);
}
@Test
public void testCustomMNISTCalculator(){
Scope symTab = createSymTab("src/test/resources/custom_files", Backend.GLUON, "src/test/resources/models/customMNISTCalculator");
EMAComponentSymbol a = symTab.<EMAComponentSymbol>resolve("cNNCalculator.Connector", EMAComponentSymbol.KIND).orElse(null);
assertNotNull(a);
}
}
......@@ -122,6 +122,18 @@ public class IntegrationGluonTest extends IntegrationTest {
checkFindingsCount();
}
@Test
public void testMNISTCalculatorWithCustomLayer() {
Log.getFindings().clear();
deleteHashFile(Paths.get("./target/generated-sources-emadl/cNNCalculator/Network.training_hash"));
String[] args = {"-m", "src/test/resources/models/customMNISTCalculator", "-r", "cNNCalculator.Connector", "-b", "GLUON", "-cfp", "src/test/resources/custom_files"};
EMADLGeneratorCli.main(args);
checkFindingsCount(5);
}
private void deleteHashFile(Path hashFile) {
try {
Files.delete(hashFile);
......
import mxnet as mx
from mxnet import gluon, util
class MyELU(gluon.HybridBlock):
def __init__(self, alpha=1.0, **kwargs):
super(MyELU, self).__init__(**kwargs)
self._alpha = alpha
# A method to return a dictionary with
# the parameters of the layer as keys and their data type as value (parameters - string, types - data type objects)
def get_parameters(self):
return {'alpha': int}
# A method to print a dictionary with
# the parameters of the layer as keys and their data type as value (both should be strings)
def print_parameters(self):
print({'alpha': 'int'})
# A method which gets the output dimensions of the previous layer as array of 3-element tuples and computes
# the output dimensions of this layer and print a 5-element tuple with the output dimensions and
# min max value in the form (channel1, height1, width1, min1, max1), (channels2, ...)
# input_dimension_array = [(channels1, height1, width1), (channels2, height2, width2), ...]
def compute_output_types(self, alpha, input_dimension_array):
channels1 = input_dimension_array[0][0]
height1 = input_dimension_array[0][1]
width1 = input_dimension_array[0][2]
min1 = 0
max1 = 'oo'
print([(channels1, height1, width1, min1, max1)])
# How compute output function looks like if the class was predefined activation layer :
# .channels(layer.getInputTypes().get(0).getChannels())
# .height(layer.getInputTypes().get(0).getHeight())
# .width(layer.getInputTypes().get(0).getWidth())
# .elementType("0", "oo");
def hybrid_forward(self, F, x):
leaky_relu = F.npx.leaky_relu if False else F.LeakyReLU
return leaky_relu(x, act_type='elu', slope=self._alpha)
from os.path import dirname, basename, isfile, join
import glob
modules = glob.glob(join(dirname(__file__), "*.py"))
__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
\ No newline at end of file
/* (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;
}
}
/* (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) ->
MyELU(alpha=1) ->
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) ->
MyELU(alpha=1) ->
Dropout() ->
FullyConnected(units=classes) ->
Softmax() ->
softmax ->
softmax;
}
}
/* (c) https://github.com/MontiCore/monticore */
configuration VGG16{
num_epoch:1
batch_size:64
normalize:true
load_checkpoint:false
optimizer:adam{
learning_rate:0.01
learning_rate_decay:0.8
step_size:1000
weight_decay: 0.01
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment