Commit 45598520 authored by Christian Fuß's avatar Christian Fuß
Browse files

merged develop into rnn

parents 26a7c749 aaef2c79
Pipeline #173115 failed with stages
in 23 seconds
......@@ -27,7 +27,7 @@ masterJobLinux:
stage: linux
image: maven:3-jdk-8
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean deploy --settings settings.xml -Dtest=\!Integration*
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean deploy --settings settings.xml
- cat target/site/jacoco/index.html
- mvn package sonar:sonar -s settings.xml
only:
......@@ -36,7 +36,7 @@ masterJobLinux:
masterJobWindows:
stage: windows
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean install --settings settings.xml -Dtest=\!Integration*
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean install --settings settings.xml
tags:
- Windows10
......@@ -44,13 +44,7 @@ BranchJobLinux:
stage: linux
image: maven:3-jdk-8
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean install --settings settings.xml -Dtest=\!Integration*
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean install --settings settings.xml
- cat target/site/jacoco/index.html
except:
- master
PythonWrapperIntegrationTest:
stage: linux
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2pythonwrapper/tests/mvn-swig:latest
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B clean install --settings settings.xml -Dtest=IntegrationPythonWrapperTest
......@@ -8,19 +8,19 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnnarch-gluon-generator</artifactId>
<version>0.2.2-SNAPSHOT</version>
<version>0.2.8-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
<properties>
<!-- .. SE-Libraries .................................................. -->
<CNNArch.version>0.3.2-SNAPSHOT</CNNArch.version>
<CNNTrain.version>0.3.4-SNAPSHOT</CNNTrain.version>
<CNNArch2X.version>0.0.2-SNAPSHOT</CNNArch2X.version>
<CNNArch.version>0.3.3-SNAPSHOT</CNNArch.version>
<CNNTrain.version>0.3.6-SNAPSHOT</CNNTrain.version>
<CNNArch2X.version>0.0.4-SNAPSHOT</CNNArch2X.version>
<embedded-montiarc-math-opt-generator>0.1.4</embedded-montiarc-math-opt-generator>
<EMADL2PythonWrapper.version>0.0.1</EMADL2PythonWrapper.version>
<EMADL2PythonWrapper.version>0.0.2-SNAPSHOT</EMADL2PythonWrapper.version>
<!-- .. Libraries .................................................. -->
<guava.version>18.0</guava.version>
......@@ -239,6 +239,7 @@
<version>2.19.1</version>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
<trimStackTrace>false</trimStackTrace>
</configuration>
</plugin>
<plugin>
......
......@@ -20,16 +20,16 @@
*/
package de.monticore.lang.monticar.cnnarch.gluongenerator;
import de.monticore.lang.monticar.cnnarch._symboltable.IOSymbol;
import de.monticore.lang.monticar.cnnarch.generator.CNNArchGenerator;
import de.monticore.lang.monticar.cnnarch.generator.Target;
import de.monticore.lang.monticar.cnnarch.generator.TemplateConfiguration;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.se_rwth.commons.logging.Log;
import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.cmake.CMakeConfig;
import de.monticore.lang.monticar.generator.cmake.CMakeFindModule;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
public class CNNArch2Gluon extends CNNArchGenerator {
......@@ -52,18 +52,9 @@ public class CNNArch2Gluon extends CNNArchGenerator {
} else {
fileContentMap = compileFileContentMap(architecture);
}
checkValidOutputTypes(architecture);
return fileContentMap;
}
private void checkValidOutputTypes(ArchitectureSymbol architecture) {
if (((IOSymbol)architecture.getOutputs().get(0)).getDefinition().getType().getWidth() != 1
|| ((IOSymbol)architecture.getOutputs().get(0)).getDefinition().getType().getHeight() != 1) {
Log.error("This cnn architecture has a multi-dimensional output, which is currently not supported by" +
" the code generator.", architecture.getSourcePosition());
}
}
private Map<String, String> compilePythonFiles(CNNArch2GluonTemplateController controller, ArchitectureSymbol architecture) {
Map<String, String> fileContentMap = new HashMap<>();
Map.Entry<String, String> temp;
......@@ -120,4 +111,20 @@ public class CNNArch2Gluon extends CNNArchGenerator {
architecture, templateConfiguration);
return compilePythonFiles(archTc, architecture);
}
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;
}
}
\ No newline at end of file
......@@ -22,9 +22,24 @@ public class CNNArch2GluonArchitectureSupportChecker extends ArchitectureSupport
return true;
}
@Override
protected boolean checkMultiDimensionalOutput(ArchitectureSymbol architecture) {
return true;
}
@Override
protected boolean checkConstants(ArchitectureSymbol architecture) {
return true;
}
@Override
protected boolean checkLayerVariables(ArchitectureSymbol architecture) {
return true;
}
@Override
protected boolean checkOutputAsInput(ArchitectureSymbol architecture) {
return true;
}
}
......@@ -29,4 +29,4 @@ public class CNNArch2GluonCli {
GenericCNNArchCli cli = new GenericCNNArchCli(generator);
cli.run(args);
}
}
}
\ No newline at end of file
......@@ -24,6 +24,10 @@ public class CNNArch2GluonLayerSupportChecker extends LayerSupportChecker {
supportedLayerList.add(AllPredefinedLayers.FLATTEN_NAME);
supportedLayerList.add(AllPredefinedLayers.ONE_HOT_NAME);
supportedLayerList.add(AllPredefinedLayers.BEAMSEARCH_NAME);
supportedLayerList.add(AllPredefinedLayers.RNN_NAME);
supportedLayerList.add(AllPredefinedLayers.LSTM_NAME);
supportedLayerList.add(AllPredefinedLayers.GRU_NAME);
supportedLayerList.add(AllPredefinedLayers.EMBEDDING_NAME);
}
}
......@@ -49,20 +49,25 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
getTemplateConfiguration().processTemplate(ftlContext, templatePath, writer);
}
public void include(IOSymbol ioElement, Writer writer, NetDefinitionMode netDefinitionMode){
public void include(VariableSymbol element, Writer writer, NetDefinitionMode netDefinitionMode){
ArchitectureElementData previousElement = getCurrentElement();
setCurrentElement(ioElement);
setCurrentElement(element);
if (ioElement.isAtomic()){
if (ioElement.isInput()){
include(TEMPLATE_ELEMENTS_DIR_PATH, "Input", writer, netDefinitionMode);
if (element.isAtomic()){
if (element.getType() == VariableSymbol.Type.IO) {
if (element.isInput()){
include(TEMPLATE_ELEMENTS_DIR_PATH, "Input", writer, netDefinitionMode);
}
else {
include(TEMPLATE_ELEMENTS_DIR_PATH, "Output", writer, netDefinitionMode);
}
}
else {
include(TEMPLATE_ELEMENTS_DIR_PATH, "Output", writer, netDefinitionMode);
else if (element.getType() == VariableSymbol.Type.LAYER) {
include(TEMPLATE_ELEMENTS_DIR_PATH, element.getLayerVariableDeclaration().getLayer().getName(), writer, netDefinitionMode);
}
}
else {
include(ioElement.getResolvedThis().get(), writer, netDefinitionMode);
include(element.getResolvedThis().get(), writer, netDefinitionMode);
}
setCurrentElement(previousElement);
......@@ -87,7 +92,6 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
setCurrentElement(layer);
if (layer.isAtomic()){
ArchitectureElementSymbol nextElement = layer.getOutputElement().get();
String templateName = layer.getDeclaration().getName();
include(TEMPLATE_ELEMENTS_DIR_PATH, templateName, writer, netDefinitionMode);
}
......@@ -106,7 +110,7 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
include(unrollElement.getBody().getElements().get(0).getResolvedThis().get(), writer, netDefinitionMode);
}
for(int i = 0; i < (int)unrollElement.getIntValue(AllPredefinedLayers.BEAMSEARCH_MAX_LENGTH_NAME).get(); i++) {
for(int i = 0; i < (int)unrollElement.getIntValue(AllPredefinedLayers.BEAMSEARCH_MAX_LENGTH).get(); i++) {
System.err.println("i: " + i);
......@@ -154,7 +158,7 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
include((ConstantSymbol) architectureElement, writer, netDefinitionMode);
}
else {
include((IOSymbol) architectureElement, writer, netDefinitionMode);
include((VariableSymbol) architectureElement, writer, netDefinitionMode);
}
}
......@@ -172,43 +176,173 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
include(architectureElement, getWriter(), netDefinitionMode);
}
public String ioNameToCpp(String ioName) {
return ioName.replaceAll("_([0-9]+)_", "[$1]");
public Set<String> getStreamInputNames(SerialCompositeElementSymbol stream) {
return getStreamInputs(stream).keySet();
}
public List<String> getStreamInputNames(SerialCompositeElementSymbol stream) {
List<String> names = new ArrayList<>();
public Set<String> getUnrollInputNames(UnrollSymbol unroll) {
return getUnrollInputs(unroll).keySet();
}
for (ArchitectureElementSymbol element : stream.getFirstAtomicElements()) {
names.add(getName(element));
}
return names;
public Collection<List<String>> getStreamInputDimensions(SerialCompositeElementSymbol stream) {
return getStreamInputs(stream).values();
}
public Collection<List<String>> getUnrollInputDimensions(UnrollSymbol unroll) {
return getUnrollInputs(unroll).values();
}
public List<String> getStreamOutputNames(SerialCompositeElementSymbol stream) {
List<String> names = new ArrayList<>();
public Set<String> getStreamOutputNames(SerialCompositeElementSymbol stream) {
Set<String> outputNames = new LinkedHashSet<>();
for (ArchitectureElementSymbol element : stream.getLastAtomicElements()) {
names.add(getName(element));
if (element.isOutput()) {
outputNames.add(getName(element));
}
}
outputNames.addAll(getStreamLayerVariableMembers(stream, "1", true).keySet());
return outputNames;
}
public Set<String> getUnrollOutputNames(UnrollSymbol unroll) {
Set<String> outputNames = new LinkedHashSet<>();
for (ArchitectureElementSymbol element : unroll.getBody().getLastAtomicElements()) {
if (element.isOutput()) {
outputNames.add(getName(element));
}
}
return names;
outputNames.addAll(getStreamLayerVariableMembers(unroll.getBody(), "1", true).keySet());
return outputNames;
}
public List<String> getUnrollInputNames(UnrollSymbol unroll) {
List<String> names = new ArrayList<>();
// Used to initialize all layer variable members which are passed through the networks
public Map<String, List<String>> getLayerVariableMembers(String batchSize) {
Map<String, List<String>> members = new LinkedHashMap<>();
for (ArchitectureElementSymbol element : unroll.getFirstAtomicElements()) {
names.add(getName(element));
for (SerialCompositeElementSymbol stream : getArchitecture().getStreams()) {
members.putAll(getStreamLayerVariableMembers(stream, batchSize, true));
}
return names;
return members;
}
public List<String> getUnrollOutputNames(UnrollSymbol unroll) {
List<String> names = new ArrayList<>();
private Map<String, List<String>> getStreamInputs(SerialCompositeElementSymbol stream) {
Map<String, List<String>> inputs = new LinkedHashMap<>();
for (ArchitectureElementSymbol element : stream.getFirstAtomicElements()) {
if (element.isInput() || element.isOutput()) {
List<Integer> intDimensions = element.getOutputTypes().get(0).getDimensions();
List<String> dimensions = new ArrayList<>();
for (Integer intDimension : intDimensions) {
dimensions.add(intDimension.toString());
}
// Add batch size dimension
dimensions.add(0, "1");
for (ArchitectureElementSymbol element : unroll.getLastAtomicElements()) {
names.add(getName(element));
inputs.put(getName(element), dimensions);
}
}
return names;
inputs.putAll(getStreamLayerVariableMembers(stream, "1", false));
return inputs;
}
private Map<String, List<String>> getUnrollInputs(UnrollSymbol unroll) {
Map<String, List<String>> inputs = new LinkedHashMap<>();
for (ArchitectureElementSymbol element : unroll.getBody().getFirstAtomicElements()) {
if (element.isInput() || element.isOutput()) {
List<Integer> intDimensions = element.getOutputTypes().get(0).getDimensions();
List<String> dimensions = new ArrayList<>();
for (Integer intDimension : intDimensions) {
dimensions.add(intDimension.toString());
}
// Add batch size dimension
dimensions.add(0, "1");
inputs.put(getName(element), dimensions);
}
}
inputs.putAll(getStreamLayerVariableMembers(unroll.getBody(), "1", false));
return inputs;
}
private Map<String, List<String>> getStreamLayerVariableMembers(SerialCompositeElementSymbol stream, String batchSize, boolean includeOutput) {
Map<String, List<String>> members = new HashMap<>();
List<ArchitectureElementSymbol> elements = stream.getSpannedScope().resolveLocally(ArchitectureElementSymbol.KIND);
for (ArchitectureElementSymbol element : elements) {
if (element instanceof VariableSymbol) {
VariableSymbol variable = (VariableSymbol) element;
if (variable.getType() == VariableSymbol.Type.LAYER && variable.getMember() == VariableSymbol.Member.NONE) {
LayerVariableDeclarationSymbol layerVariableDeclaration = variable.getLayerVariableDeclaration();
if (layerVariableDeclaration.getLayer().getDeclaration().isPredefined()) {
PredefinedLayerDeclaration predefinedLayerDeclaration =
(PredefinedLayerDeclaration) layerVariableDeclaration.getLayer().getDeclaration();
if (predefinedLayerDeclaration.isValidMember(VariableSymbol.Member.STATE)) {
String name = variable.getName() + "_state_";
List<Integer> intDimensions = predefinedLayerDeclaration.computeOutputTypes(
layerVariableDeclaration.getLayer().getInputTypes(),
layerVariableDeclaration.getLayer(),
VariableSymbol.Member.STATE
).get(0).getDimensions();
List<String> dimensions = new ArrayList<>();
for (Integer intDimension : intDimensions) {
dimensions.add(intDimension.toString());
}
// Add batch size dimension at index 1, since RNN states in Gluon have the format
// (layers, batch_size, units)
dimensions.add(1, batchSize);
members.put(name, dimensions);
}
if (includeOutput) {
if (predefinedLayerDeclaration.isValidMember(VariableSymbol.Member.OUTPUT)) {
String name = variable.getName() + "_output_";
List<Integer> intDimensions = predefinedLayerDeclaration.computeOutputTypes(
layerVariableDeclaration.getLayer().getInputTypes(),
layerVariableDeclaration.getLayer(),
VariableSymbol.Member.OUTPUT
).get(0).getDimensions();
List<String> dimensions = new ArrayList<>();
for (Integer intDimension : intDimensions) {
dimensions.add(intDimension.toString());
}
// Add batch size dimension at index 0, since we use NTC format for RNN output in Gluon
dimensions.add(0, batchSize);
members.put(name, dimensions);
}
}
}
}
}
}
return members;
}
}
package de.monticore.lang.monticar.cnnarch.gluongenerator;
import com.google.common.collect.Maps;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.critic.CriticNetworkGenerationPair;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.critic.CriticNetworkGenerator;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.cnnarch._symboltable.ArchitectureSymbol;
import de.monticore.lang.monticar.cnnarch.gluongenerator.annotations.ArchitectureAdapter;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.FunctionParameterChecker;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.RewardFunctionParameterAdapter;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.RewardFunctionSourceGenerator;
......@@ -10,15 +11,12 @@ import de.monticore.lang.monticar.cnnarch.generator.ConfigurationData;
import de.monticore.lang.monticar.cnnarch.generator.CNNTrainGenerator;
import de.monticore.lang.monticar.cnnarch.generator.TemplateConfiguration;
import de.monticore.lang.monticar.cnntrain._symboltable.ConfigurationSymbol;
import de.monticore.lang.monticar.cnntrain._symboltable.LearningMethod;
import de.monticore.lang.monticar.cnntrain._symboltable.RLAlgorithm;
import de.monticore.lang.monticar.cnntrain._symboltable.RewardFunctionSymbol;
import de.monticore.lang.monticar.cnntrain.annotations.TrainedArchitecture;
import de.monticore.lang.monticar.cnntrain._symboltable.*;
import de.monticore.lang.monticar.generator.FileContent;
import de.monticore.lang.monticar.generator.cpp.GeneratorCPP;
import de.monticore.lang.monticar.generator.pythonwrapper.GeneratorPythonWrapperStandaloneApi;
import de.monticore.lang.monticar.generator.pythonwrapper.symbolservices.data.ComponentPortInformation;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.se_rwth.commons.logging.Log;
import java.io.File;
......@@ -54,13 +52,6 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
@Override
public ConfigurationSymbol getConfigurationSymbol(Path modelsDirPath, String rootModelName) {
ConfigurationSymbol configurationSymbol = super.getConfigurationSymbol(modelsDirPath, rootModelName);
// Generate Reward function if necessary
if (configurationSymbol.getLearningMethod().equals(LearningMethod.REINFORCEMENT)
&& configurationSymbol.getRlRewardFunction().isPresent()) {
generateRewardFunction(configurationSymbol.getRlRewardFunction().get(), modelsDirPath);
}
return configurationSymbol;
}
......@@ -93,17 +84,25 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
}
}
public void generate(Path modelsDirPath, String rootModelName, TrainedArchitecture trainedArchitecture) {
public void generate(Path modelsDirPath,
String rootModelName,
NNArchitectureSymbol trainedArchitecture,
NNArchitectureSymbol criticNetwork) {
ConfigurationSymbol configurationSymbol = this.getConfigurationSymbol(modelsDirPath, rootModelName);
configurationSymbol.setTrainedArchitecture(trainedArchitecture);
configurationSymbol.setCriticNetwork(criticNetwork);
this.setRootProjectModelsDir(modelsDirPath.toString());
generateFilesFromConfigurationSymbol(configurationSymbol);
}
public void generate(Path modelsDirPath, String rootModelName, NNArchitectureSymbol trainedArchitecture) {
generate(modelsDirPath, rootModelName, trainedArchitecture, null);
}
@Override
public Map<String, String> generateStrings(ConfigurationSymbol configuration) {
TemplateConfiguration templateConfiguration = new GluonTemplateConfiguration();
ReinforcementConfigurationData configData = new ReinforcementConfigurationData(configuration, getInstanceName());
GluonConfigurationData configData = new GluonConfigurationData(configuration, getInstanceName());
List<ConfigurationData> configDataList = new ArrayList<>();
configDataList.add(configData);
......@@ -119,24 +118,39 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
final String trainerName = "CNNTrainer_" + getInstanceName();
final RLAlgorithm rlAlgorithm = configData.getRlAlgorithm();
if (rlAlgorithm.equals(RLAlgorithm.DDPG)) {
CriticNetworkGenerator criticNetworkGenerator = new CriticNetworkGenerator();
criticNetworkGenerator.setGenerationTargetPath(
Paths.get(getGenerationTargetPath(), REINFORCEMENT_LEARNING_FRAMEWORK_MODULE).toString());
if (getRootProjectModelsDir().isPresent()) {
criticNetworkGenerator.setRootModelsDir(getRootProjectModelsDir().get());
} else {
Log.error("No root model dir set");
if (rlAlgorithm.equals(RLAlgorithm.DDPG)
|| rlAlgorithm.equals(RLAlgorithm.TD3)) {
if (!configuration.getCriticNetwork().isPresent()) {
Log.error("No architecture model for critic available but is required for chosen " +
"actor-critic algorithm");
}
NNArchitectureSymbol genericArchitectureSymbol = configuration.getCriticNetwork().get();
ArchitectureSymbol architectureSymbol
= ((ArchitectureAdapter)genericArchitectureSymbol).getArchitectureSymbol();
CriticNetworkGenerationPair criticNetworkResult
= criticNetworkGenerator.generateCriticNetworkContent(templateConfiguration, configuration);
CNNArch2Gluon gluonGenerator = new CNNArch2Gluon();
gluonGenerator.setGenerationTargetPath(
Paths.get(getGenerationTargetPath(), REINFORCEMENT_LEARNING_FRAMEWORK_MODULE).toString());
Map<String, String> architectureFileContentMap
= gluonGenerator.generateStringsAllowMultipleIO(architectureSymbol, true);
fileContentMap.putAll(criticNetworkResult.getFileContent().entrySet().stream().collect(Collectors.toMap(
final String creatorName = architectureFileContentMap.keySet().iterator().next();
final String criticInstanceName = creatorName.substring(
creatorName.indexOf('_') + 1, creatorName.lastIndexOf(".py"));
fileContentMap.putAll(architectureFileContentMap.entrySet().stream().collect(Collectors.toMap(
k -> REINFORCEMENT_LEARNING_FRAMEWORK_MODULE + "/" + k.getKey(),
Map.Entry::getValue))
);
ftlContext.put("criticInstanceName", criticNetworkResult.getCriticNetworkName());
ftlContext.put("criticInstanceName", criticInstanceName);
}
// Generate Reward function if necessary
if (configuration.getRlRewardFunction().isPresent()) {
generateRewardFunction(configuration.getRlRewardFunction().get(), Paths.get(rootProjectModelsDir));
}
ftlContext.put("trainerName", trainerName);
......@@ -164,8 +178,11 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
setRootProjectModelsDir(modelsDirPath.toString());
}
rewardFunctionSourceGenerator.generate(getRootProjectModelsDir().get(),
rewardFunctionRootModel, rewardFunctionOutputPath);
final TaggingResolver taggingResolver
= rewardFunctionSourceGenerator.createTaggingResolver(getRootProjectModelsDir().get());