Commit a5e00e92 authored by Thomas Michael Timmermanns's avatar Thomas Michael Timmermanns Committed by Thomas Michael Timmermanns

New version for direct embedding.

Added CNNArchCompilationUnitSymbol, changed ArchitectureSymbol and changed Cocos to work with adapter.
Removed data format declaration from input and output.
parent ad995430
...@@ -25,26 +25,26 @@ There are more compact versions of the same architecture but we will get to that ...@@ -25,26 +25,26 @@ There are more compact versions of the same architecture but we will get to that
All predefined methods are listed at the end of this document. All predefined methods are listed at the end of this document.
``` ```
architecture Alexnet_alt(img_height=224, img_width=224, img_channels=3, classes=10){ architecture Alexnet_alt(img_height=224, img_width=224, img_channels=3, classes=10){
def input Z(0:255)^{H:img_height, W:img_width, C:img_channels} image def input Z(0:255)^{img_channels, img_height, img_width} image
def output Q(0:1)^{C:classes} predictions def output Q(0:1)^{classes} predictions
image -> image ->
Convolution(kernel=(11,11), channels=96, stride=(4,4), padding="no_loss") -> Convolution(kernel=(11,11), channels=96, stride=(4,4), padding="no_loss") ->
Lrn(nsize=5, alpha=0.0001, beta=0.75) -> Lrn(nsize=5, alpha=0.0001, beta=0.75) ->
Pooling(type="max", kernel=(3,3), stride=(2,2), padding="no_loss") -> Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
Relu() -> Relu() ->
Split(n=2) -> Split(n=2) ->
( (
[0] -> [0] ->
Convolution(kernel=(5,5), channels=128) -> Convolution(kernel=(5,5), channels=128) ->
Lrn(nsize=5, alpha=0.0001, beta=0.75) -> Lrn(nsize=5, alpha=0.0001, beta=0.75) ->
Pooling(type="max", kernel=(3,3), stride=(2,2), padding="no_loss") -> Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
Relu() Relu()
| |
[1] -> [1] ->
Convolution(kernel=(5,5), channels=128) -> Convolution(kernel=(5,5), channels=128) ->
Lrn(nsize=5, alpha=0.0001, beta=0.75) -> Lrn(nsize=5, alpha=0.0001, beta=0.75) ->
Pooling(type="max", kernel=(3,3), stride=(2,2), padding="no_loss") -> Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
Relu() Relu()
) -> ) ->
Concatenate() -> Concatenate() ->
...@@ -56,14 +56,14 @@ architecture Alexnet_alt(img_height=224, img_width=224, img_channels=3, classes= ...@@ -56,14 +56,14 @@ architecture Alexnet_alt(img_height=224, img_width=224, img_channels=3, classes=
Convolution(kernel=(3,3), channels=192) -> Convolution(kernel=(3,3), channels=192) ->
Relu() -> Relu() ->
Convolution(kernel=(3,3), channels=128) -> Convolution(kernel=(3,3), channels=128) ->
Pooling(type="max", kernel=(3,3), stride=(2,2), padding="no_loss") -> Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
Relu() Relu()
| |
[1] -> [1] ->
Convolution(kernel=(3,3), channels=192) -> Convolution(kernel=(3,3), channels=192) ->
Relu() -> Relu() ->
Convolution(kernel=(3,3), channels=128) -> Convolution(kernel=(3,3), channels=128) ->
Pooling(type="max", kernel=(3,3), stride=(2,2), padding="no_loss") -> Pooling(pool_type="max", kernel=(3,3), stride=(2,2), padding="no_loss") ->
Relu() Relu()
) -> ) ->
Concatenate() -> Concatenate() ->
...@@ -100,18 +100,17 @@ An architecture in CNNArch can have multiple inputs and outputs. ...@@ -100,18 +100,17 @@ An architecture in CNNArch can have multiple inputs and outputs.
Multiple inputs (or outputs) of the same form can be combined to an array. Multiple inputs (or outputs) of the same form can be combined to an array.
Assuming `h` and `w` are architecture parameter, the following is a valid example: Assuming `h` and `w` are architecture parameter, the following is a valid example:
``` ```
def input Z(0:255)^{H:h, W:w, C:3} image[2] def input Z(0:255)^{3, h, w} image[2]
def input Q(-oo:+oo)^{C:10} additionalData def input Q(-oo:+oo)^{10} additionalData
def output Q(0:1)^{C:3} predictions def output Q(0:1)^{3} predictions
``` ```
The first line defines the input *image* as an array of two rgb (or bgr) images with a resolution of `h` x `w`. The first line defines the input *image* as an array of two rgb (or bgr) images with a resolution of `h` x `w`.
The part `Z(0:255)`, which corresponds to the type definition in EmbeddedMontiArc, restricts the values to integers between 0 and 255. The part `Z(0:255)`, which corresponds to the type definition in EmbeddedMontiArc, restricts the values to integers between 0 and 255.
The following line `{H:h, W:w, C:3}` declares the shape of the input. The following line `{3, h, w}` declares the shape of the input.
The shape denotes the dimensionality in form of height `H`, width `W` and depth `C`(number of channels). The shape denotes the dimensionality in form of depth (number of channels), height and width.
Here, the height is initialized as `h`, the width as `w` and the number of channels is 3. Here, the height is initialized as `h`, the width as `w` and the number of channels is 3.
The second line defines another input with one dimension of size 10 and arbitrary rational values. The second line defines another input with one dimension of size 10 and arbitrary rational values.
The last line defines an one-dimensional output of size 3 with rational values between 0 and 1 (probabilities of 3 classes). The last line defines an one-dimensional output of size 3 with rational values between 0 and 1 (probabilities of 3 classes).
The order of `H`, `W` and `C` determines the shape of the input or output of the network.
If an input or output is an array, it can be used in the architecture in two different ways. If an input or output is an array, it can be used in the architecture in two different ways.
Either a single element is accessed or the array is used as a whole. Either a single element is accessed or the array is used as a whole.
...@@ -198,13 +197,13 @@ The comparison operators do not work reliably for the comparison of tuple (they ...@@ -198,13 +197,13 @@ The comparison operators do not work reliably for the comparison of tuple (they
This version of Alexnet, which uses method construction, argument sequences and special arguments, is identical to the one in the section Basic Structure. This version of Alexnet, which uses method construction, argument sequences and special arguments, is identical to the one in the section Basic Structure.
``` ```
architecture Alexnet_alt2(img_height=224, img_width=224, img_channels=3, classes=10){ architecture Alexnet_alt2(img_height=224, img_width=224, img_channels=3, classes=10){
def input Z(0:255)^{H:img_height, W:img_width, C:img_channels} image def input Z(0:255)^{img_channels, img_height, img_width} image
def output Q(0:1)^{C:classes} predictions def output Q(0:1)^{classes} predictions
def conv(filter, channels, convStride=1, poolStride=1, hasLrn=false, convPadding="same"){ def conv(filter, channels, convStride=1, poolStride=1, hasLrn=false, convPadding="same"){
Convolution(kernel=(filter,filter), channels=channels, stride=(convStride,convStride), padding=convPadding) -> Convolution(kernel=(filter,filter), channels=channels, stride=(convStride,convStride), padding=convPadding) ->
Lrn(nsize=5, alpha=0.0001, beta=0.75, ?=hasLrn) -> Lrn(nsize=5, alpha=0.0001, beta=0.75, ?=hasLrn) ->
Pooling(type="max", kernel=(3,3), stride=(poolStride,poolStride), padding="no_loss", ?=(poolStride != 1)) -> Pooling(pool_type="max", kernel=(3,3), stride=(poolStride,poolStride), padding="no_loss", ?=(poolStride != 1)) ->
Relu() Relu()
} }
def split1(i){ def split1(i){
...@@ -287,20 +286,20 @@ All predefined methods start with a capital letter and all constructed methods h ...@@ -287,20 +286,20 @@ All predefined methods start with a capital letter and all constructed methods h
* **p** (1 >= float >= 0, optional, default=0.5): Fraction of the input that gets dropped out during training time. * **p** (1 >= float >= 0, optional, default=0.5): Fraction of the input that gets dropped out during training time.
* **Pooling(type, kernel, stride=(1,1), padding="same")** * **Pooling(pool_type, kernel, stride=(1,1), padding="same")**
Performs pooling on the input. Performs pooling on the input.
* **type** ({"avg", "max"}, required): Pooling type to be applied. * **pool_type** ({"avg", "max"}, required): Pooling type to be applied.
* **kernel** (integer tuple > 0, required): convolution kernel size: (height, width). * **kernel** (integer tuple > 0, required): convolution kernel size: (height, width).
* **stride** (integer tuple > 0, optional, default=(1,1)): convolution stride: (height, width). * **stride** (integer tuple > 0, optional, default=(1,1)): convolution stride: (height, width).
* **padding** ({"valid", "same", "no_loss"}, optional, default="same"): One of "valid", "same" or "no_loss". "valid" means no padding. "same" results in padding the input such that the output has the same length as the original input divided by the stride (rounded up). "no_loss" results in minimal padding such that each input is used by at least one filter (identical to "valid" if *stride* equals 1). * **padding** ({"valid", "same", "no_loss"}, optional, default="same"): One of "valid", "same" or "no_loss". "valid" means no padding. "same" results in padding the input such that the output has the same length as the original input divided by the stride (rounded up). "no_loss" results in minimal padding such that each input is used by at least one filter (identical to "valid" if *stride* equals 1).
* **GlobalPooling(type)** * **GlobalPooling(pool_type)**
Performs global pooling on the input. Performs global pooling on the input.
* **type** ({"avg", "max"}, required): Pooling type to be applied. * **pool_type** ({"avg", "max"}, required): Pooling type to be applied.
* **Lrn(nsize, knorm=2, alpha=0.0001, beta=0.75)** * **Lrn(nsize, knorm=2, alpha=0.0001, beta=0.75)**
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
<groupId>de.monticore.lang.monticar</groupId> <groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnn-arch</artifactId> <artifactId>cnn-arch</artifactId>
<version>0.1.1-SNAPSHOT</version> <version>0.2.0-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= --> <!-- == PROJECT DEPENDENCIES ============================================= -->
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
<mc.grammars.assembly.version>0.0.6</mc.grammars.assembly.version> <mc.grammars.assembly.version>0.0.6</mc.grammars.assembly.version>
<SIUnit.version>0.0.10-SNAPSHOT</SIUnit.version> <SIUnit.version>0.0.10-SNAPSHOT</SIUnit.version>
<Common-MontiCar.version>0.0.10-SNAPSHOT</Common-MontiCar.version> <Common-MontiCar.version>0.0.10-SNAPSHOT</Common-MontiCar.version>
<Math.version>0.0.10-SNAPSHOT</Math.version> <Math.version>0.0.11-SNAPSHOT</Math.version>
<!-- .. Libraries .................................................. --> <!-- .. Libraries .................................................. -->
<guava.version>18.0</guava.version> <guava.version>18.0</guava.version>
<junit.version>4.12</junit.version> <junit.version>4.12</junit.version>
......
...@@ -2,39 +2,36 @@ package de.monticore.lang.monticar; ...@@ -2,39 +2,36 @@ package de.monticore.lang.monticar;
grammar CNNArch extends de.monticore.lang.math.Math { grammar CNNArch extends de.monticore.lang.math.Math {
CNNArchCompilationUnit = Architecture; symbol scope CNNArchCompilationUnit = "architecture"
name:Name&
( "(" (ArchitectureParameter || ",")* ")" )? "{"
ioDeclarations:IODeclaration*
Architecture
"}";
symbol scope Architecture = "architecture" Architecture = methodDeclaration:MethodDeclaration*
name:Name& body:ArchBody;
( "(" (ArchitectureParameter || ",")* ")" )? "{"
declarations:ArchDeclaration*
body:ArchBody "}";
interface ArchDeclaration;
interface ArchitectureElement; interface ArchitectureElement;
interface Variable; interface Variable;
ast Variable = method String getName(){}; ast Variable = method String getName(){};
IODeclaration implements ArchDeclaration = "def" IODeclaration = "def"
(in:"input" | out:"output") (in:"input" | out:"output")
type:ArchType type:ArchType
Name& Name&
(ArrayDeclaration)?; (ArrayDeclaration)?;
ArchType implements Type = ElementType "^" Shape; ArchType = ElementType "^" Shape;
Shape = "{" dimensions:(DimensionArgument || ",")* "}"; Shape = "{" dimensions:(ArchSimpleExpression || ",")* "}";
DimensionArgument = (name:"H" ":" height:ArchSimpleExpression
| name:"W" ":" width:ArchSimpleExpression
| name:"C" ":" channels:ArchSimpleExpression);
ArchitectureParameter implements Variable = Name& ("=" default:ArchSimpleExpression)?; ArchitectureParameter implements Variable = Name& ("=" default:ArchSimpleExpression)?;
MethodDeclaration implements ArchDeclaration = "def" MethodDeclaration = "def"
Name& "(" Name& "("
parameters:(MethodParameter || ",")* ")" "{" parameters:(MethodParameter || ",")* ")" "{"
body:ArchBody "}"; body:ArchBody "}";
MethodParameter implements Variable = Name& ("=" default:ArchSimpleExpression)?; MethodParameter implements Variable = Name& ("=" default:ArchSimpleExpression)?;
...@@ -61,7 +58,7 @@ grammar CNNArch extends de.monticore.lang.math.Math { ...@@ -61,7 +58,7 @@ grammar CNNArch extends de.monticore.lang.math.Math {
ArchExpression = (expression:ArchSimpleExpression | sequence:ArchValueSequence); ArchExpression = (expression:ArchSimpleExpression | sequence:ArchValueSequence);
interface ArchValueSequence; interface ArchValueSequence;
ArchParallelSequence implements ArchValueSequence = "[" parallelValues:(ArchSerialSequence || "|")* "]"; ArchParallelSequence implements ArchValueSequence = "[" parallelValues:(ArchSerialSequence || "|")* "]";
......
...@@ -40,9 +40,10 @@ public class CNNArchCocos { ...@@ -40,9 +40,10 @@ public class CNNArchCocos {
public static CNNArchCoCoChecker createPostResolveChecker() { public static CNNArchCoCoChecker createPostResolveChecker() {
return new CNNArchCoCoChecker() return new CNNArchCoCoChecker()
.addCoCo(new CheckIOType())
.addCoCo(new CheckLayerInputs()) .addCoCo(new CheckLayerInputs())
.addCoCo(new CheckIOAccessAndIOMissing()) .addCoCo(new CheckIOAccessAndIOMissing())
.addCoCo(new CheckIOShape()) .addCoCo(new CheckUnusedASTIODeclaration())
.addCoCo(new CheckArchitectureFinished()); .addCoCo(new CheckArchitectureFinished());
} }
...@@ -53,7 +54,6 @@ public class CNNArchCocos { ...@@ -53,7 +54,6 @@ public class CNNArchCocos {
.addCoCo(new CheckMethodLayer()) .addCoCo(new CheckMethodLayer())
.addCoCo(new CheckRangeOperators()) .addCoCo(new CheckRangeOperators())
.addCoCo(new CheckVariableName()) .addCoCo(new CheckVariableName())
.addCoCo(new CheckUnknownIO())
.addCoCo(new CheckArgument()) .addCoCo(new CheckArgument())
.addCoCo(new CheckMethodName()) .addCoCo(new CheckMethodName())
.addCoCo(new CheckMethodRecursion()); .addCoCo(new CheckMethodRecursion());
......
...@@ -39,16 +39,6 @@ public class CheckArgument implements CNNArchASTArchArgumentCoCo { ...@@ -39,16 +39,6 @@ public class CheckArgument implements CNNArchASTArchArgumentCoCo {
"Possible arguments are: " + Joiners.COMMA.join(method.getParameters()) "Possible arguments are: " + Joiners.COMMA.join(method.getParameters())
, node.get_SourcePositionStart()); , node.get_SourcePositionStart());
} }
else {
/*if (argument.getRhs().getValue().isPresent()){
argument.checkConstraints();
}*/
/*if (argument.getRhs().isResolvable()) {
argument.getRhs().resolveOrError();
argument.checkConstraints();
argument.getRhs().reset();
}*/
}
} }
} }
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
*/ */
package de.monticore.lang.monticar.cnnarch._cocos; package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchitecture;
import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration; import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol; import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOLayerSymbol; import de.monticore.lang.monticar.cnnarch._symboltable.IOLayerSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes; import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
...@@ -33,17 +35,19 @@ import java.util.Optional; ...@@ -33,17 +35,19 @@ import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.IntStream; import java.util.stream.IntStream;
public class CheckIOAccessAndIOMissing implements CNNArchASTIODeclarationCoCo { public class CheckIOAccessAndIOMissing implements CNNArchASTArchitectureCoCo {
@Override @Override
public void check(ASTIODeclaration node) { public void check(ASTArchitecture node) {
IODeclarationSymbol ioDeclaration = (IODeclarationSymbol) node.getSymbol().get(); ArchitectureSymbol architecture = (ArchitectureSymbol) node.getSymbol().get();
if (ioDeclaration.getArrayLength() == 1){ for (IODeclarationSymbol ioDeclaration : architecture.getIODeclarations()){
checkSingleIO(ioDeclaration); if (ioDeclaration.getArrayLength() == 1){
} checkSingleIO(ioDeclaration);
else { }
checkIOArray(ioDeclaration); else {
checkIOArray(ioDeclaration);
}
} }
} }
......
...@@ -20,26 +20,36 @@ ...@@ -20,26 +20,36 @@
*/ */
package de.monticore.lang.monticar.cnnarch._cocos; package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration; import de.monticore.lang.monticar.cnnarch._ast.ASTIOLayer;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes; import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log; import de.se_rwth.commons.logging.Log;
import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
public class CheckIOName implements CNNArchASTIODeclarationCoCo { public class CheckIOName implements CNNArchASTIOLayerCoCo {
Set<String> ioNames = new HashSet<>(); private Set<IODeclarationSymbol> checkedIODeclarations = new HashSet<>();
@Override @Override
public void check(ASTIODeclaration node) { public void check(ASTIOLayer node) {
if (ioNames.contains(node.getName())){ Collection<IODeclarationSymbol> ioDeclarations = node.getEnclosingScope().get().<IODeclarationSymbol>resolveMany(node.getName(), IODeclarationSymbol.KIND);
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated IO name. " +
"The name '" + node.getName() + "' is already used." if (ioDeclarations.isEmpty()){
Log.error("0" + ErrorCodes.UNKNOWN_IO + " Unknown input or output name. " +
"The input or output '" + node.getName() + "' does not exist"
, node.get_SourcePositionStart()); , node.get_SourcePositionStart());
} }
else { else if (ioDeclarations.size() > 1){
ioNames.add(node.getName()); IODeclarationSymbol ioDeclaration = ioDeclarations.iterator().next();
if (!checkedIODeclarations.contains(ioDeclaration)){
Log.error("0" + ErrorCodes.DUPLICATED_NAME + " Duplicated IO name. " +
"The name '" + ioDeclaration.getName() + "' is already used."
, ioDeclaration.getSourcePosition());
checkedIODeclarations.addAll(ioDeclarations);
}
} }
} }
......
...@@ -20,59 +20,62 @@ ...@@ -20,59 +20,62 @@
*/ */
package de.monticore.lang.monticar.cnnarch._cocos; package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTArchType; import de.monticore.lang.monticar.cnnarch._ast.ASTArchitecture;
import de.monticore.lang.monticar.cnnarch._ast.ASTDimensionArgument;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchSimpleExpressionSymbol; import de.monticore.lang.monticar.cnnarch._symboltable.ArchSimpleExpressionSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchTypeSymbol; import de.monticore.lang.monticar.cnnarch._symboltable.ArchTypeSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes; import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.se_rwth.commons.logging.Log; import de.se_rwth.commons.logging.Log;
import java.util.Optional; import java.util.Optional;
public class CheckIOShape implements CNNArchASTArchTypeCoCo { public class CheckIOType implements CNNArchASTArchitectureCoCo {
@Override @Override
public void check(ASTArchType node) { public void check(ASTArchitecture node) {
boolean hasHeight = false; ArchitectureSymbol architecture = (ArchitectureSymbol) node.getSymbol().get();
boolean hasWidth = false;
boolean hasChannels = false; for (IODeclarationSymbol ioDeclaration : architecture.getIODeclarations()){
for (ASTDimensionArgument dimensionArg : node.getShape().getDimensions()){ check(ioDeclaration);
if (dimensionArg.getWidth().isPresent()){
if (hasWidth){
repetitionError(dimensionArg);
}
hasWidth = true;
}
else if (dimensionArg.getHeight().isPresent()){
if (hasHeight){
repetitionError(dimensionArg);
}
hasHeight = true;
}
else {
if (hasChannels){
repetitionError(dimensionArg);
}
hasChannels = true;
}
} }
}
public void check(IODeclarationSymbol ioDeclaration) {
ArchTypeSymbol type = ioDeclaration.getType();
ArchTypeSymbol shape = (ArchTypeSymbol) node.getSymbol().get(); if (type.getElementType().isIsComplex() || type.getElementType().isIsBoolean()){
for (ArchSimpleExpressionSymbol dimension : shape.getDimensionSymbols()){ Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid IO element type. " +
Optional<Integer> value = dimension.getIntValue(); "Type has to be rational or whole number.");
if (!value.isPresent() || value.get() <= 0){ }
Log.error("0" + ErrorCodes.INVALID_IO_SHAPE + " Invalid shape. " +
"The dimensions can only be defined by a positive integer." if (type.getDimensionSymbols().size() == 2 || type.getDimensionSymbols().size() > 3){
, dimension.getSourcePosition()); 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})."
, ioDeclaration.getSourcePosition());
}
else {
for (ArchSimpleExpressionSymbol dimension : type.getDimensionSymbols()){
Optional<Integer> value = dimension.getIntValue();
if (!value.isPresent() || value.get() <= 0){
Log.error("0" + ErrorCodes.INVALID_IO_TYPE + " Invalid shape. " +
"The dimension sizes can only be positive integers."
, dimension.getSourcePosition());
}
} }
} }
}
private void repetitionError(ASTDimensionArgument node){ if (Log.getFindings().isEmpty()){
Log.error("0" + ErrorCodes.INVALID_IO_SHAPE + " Invalid shape. " + if (ioDeclaration.isInput() && type.getChannels() != 3 && type.getChannels() != 1){
"The dimension '" + node.getName().get() + "' was defined multiple times. " if (type.getHeight() > 1 || type.getWidth() > 1){
, node.get_SourcePositionStart()); 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());
}
}
}
} }
} }
...@@ -20,29 +20,19 @@ ...@@ -20,29 +20,19 @@
*/ */
package de.monticore.lang.monticar.cnnarch._cocos; package de.monticore.lang.monticar.cnnarch._cocos;
import de.monticore.lang.monticar.cnnarch._ast.ASTIOLayer; import de.monticore.lang.monticar.cnnarch._ast.ASTIODeclaration;
import de.monticore.lang.monticar.cnnarch._symboltable.CompositeLayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol; import de.monticore.lang.monticar.cnnarch._symboltable.IODeclarationSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.IOLayerSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol;
import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes; import de.monticore.lang.monticar.cnnarch.helper.ErrorCodes;
import de.monticore.symboltable.Symbol;
import de.se_rwth.commons.logging.Log; import de.se_rwth.commons.logging.Log;
import java.util.Collection; public class CheckUnusedASTIODeclaration implements CNNArchASTIODeclarationCoCo {
import java.util.Collections;
public class CheckUnknownIO implements CNNArchASTIOLayerCoCo {
@Override @Override
public void check(ASTIOLayer node) { public void check(ASTIODeclaration node) {
Symbol symbol = node.getSymbol().get(); IODeclarationSymbol ioDeclaration = (IODeclarationSymbol) node.getSymbol().get();
Collection<IODeclarationSymbol> ioDeclarations = node.getEnclosingScope().get().<IODeclarationSymbol>resolveMany(node.getName(), IODeclarationSymbol.KIND); if (ioDeclaration.getConnectedLayers().isEmpty()){
Log.error("0" + ErrorCodes.MISSING_IO + " Input or output with name '" + ioDeclaration.getName() + "' was declared but not used. "
if (ioDeclarations.isEmpty()){ , ioDeclaration.getSourcePosition());
Log.error("0" + ErrorCodes.UNKNOWN_IO + " Unknown input or output name. " +
"The input or output '" + node.getName() + "' does not exist"