Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
monticore
EmbeddedMontiArc
generators
CNNArch2Gluon
Commits
79e523d7
Commit
79e523d7
authored
Feb 25, 2019
by
Evgeny Kusmenko
Browse files
Merge branch 'inherit-from-mxnet-generator' into 'master'
Refactor and Inherit from CNNArch2MxNet See merge request
!9
parents
100af92f
531d89e8
Pipeline
#107566
passed with stages
in 4 minutes and 25 seconds
Changes
15
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
pom.xml
View file @
79e523d7
...
...
@@ -8,7 +8,7 @@
<groupId>
de.monticore.lang.monticar
</groupId>
<artifactId>
cnnarch-gluon-generator
</artifactId>
<version>
0.1.
0
-SNAPSHOT
</version>
<version>
0.1.
2
-SNAPSHOT
</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
...
...
@@ -17,6 +17,7 @@
<!-- .. SE-Libraries .................................................. -->
<CNNArch.version>
0.2.9
</CNNArch.version>
<CNNTrain.version>
0.2.6
</CNNTrain.version>
<CNNArch2MXNet.version>
0.2.13-SNAPSHOT
</CNNArch2MXNet.version>
<embedded-montiarc-math-opt-generator>
0.1.4
</embedded-montiarc-math-opt-generator>
<!-- .. Libraries .................................................. -->
...
...
@@ -59,6 +60,12 @@
<!-- MontiCore Dependencies -->
<dependency>
<groupId>
de.monticore.lang.monticar
</groupId>
<artifactId>
cnnarch-mxnet-generator
</artifactId>
<version>
${CNNArch2MXNet.version}
</version>
</dependency>
<dependency>
<groupId>
de.monticore.lang.monticar
</groupId>
<artifactId>
cnn-arch
</artifactId>
...
...
src/main/java/de/monticore/lang/monticar/cnnarch/gluongenerator/ArchitectureElementData.java
deleted
100644 → 0
View file @
100af92f
/**
*
* ******************************************************************************
* 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.gluongenerator
;
import
de.monticore.lang.monticar.cnnarch._symboltable.ArchTypeSymbol
;
import
de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureElementSymbol
;
import
de.monticore.lang.monticar.cnnarch._symboltable.LayerSymbol
;
import
de.monticore.lang.monticar.cnnarch.predefined.AllPredefinedLayers
;
import
de.se_rwth.commons.logging.Log
;
import
javax.annotation.Nullable
;
import
java.util.Arrays
;
import
java.util.List
;
public
class
ArchitectureElementData
{
private
String
name
;
private
ArchitectureElementSymbol
element
;
private
CNNArchTemplateController
templateController
;
public
ArchitectureElementData
(
String
name
,
ArchitectureElementSymbol
element
,
CNNArchTemplateController
templateController
)
{
this
.
name
=
name
;
this
.
element
=
element
;
this
.
templateController
=
templateController
;
}
public
String
getName
()
{
return
name
;
}
public
void
setName
(
String
name
)
{
this
.
name
=
name
;
}
public
ArchitectureElementSymbol
getElement
()
{
return
element
;
}
public
void
setElement
(
ArchitectureElementSymbol
element
)
{
this
.
element
=
element
;
}
public
CNNArchTemplateController
getTemplateController
()
{
return
templateController
;
}
public
void
setTemplateController
(
CNNArchTemplateController
templateController
)
{
this
.
templateController
=
templateController
;
}
public
List
<
String
>
getInputs
(){
return
getTemplateController
().
getLayerInputs
(
getElement
());
}
public
boolean
isLogisticRegressionOutput
(){
return
getTemplateController
().
isLogisticRegressionOutput
(
getElement
());
}
public
boolean
isLinearRegressionOutput
(){
boolean
result
=
getTemplateController
().
isLinearRegressionOutput
(
getElement
());
if
(
result
){
Log
.
warn
(
"The Output '"
+
getElement
().
getName
()
+
"' is a linear regression output (squared loss) during training"
+
" because the previous architecture element is not a softmax (cross-entropy loss) or sigmoid (logistic regression loss) activation. "
+
"Other loss functions are currently not supported. "
,
getElement
().
getSourcePosition
());
}
return
result
;
}
public
boolean
isSoftmaxOutput
(){
return
getTemplateController
().
isSoftmaxOutput
(
getElement
());
}
public
List
<
Integer
>
getKernel
(){
return
((
LayerSymbol
)
getElement
())
.
getIntTupleValue
(
AllPredefinedLayers
.
KERNEL_NAME
).
get
();
}
public
int
getChannels
(){
return
((
LayerSymbol
)
getElement
())
.
getIntValue
(
AllPredefinedLayers
.
CHANNELS_NAME
).
get
();
}
public
List
<
Integer
>
getStride
(){
return
((
LayerSymbol
)
getElement
())
.
getIntTupleValue
(
AllPredefinedLayers
.
STRIDE_NAME
).
get
();
}
public
int
getUnits
(){
return
((
LayerSymbol
)
getElement
())
.
getIntValue
(
AllPredefinedLayers
.
UNITS_NAME
).
get
();
}
public
boolean
getNoBias
(){
return
((
LayerSymbol
)
getElement
())
.
getBooleanValue
(
AllPredefinedLayers
.
NOBIAS_NAME
).
get
();
}
public
double
getP
(){
return
((
LayerSymbol
)
getElement
())
.
getDoubleValue
(
AllPredefinedLayers
.
P_NAME
).
get
();
}
public
int
getIndex
(){
return
((
LayerSymbol
)
getElement
())
.
getIntValue
(
AllPredefinedLayers
.
INDEX_NAME
).
get
();
}
public
int
getNumOutputs
(){
return
((
LayerSymbol
)
getElement
())
.
getIntValue
(
AllPredefinedLayers
.
NUM_SPLITS_NAME
).
get
();
}
public
boolean
getFixGamma
(){
return
((
LayerSymbol
)
getElement
())
.
getBooleanValue
(
AllPredefinedLayers
.
FIX_GAMMA_NAME
).
get
();
}
public
int
getNsize
(){
return
((
LayerSymbol
)
getElement
())
.
getIntValue
(
AllPredefinedLayers
.
NSIZE_NAME
).
get
();
}
public
double
getKnorm
(){
return
((
LayerSymbol
)
getElement
())
.
getDoubleValue
(
AllPredefinedLayers
.
KNORM_NAME
).
get
();
}
public
double
getAlpha
(){
return
((
LayerSymbol
)
getElement
())
.
getDoubleValue
(
AllPredefinedLayers
.
ALPHA_NAME
).
get
();
}
public
double
getBeta
(){
return
((
LayerSymbol
)
getElement
())
.
getDoubleValue
(
AllPredefinedLayers
.
BETA_NAME
).
get
();
}
@Nullable
public
String
getPoolType
(){
return
((
LayerSymbol
)
getElement
())
.
getStringValue
(
AllPredefinedLayers
.
POOL_TYPE_NAME
).
get
();
}
@Nullable
public
List
<
Integer
>
getPadding
(){
return
getPadding
((
LayerSymbol
)
getElement
());
}
@Nullable
public
List
<
Integer
>
getPadding
(
LayerSymbol
layer
){
List
<
Integer
>
kernel
=
layer
.
getIntTupleValue
(
AllPredefinedLayers
.
KERNEL_NAME
).
get
();
List
<
Integer
>
stride
=
layer
.
getIntTupleValue
(
AllPredefinedLayers
.
STRIDE_NAME
).
get
();
ArchTypeSymbol
inputType
=
layer
.
getInputTypes
().
get
(
0
);
ArchTypeSymbol
outputType
=
layer
.
getOutputTypes
().
get
(
0
);
int
heightWithPad
=
kernel
.
get
(
0
)
+
stride
.
get
(
0
)*(
outputType
.
getHeight
()
-
1
);
int
widthWithPad
=
kernel
.
get
(
1
)
+
stride
.
get
(
1
)*(
outputType
.
getWidth
()
-
1
);
int
heightPad
=
Math
.
max
(
0
,
heightWithPad
-
inputType
.
getHeight
());
int
widthPad
=
Math
.
max
(
0
,
widthWithPad
-
inputType
.
getWidth
());
int
topPad
=
(
int
)
Math
.
ceil
(
heightPad
/
2.0
);
int
bottomPad
=
(
int
)
Math
.
floor
(
heightPad
/
2.0
);
int
leftPad
=
(
int
)
Math
.
ceil
(
widthPad
/
2.0
);
int
rightPad
=
(
int
)
Math
.
floor
(
widthPad
/
2.0
);
if
(
topPad
==
0
&&
bottomPad
==
0
&&
leftPad
==
0
&&
rightPad
==
0
){
return
null
;
}
return
Arrays
.
asList
(
0
,
0
,
0
,
0
,
topPad
,
bottomPad
,
leftPad
,
rightPad
);
}
}
src/main/java/de/monticore/lang/monticar/cnnarch/gluongenerator/CNNArch2Gluon.java
View file @
79e523d7
...
...
@@ -20,83 +20,25 @@
*/
package
de.monticore.lang.monticar.cnnarch.gluongenerator
;
import
de.monticore.lang.monticar.cnnarch.CNNArchGenerator
;
import
de.monticore.lang.monticar.cnnarch._cocos.CNNArchCocos
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.CNNArch2MxNet
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.Target
;
import
de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol
;
import
de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureElementSymbol
;
import
de.monticore.lang.monticar.cnnarch._symboltable.CompositeElementSymbol
;
import
de.monticore.lang.monticar.cnnarch._symboltable.CNNArchCompilationUnitSymbol
;
import
de.monticore.lang.monticar.generator.FileContent
;
import
de.monticore.lang.monticar.generator.cmake.CMakeConfig
;
import
de.monticore.lang.monticar.generator.cmake.CMakeFindModule
;
import
de.monticore.lang.monticar.generator.cpp.GeneratorCPP
;
import
de.monticore.symboltable.Scope
;
import
de.se_rwth.commons.logging.Log
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.TemplateConfiguration
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.List
;
public
class
CNNArch2Gluon
extends
CNNArchGenerator
{
private
boolean
isSupportedLayer
(
ArchitectureElementSymbol
element
,
LayerSupportChecker
layerChecker
){
List
<
ArchitectureElementSymbol
>
constructLayerElemList
;
if
(
element
.
getResolvedThis
().
get
()
instanceof
CompositeElementSymbol
)
{
constructLayerElemList
=
((
CompositeElementSymbol
)
element
.
getResolvedThis
().
get
()).
getElements
();
for
(
ArchitectureElementSymbol
constructedLayerElement
:
constructLayerElemList
)
{
if
(!
isSupportedLayer
(
constructedLayerElement
,
layerChecker
))
{
return
false
;
}
}
}
if
(!
layerChecker
.
isSupported
(
element
.
toString
()))
{
Log
.
error
(
"Unsupported layer "
+
"'"
+
element
.
getName
()
+
"'"
+
" for the backend MXNET."
);
return
false
;
}
else
{
return
true
;
}
}
private
boolean
supportCheck
(
ArchitectureSymbol
architecture
){
LayerSupportChecker
layerChecker
=
new
LayerSupportChecker
();
for
(
ArchitectureElementSymbol
element
:
((
CompositeElementSymbol
)
architecture
.
getBody
()).
getElements
()){
if
(!
isSupportedLayer
(
element
,
layerChecker
))
{
return
false
;
}
}
return
true
;
}
public
CNNArch2Gluon
()
{
setGenerationTargetPath
(
"./target/generated-sources-cnnarch/"
);
}
public
void
generate
(
Scope
scope
,
String
rootModelName
){
Optional
<
CNNArchCompilationUnitSymbol
>
compilationUnit
=
scope
.
resolve
(
rootModelName
,
CNNArchCompilationUnitSymbol
.
KIND
);
if
(!
compilationUnit
.
isPresent
()){
Log
.
error
(
"could not resolve architecture "
+
rootModelName
);
quitGeneration
();
}
CNNArchCocos
.
checkAll
(
compilationUnit
.
get
());
if
(!
supportCheck
(
compilationUnit
.
get
().
getArchitecture
())){
quitGeneration
();
}
try
{
generateFiles
(
compilationUnit
.
get
().
getArchitecture
());
}
catch
(
IOException
e
){
Log
.
error
(
e
.
toString
());
}
}
public
class
CNNArch2Gluon
extends
CNNArch2MxNet
{
//check cocos with CNNArchCocos.checkAll(architecture) before calling this method.
@Override
public
Map
<
String
,
String
>
generateStrings
(
ArchitectureSymbol
architecture
){
TemplateConfiguration
templateConfiguration
=
new
GluonTemplateConfiguration
();
Map
<
String
,
String
>
fileContentMap
=
new
HashMap
<>();
CNNArchTemplateController
archTc
=
new
CNNArchTemplateController
(
architecture
);
CNNArch2GluonTemplateController
archTc
=
new
CNNArch2GluonTemplateController
(
architecture
,
templateConfiguration
);
Map
.
Entry
<
String
,
String
>
temp
;
temp
=
archTc
.
process
(
"CNNPredictor"
,
Target
.
CPP
);
...
...
@@ -118,28 +60,4 @@ public class CNNArch2Gluon extends CNNArchGenerator {
return
fileContentMap
;
}
public
void
generateFromFilecontentsMap
(
Map
<
String
,
String
>
fileContentMap
)
throws
IOException
{
GeneratorCPP
genCPP
=
new
GeneratorCPP
();
genCPP
.
setGenerationTargetPath
(
getGenerationTargetPath
());
for
(
String
fileName
:
fileContentMap
.
keySet
()){
genCPP
.
generateFile
(
new
FileContent
(
fileContentMap
.
get
(
fileName
),
fileName
));
}
}
public
Map
<
String
,
String
>
generateCMakeContent
(
String
rootModelName
)
{
// model name should start with a lower case letter. If it is a component, replace dot . by _
rootModelName
=
rootModelName
.
replace
(
'.'
,
'_'
).
replace
(
'['
,
'_'
).
replace
(
']'
,
'_'
);
rootModelName
=
rootModelName
.
substring
(
0
,
1
).
toLowerCase
()
+
rootModelName
.
substring
(
1
);
CMakeConfig
cMakeConfig
=
new
CMakeConfig
(
rootModelName
);
cMakeConfig
.
addModuleDependency
(
new
CMakeFindModule
(
"Armadillo"
,
true
));
cMakeConfig
.
addCMakeCommand
(
"set(LIBS ${LIBS} mxnet)"
);
Map
<
String
,
String
>
fileContentMap
=
new
HashMap
<>();
for
(
FileContent
fileContent
:
cMakeConfig
.
generateCMakeFiles
()){
fileContentMap
.
put
(
fileContent
.
getFileName
(),
fileContent
.
getFileContent
());
}
return
fileContentMap
;
}
}
src/main/java/de/monticore/lang/monticar/cnnarch/gluongenerator/CNNArch2GluonCli.java
View file @
79e523d7
...
...
@@ -19,81 +19,14 @@
* *******************************************************************************
*/
package
de.monticore.lang.monticar.cnnarch.gluongenerator
;
import
de.se_rwth.commons.logging.Log
;
import
org.apache.commons.cli.*
;
import
java.nio.file.Path
;
import
java.nio.file.Paths
;
import
de.monticore.lang.monticar.cnnarch.CNNArchGenerator
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.GenericCNNArchCli
;
public
class
CNNArch2GluonCli
{
public
static
final
Option
OPTION_MODELS_PATH
=
Option
.
builder
(
"m"
)
.
longOpt
(
"models-dir"
)
.
desc
(
"full path to the directory with the CNNArch model"
)
.
hasArg
(
true
)
.
required
(
true
)
.
build
();
public
static
final
Option
OPTION_ROOT_MODEL
=
Option
.
builder
(
"r"
)
.
longOpt
(
"root-model"
)
.
desc
(
"name of the architecture"
)
.
hasArg
(
true
)
.
required
(
true
)
.
build
();
public
static
final
Option
OPTION_OUTPUT_PATH
=
Option
.
builder
(
"o"
)
.
longOpt
(
"output-dir"
)
.
desc
(
"full path to output directory for tests"
)
.
hasArg
(
true
)
.
required
(
false
)
.
build
();
private
CNNArch2GluonCli
()
{
}
public
static
void
main
(
String
[]
args
)
{
Options
options
=
getOptions
();
CommandLineParser
parser
=
new
DefaultParser
();
CommandLine
cliArgs
=
parseArgs
(
options
,
parser
,
args
);
if
(
cliArgs
!=
null
)
{
runGenerator
(
cliArgs
);
}
}
private
static
Options
getOptions
()
{
Options
options
=
new
Options
();
options
.
addOption
(
OPTION_MODELS_PATH
);
options
.
addOption
(
OPTION_ROOT_MODEL
);
options
.
addOption
(
OPTION_OUTPUT_PATH
);
return
options
;
}
private
static
CommandLine
parseArgs
(
Options
options
,
CommandLineParser
parser
,
String
[]
args
)
{
CommandLine
cliArgs
;
try
{
cliArgs
=
parser
.
parse
(
options
,
args
);
}
catch
(
ParseException
e
)
{
Log
.
error
(
"argument parsing exception: "
+
e
.
getMessage
());
quitGeneration
();
return
null
;
}
return
cliArgs
;
}
private
static
void
quitGeneration
(){
Log
.
error
(
"Code generation is aborted"
);
System
.
exit
(
1
);
}
private
static
void
runGenerator
(
CommandLine
cliArgs
)
{
Path
modelsDirPath
=
Paths
.
get
(
cliArgs
.
getOptionValue
(
OPTION_MODELS_PATH
.
getOpt
()));
String
rootModelName
=
cliArgs
.
getOptionValue
(
OPTION_ROOT_MODEL
.
getOpt
());
String
outputPath
=
cliArgs
.
getOptionValue
(
OPTION_OUTPUT_PATH
.
getOpt
());
CNNArch2Gluon
generator
=
new
CNNArch2Gluon
();
if
(
outputPath
!=
null
){
generator
.
setGenerationTargetPath
(
outputPath
);
}
generator
.
generate
(
modelsDirPath
,
rootModelName
);
CNNArchGenerator
generator
=
new
CNNArch2Gluon
();
GenericCNNArchCli
cli
=
new
GenericCNNArchCli
(
generator
);
cli
.
run
(
args
);
}
}
src/main/java/de/monticore/lang/monticar/cnnarch/gluongenerator/CNNArchTemplateController.java
→
src/main/java/de/monticore/lang/monticar/cnnarch/gluongenerator/CNNArch
2Gluon
TemplateController.java
View file @
79e523d7
...
...
@@ -20,107 +20,21 @@
*/
package
de.monticore.lang.monticar.cnnarch.gluongenerator
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.ArchitectureElementData
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.CNNArchTemplateController
;
import
de.monticore.lang.monticar.cnnarch._symboltable.*
;
import
de.monticore.lang.monticar.cnnarch.predefined.Sigmoid
;
import
de.monticore.lang.monticar.cnnarch.predefined.Softmax
;
import
de.monticore.lang.monticar.cnnarch.mxnetgenerator.TemplateConfiguration
;
import
java.io.StringWriter
;
import
java.io.Writer
;
import
java.util.*
;
public
class
CNNArchTemplateController
{
public
static
final
String
FTL_FILE_ENDING
=
".ftl"
;
public
static
final
String
TEMPLATE_ELEMENTS_DIR_PATH
=
"elements/"
;
public
static
final
String
TEMPLATE_CONTROLLER_KEY
=
"tc"
;
public
static
final
String
ELEMENT_DATA_KEY
=
"element"
;
public
class
CNNArch2GluonTemplateController
extends
CNNArchTemplateController
{
public
static
final
String
NET_DEFINITION_MODE_KEY
=
"definition_mode"
;
private
LayerNameCreator
nameManager
;
private
ArchitectureSymbol
architecture
;
//temporary attributes. They are set after calling process()
private
Writer
writer
;
private
String
mainTemplateNameWithoutEnding
;
private
Target
targetLanguage
;
private
ArchitectureElementData
dataElement
;
public
CNNArchTemplateController
(
ArchitectureSymbol
architecture
)
{
setArchitecture
(
architecture
);
}
public
String
getFileNameWithoutEnding
()
{
return
mainTemplateNameWithoutEnding
+
"_"
+
getFullArchitectureName
();
}
public
ArchitectureElementData
getCurrentElement
()
{
return
dataElement
;
}
public
void
setCurrentElement
(
ArchitectureElementSymbol
layer
)
{
this
.
dataElement
=
new
ArchitectureElementData
(
getName
(
layer
),
layer
,
this
);
}
public
void
setCurrentElement
(
ArchitectureElementData
dataElement
)
{
this
.
dataElement
=
dataElement
;
}
public
ArchitectureSymbol
getArchitecture
()
{
return
architecture
;
}
public
void
setArchitecture
(
ArchitectureSymbol
architecture
)
{
this
.
architecture
=
architecture
;
this
.
nameManager
=
new
LayerNameCreator
(
architecture
);
}
public
String
getName
(
ArchitectureElementSymbol
layer
){
return
nameManager
.
getName
(
layer
);
}
public
String
getArchitectureName
(){
return
getArchitecture
().
getEnclosingScope
().
getSpanningSymbol
().
get
().
getName
().
replaceAll
(
"\\."
,
"_"
);
}
public
String
getFullArchitectureName
(){
return
getArchitecture
().
getEnclosingScope
().
getSpanningSymbol
().
get
().
getFullName
().
replaceAll
(
"\\."
,
"_"
);
}
public
List
<
String
>
getLayerInputs
(
ArchitectureElementSymbol
layer
){
List
<
String
>
inputNames
=
new
ArrayList
<>();
if
(
isSoftmaxOutput
(
layer
)
||
isLogisticRegressionOutput
(
layer
)){
inputNames
=
getLayerInputs
(
layer
.
getInputElement
().
get
());
}
else
{
for
(
ArchitectureElementSymbol
input
:
layer
.
getPrevious
())
{
if
(
input
.
getOutputTypes
().
size
()
==
1
)
{
inputNames
.
add
(
getName
(
input
));
}
else
{
for
(
int
i
=
0
;
i
<
input
.
getOutputTypes
().
size
();
i
++)
{
inputNames
.
add
(
getName
(
input
)
+
"["
+
i
+
"]"
);
}
}
}
}
return
inputNames
;
}
public
List
<
String
>
getArchitectureInputs
(){
List
<
String
>
list
=
new
ArrayList
<>();
for
(
IOSymbol
ioElement
:
getArchitecture
().
getInputs
()){
list
.
add
(
nameManager
.
getName
(
ioElement
));
}
return
list
;
}
public
List
<
String
>
getArchitectureOutputs
(){
List
<
String
>
list
=
new
ArrayList
<>();
for
(
IOSymbol
ioElement
:
getArchitecture
().
getOutputs
()){
list
.
add
(
nameManager
.
getName
(
ioElement
));
}
return
list
;
public
CNNArch2GluonTemplateController
(
ArchitectureSymbol
architecture
,
TemplateConfiguration
templateConfiguration
)
{
super
(
architecture
,
templateConfiguration
);
}
public
void
include
(
String
relativePath
,
String
templateWithoutFileEnding
,
Writer
writer
,
NetDefinitionMode
netDefinitionMode
){
...
...
@@ -129,15 +43,7 @@ public class CNNArchTemplateController {
ftlContext
.
put
(
TEMPLATE_CONTROLLER_KEY
,
this
);
ftlContext
.
put
(
ELEMENT_DATA_KEY
,
getCurrentElement
());
ftlContext
.
put
(
NET_DEFINITION_MODE_KEY
,
netDefinitionMode
);
TemplateConfiguration
.
processTemplate
(
ftlContext
,
templatePath
,
writer
);
}
public
void
include
(
String
relativePath
,
String
templateWithoutFileEnding
,
Writer
writer
)
{
String
templatePath
=
relativePath
+
templateWithoutFileEnding
+
FTL_FILE_ENDING