Commit 50fc840b authored by Christian Fuß's avatar Christian Fuß
Browse files

merged develop into rnn

parents 6770c3e0 afb3db82
Pipeline #173105 failed with stages
......@@ -30,7 +30,7 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnn-arch</artifactId>
<version>0.3.2-SNAPSHOT</version>
<version>0.3.3-SNAPSHOT</version>
......
......@@ -25,10 +25,6 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
parameters:(LayerParameter || ",")* ")" "{"
body:Stream "}";
UnrollDeclaration = "unroll" "<" timeParameter:LayerParameter ">"
Name "(" parameters:(LayerParameter || ",")* ")"
"{" body:Stream "}";
IODeclaration = "def"
(in:"input" | out:"output")
type:ArchType
......@@ -60,17 +56,19 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
Architecture = methodDeclaration:LayerDeclaration*
instructions:(Instruction || ";")+ ";";
interface Instruction;
Instruction = (LayerVariableDeclaration | Stream | Unroll);
LayerVariableDeclaration = "layer" Layer Name;
Stream implements Instruction = elements:(ArchitectureElement || "->")+;
Stream = elements:(ArchitectureElement || "->")+;
Unroll implements Instruction = "timed" "<" timeParameter:ArchitectureParameter ">"
Unroll = "timed" "<" timeParameter:ArchitectureParameter ">"
Name "(" arguments:(ArchArgument || ",")* ")"
"{" body:Stream "}";
interface ArchitectureElement;
IOElement implements ArchitectureElement = Name ("[" index:ArchSimpleExpression "]")?;
Variable implements ArchitectureElement = Name ("." (member:"output" | member:Name))? ("[" index:ArchSimpleExpression "]")?;
Constant implements ArchitectureElement = ArchSimpleExpression;
......@@ -86,11 +84,11 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
/* ====== Variables/Arguments ======*/
interface Variable;
interface ArchParameter;
ArchitectureParameter implements Variable = Name ("=" default:ArchSimpleExpression)? ;
ArchitectureParameter implements ArchParameter = Name ("=" default:ArchSimpleExpression)? ;
LayerParameter implements Variable = Name ("=" default:ArchSimpleExpression)? ;
LayerParameter implements ArchParameter = Name ("=" default:ArchSimpleExpression)? ;
interface ArchArgument;
......@@ -119,7 +117,7 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
(serial2:"->" | parallel2:"|")
end:ArchSimpleExpression "]";
/**
Expressions for variable values.
Expressions for parameter and variable values.
*/
ArchSimpleExpression = (arithmeticExpression:ArchArithmeticExpression
| booleanExpression:ArchBooleanExpression
......@@ -168,7 +166,7 @@ grammar CNNArch extends de.monticore.CommonExpressions, de.monticore.lang.Math,
/* =================================*/
/* ============ ASTRULES ===========*/
/* =================================*/
ast Variable = method String getName(){};
ast ArchParameter = method String getName(){};
ast ArchSpecialArgument = method public String getName(){return "";}; //Override is necessary
ast ArchArgument = method String getName(){}
method ASTArchExpression getRhs(){};
......
......@@ -67,13 +67,17 @@ public class CNNArchCocos {
.addCoCo(new CheckElementInputs())
.addCoCo(new CheckIOAccessAndIOMissing())
.addCoCo(new CheckArchitectureFinished())
.addCoCo(new CheckNetworkStreamMissing());
.addCoCo(new CheckNetworkStreamMissing())
.addCoCo(new CheckVariableMember())
.addCoCo(new CheckLayerVariableDeclarationLayerType())
.addCoCo(new CheckLayerVariableDeclarationIsUsed());
}
//checks cocos based on symbols before the resolve method of the ArchitectureSymbol is called
public static CNNArchSymbolCoCoChecker createCNNArchPreResolveSymbolChecker() {
return new CNNArchSymbolCoCoChecker()
.addCoCo(new CheckIOName())
.addCoCo(new CheckVariableDeclarationName())
.addCoCo(new CheckVariableName())
.addCoCo(new CheckExpressions());
}
......@@ -82,7 +86,7 @@ public class CNNArchCocos {
return new CNNArchCoCoChecker()
.addCoCo(new CheckLayer())
.addCoCo(new CheckRangeOperators())
.addCoCo(new CheckVariableName())
.addCoCo(new CheckParameterName())
.addCoCo(new CheckLayerName())
.addCoCo(new CheckArgument())
.addCoCo(new CheckLayerRecursion());
......
......@@ -45,8 +45,8 @@ public class CNNArchSymbolCoCo {
else if (sym instanceof ArchTypeSymbol){
check((ArchTypeSymbol) sym);
}
else if (sym instanceof VariableSymbol){
check((VariableSymbol) sym);
else if (sym instanceof ParameterSymbol){
check((ParameterSymbol) sym);
}
else if (sym instanceof ArgumentSymbol){
check((ArgumentSymbol) sym);
......@@ -54,8 +54,8 @@ public class CNNArchSymbolCoCo {
else if (sym instanceof CNNArchCompilationUnitSymbol){
check((CNNArchCompilationUnitSymbol) sym);
}
else if (sym instanceof IODeclarationSymbol){
check((IODeclarationSymbol) sym);
else if (sym instanceof VariableDeclarationSymbol){
check((VariableDeclarationSymbol) sym);
}
else if (sym instanceof MathExpressionSymbol){
check((MathExpressionSymbol) sym);
......@@ -91,7 +91,7 @@ public class CNNArchSymbolCoCo {
//Override if needed
}
public void check(VariableSymbol sym){
public void check(ParameterSymbol sym){
//Override if needed
}
......@@ -103,7 +103,7 @@ public class CNNArchSymbolCoCo {
//Override if needed
}
public void check(IODeclarationSymbol sym){
public void check(VariableDeclarationSymbol sym){
//Override if needed
}
......
......@@ -36,7 +36,7 @@ public class CheckArchitectureFinished extends CNNArchSymbolCoCo {
if (!stream.getOutputTypes().isEmpty()){
Log.error("0" + ErrorCodes.UNFINISHED_ARCHITECTURE + " The architecture is not finished. " +
"There are still open streams at the end of the architecture. "
, architecture.getSourcePosition());
, stream.getSourcePosition());
}
}
for (UnrollSymbol unroll : architecture.getUnrolls()) {
......
......@@ -21,11 +21,7 @@
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchArgument;
import de.monticore.lang.monticar.cnnarch._symboltable.ArgumentSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.UnrollDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.UnrollSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
......@@ -44,7 +40,6 @@ public class CheckArgument implements CNNArchASTArchArgumentCoCo {
"Possible arguments are: " + Joiners.COMMA.join(layerDeclaration.getParameters())
, node.get_SourcePositionStart());
}
}else if(argument.getEnclosingScope().getSpanningSymbol().get() instanceof UnrollSymbol){
UnrollDeclarationSymbol layerDeclaration = argument.getUnroll().getDeclaration();
if (layerDeclaration != null && argument.getUnrollParameter() == null){
......
......@@ -24,7 +24,7 @@ import de.monticore.lang.math._symboltable.expression.MathExpressionSymbol;
import de.monticore.lang.math._symboltable.expression.MathNameExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchSimpleExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ParameterSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.helper.Utils;
import de.se_rwth.commons.logging.Log;
......@@ -47,11 +47,11 @@ public class CheckExpressions extends CNNArchSymbolCoCo {
for (MathExpressionSymbol subMathExp : Utils.createSubExpressionList(mathExpression)){
if (subMathExp instanceof MathNameExpressionSymbol){
String name = ((MathNameExpressionSymbol) subMathExp).getNameToAccess();
Collection<VariableSymbol> variableCollection = expression.getEnclosingScope().resolveMany(name, VariableSymbol.KIND);
Collection<ParameterSymbol> parameterCollection = expression.getEnclosingScope().resolveMany(name, ParameterSymbol.KIND);
if (variableCollection.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_VARIABLE_NAME + " Unknown variable name. " +
"The variable '" + name + "' does not exist. "
if (parameterCollection.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_PARAMETER_NAME + " Unknown parameter name. " +
"The parameter '" + name + "' does not exist. "
, subMathExp.getSourcePosition());
}
}
......
......@@ -22,7 +22,7 @@ package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.Joiners;
import de.se_rwth.commons.logging.Log;
......@@ -53,7 +53,7 @@ public class CheckIOAccessAndIOMissing extends CNNArchSymbolCoCo {
, ioDeclaration.getSourcePosition());
}
else {
for (IOSymbol ioElement : ioDeclaration.getConnectedElements()){
for (VariableSymbol ioElement : ioDeclaration.getConnectedElements()){
if (ioElement.getArrayAccess().isPresent()){
Log.error("0" + ErrorCodes.INVALID_ARRAY_ACCESS + " Invalid IO array access. " +
"This input or output is not an array."
......@@ -67,7 +67,7 @@ public class CheckIOAccessAndIOMissing extends CNNArchSymbolCoCo {
private void checkIOArray(IODeclarationSymbol ioDeclaration){
List<Integer> unusedIndices = IntStream.range(0, ioDeclaration.getArrayLength()).boxed().collect(Collectors.toList());
for (IOSymbol ioElement : ioDeclaration.getConnectedElements()){
for (VariableSymbol ioElement : ioDeclaration.getConnectedElements()){
if (ioElement.getArrayAccess().isPresent()){
Optional<Integer> arrayAccess = ioElement.getArrayAccess().get().getIntValue();
if (arrayAccess.isPresent() && arrayAccess.get() >= 0 && arrayAccess.get() < ioDeclaration.getArrayLength()){
......
......@@ -46,8 +46,8 @@ public class CheckIOType extends CNNArchSymbolCoCo {
"Type has to be rational or whole number.");
}
if (type.getDimensionSymbols().size() == 2 || type.getDimensionSymbols().size() > 3){
Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid dimension shape. Shape has to be either of size 1 or 3 (e.g. {number_of_channels, height, width})."
if (type.getDimensionSymbols().size() > 3){
Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid dimension shape. Shape has to be an tuple either of size 1, 2 or 3 (e.g. {number_of_channels, height, width})."
, ioDeclaration.getSourcePosition());
}
else {
......@@ -60,19 +60,6 @@ public class CheckIOType extends CNNArchSymbolCoCo {
}
}
}
if (Log.getFindings().isEmpty()){
if (ioDeclaration.isInput() && type.getChannels() != 3 && type.getChannels() != 1){
if (type.getHeight() > 1 || type.getWidth() > 1){
Log.warn("The number of channels of input '" +
ioDeclaration.getName() + "' is: " + type.getChannels() +
". Heigth: " + type.getHeight() + ". Width: " + type.getWidth() + ". " +
"This is unusual and a sign of an error. " +
"The standard data format of this language is CHW and not HWC. "
, ioDeclaration.getSourcePosition());
}
}
}
}
}
......@@ -27,7 +27,7 @@ import de.monticore.lang.monticar.cnnarch._symboltable.LayerDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.UnrollDeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.UnrollSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.VariableSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ParameterSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.Joiners;
......@@ -52,7 +52,7 @@ public class CheckLayer implements CNNArchASTLayerCoCo{
nameSet.add(name);
}
}
if(node.getSymbolOpt().get() instanceof LayerSymbol) {
LayerDeclarationSymbol layerDeclaration = ((LayerSymbol) node.getSymbolOpt().get()).getDeclaration();
if (layerDeclaration == null){
......@@ -64,7 +64,7 @@ public class CheckLayer implements CNNArchASTLayerCoCo{
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : layerDeclaration.getParameters()){
for (ParameterSymbol param : layerDeclaration.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
......@@ -90,7 +90,7 @@ public class CheckLayer implements CNNArchASTLayerCoCo{
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : unrollDeclaration.getParameters()){
for (ParameterSymbol param : unrollDeclaration.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
public class CheckLayerVariableDeclarationIsUsed extends CNNArchSymbolCoCo {
@Override
public void check(VariableDeclarationSymbol sym) {
if (sym instanceof LayerVariableDeclarationSymbol) {
LayerVariableDeclarationSymbol layerVariableDeclaration = (LayerVariableDeclarationSymbol) sym;
boolean isUsed = false;
for (SerialCompositeElementSymbol stream : layerVariableDeclaration.getLayer().getArchitecture().getStreams()) {
Collection<ArchitectureElementSymbol> elements =
stream.getSpannedScope().resolveMany(layerVariableDeclaration.getName(), ArchitectureElementSymbol.KIND);
for (ArchitectureElementSymbol element : elements) {
if (element instanceof VariableSymbol && ((VariableSymbol) element).getMember() == VariableSymbol.Member.NONE) {
isUsed = true;
break;
}
}
if (isUsed) {
break;
}
}
if (!isUsed) {
Log.error("0" + ErrorCodes.UNUSED_LAYER + " Unused layer. " +
"Declared layer variables need to be used as layer at least once.",
sym.getSourcePosition());
}
}
}
}
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
public class CheckLayerVariableDeclarationLayerType extends CNNArchSymbolCoCo {
@Override
public void check(VariableDeclarationSymbol sym) {
if (sym instanceof LayerVariableDeclarationSymbol) {
LayerVariableDeclarationSymbol layerVariableDeclaration = (LayerVariableDeclarationSymbol) sym;
// Only allow predefined layers to be declared as layer variable
if (!layerVariableDeclaration.getLayer().getDeclaration().isPredefined()) {
Log.error("0" + ErrorCodes.ILLEGAL_LAYER_USE + " Illegal layer use. " +
"Only predefined layers can be used as a type for a layer variable.",
sym.getSourcePosition());
}
}
}
}
......@@ -30,18 +30,18 @@ public class CheckNetworkStreamMissing extends CNNArchSymbolCoCo {
@Override
public void check(ArchitectureSymbol architecture) {
boolean hasNetworkStream = false;
boolean hasTrainableStream = false;
for (CompositeElementSymbol stream : architecture.getStreams()) {
hasNetworkStream |= stream.isNetwork();
hasTrainableStream |= stream.isTrainable();
}
for (UnrollSymbol unroll : architecture.getUnrolls()) {
hasNetworkStream |= unroll.isNetwork();
hasTrainableStream |= unroll.isTrainable();
}
if (!hasNetworkStream) {
Log.error("0" + ErrorCodes.MISSING_NETWORK_STREAM + " The architecture has no network stream. "
if (!hasTrainableStream) {
Log.error("0" + ErrorCodes.MISSING_TRAINABLE_STREAM + " The architecture has no trainable stream. "
, architecture.getSourcePosition());
}
}
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTLayerParameter;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchParameter;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedVariables;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class CheckParameterName implements CNNArchASTArchParameterCoCo {
Set<String> parameterNames = new HashSet<>();
@Override
public void check(ASTArchParameter node) {
checkForIllegalNames(node);
checkForDuplicates(node);
}
private void checkForIllegalNames(ASTArchParameter node){
String name = node.getName();
if (name.isEmpty() || !Character.isLowerCase(name.codePointAt(0))){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". All new parameter and method names have to start with a lowercase letter. "
, node.get_SourcePositionStart());
}
else if (name.equals(AllPredefinedVariables.TRUE_NAME) || name.equals(AllPredefinedVariables.FALSE_NAME)){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". No parameter can be named 'true' or 'false'"
, node.get_SourcePositionStart());
}
else if (name.equals(AllPredefinedVariables.CONDITIONAL_ARG_NAME.toLowerCase())){
Log.error("0" + ErrorCodes.ILLEGAL_NAME + " Illegal name: " + name +
". No parameter can be named 'if'"
, node.get_SourcePositionStart());
}
}
private void checkForDuplicates(ASTArchParameter node){
String name = node.getName();
if (parameterNames.contains(name)){
if (node instanceof ASTLayerParameter){
Collection<Symbol> allParametersWithSameName = node.getEnclosingScopeOpt().get().getLocalSymbols().get(name);
if (allParametersWithSameName.size() > 1){
duplicationError(node);
}
}
else {
duplicationError(node);
}
}
else{
parameterNames.add(name);
}
}
private void duplicationError(ASTArchParameter node){
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated parameter name. " +
"The name '" + node.getName() + "' is already used."
, node.get_SourcePositionStart());
}
}
\ No newline at end of file
......@@ -62,7 +62,7 @@ public class CheckUnroll implements CNNArchASTUnrollCoCo{
}
else {
Set<String> requiredArguments = new HashSet<>();
for (VariableSymbol param : layerDeclaration.getParameters()){
for (ParameterSymbol param : layerDeclaration.getParameters()){
if (!param.getDefaultExpression().isPresent()){
requiredArguments.add(param.getName());
}
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._symboltable.*;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log;
import java.util.HashSet;
import java.util.Set;
public class CheckVariableDeclarationName extends CNNArchSymbolCoCo {
Set<String> variableNames = new HashSet<>();
@Override
public void check(VariableDeclarationSymbol sym) {
String name = sym.getName();