commit 1e535600b1d68f52f4b0acaba4307ea14ee84e8b Author: Matthias Date: Tue Apr 11 15:47:37 2017 +0200 Initial commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..8ef87d6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,42 @@ +cmake_minimum_required(VERSION 2.8) +project(iwir2wfr-compiler Java) + +find_package(Java) +include(UseJava) + +get_directory_property(hasParent PARENT_DIRECTORY) +# Where to install the output +if (NOT hasParent) + if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/dist") + endif() +endif() + +set(CMAKE_JAVA_COMPILE_FLAGS -g:source,lines,vars) + +file(GLOB_RECURSE srcfiles src/*.java) +file(GLOB_RECURSE libfiles lib/*.jar) +add_jar(iwir2wfr-jar + SOURCES ${srcfiles} + INCLUDE_JARS ${libfiles} + ENTRY_POINT at.ac.uibk.iwir2wfr.IWIR2WFRcompiler + OUTPUT_NAME iwir2wfr + OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/iwir2wfr-compiler/dist + MANIFEST ${CMAKE_CURRENT_SOURCE_DIR}/manifest.mf) + + + + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/iwir2wfr-compiler/dist/iwir2wfr.jar DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/lib/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + FILES_MATCHING PATTERN "*.jar" +) +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/ + DESTINATION ${CMAKE_INSTALL_PREFIX}/bin + FILE_PERMISSIONS OWNER_WRITE OWNER_READ OWNER_EXECUTE + GROUP_READ GROUP_EXECUTE + WORLD_READ WORLD_EXECUTE + FILES_MATCHING PATTERN "*.sh" +) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cmake/iwir2wfr-config.cmake DESTINATION ${CMAKE_INSTALL_PREFIX}) diff --git a/Notes.txt b/Notes.txt new file mode 100755 index 0000000..84cac45 --- /dev/null +++ b/Notes.txt @@ -0,0 +1,93 @@ + +================== +=== Blockscope === +================== + +x) Input Hook: +=============== + +*) Collect port values from predecessors (can only be at the same level or immediate parents). + + +x) Output Hook: +================ + +*) Collect port values from children only. + + + + +=================== +=== Atomic Task === +=================== + +x) Input Hook: +=============== + +*) Collect port values from predecessors (can only be at the same level or immediate parents). + + +x) Exec Hook: +============== + +1) Provide input values (declare some pointers and let them point to the input). +2) Execute atomic task. +3) Store output values into output struct. + + + + +============================= +=== Parallel ForEach Task === +============================= + +x) Input Hook: +=============== + +*) Collect port values from predecessors (can only be at the same level or immediate parents, no need to differentiate between input and loopelement ports here). + + +x) Counter Hook: +================= + +*) Calculates the counters start/step/stop out of input values. + + +x) Iteration Hook: +=================== + +*) Is executed after each iteration (useless for parallel loops?) + + +x) Output Hook: +================ + +*) Collect output values from children only (one value for each loop iteration) + + + + +=============== +=== If Task === +=============== + +x) Input Hook: +=============== + +*) Collect port values from predecessors (can only be at the same level or immediate parents, no need to differentiate between input and loopelement ports here). + + +x) Condition Hook: +================= + +*) Evaluates the condition (only needs to be done once before the conditional is executed) + + +x) Output Hook: +================ + +*) Collect port values from children only (Multiple data-link with same to-port because of multiple branches). + + + + diff --git a/bin/iwir2wfr.sh b/bin/iwir2wfr.sh new file mode 100755 index 0000000..99e083f --- /dev/null +++ b/bin/iwir2wfr.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +CWD=`dirname $0` + +CP="" +for jar in $CWD/*.jar; do + CP=$CP:$jar +done +export CLASSPATH=$CP +java at.ac.uibk.iwir2wfr.IWIR2WFRcompiler "$@" diff --git a/build.xml b/build.xml new file mode 100755 index 0000000..df91cc8 --- /dev/null +++ b/build.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/classes/at/ac/uibk/iwir2wfr/GlobalConfig.class b/build/classes/at/ac/uibk/iwir2wfr/GlobalConfig.class new file mode 100755 index 0000000..045afe3 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/GlobalConfig.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.class b/build/classes/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.class new file mode 100755 index 0000000..131b9c5 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator$1.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator$1.class new file mode 100755 index 0000000..97ed5b8 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator$1.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.class new file mode 100755 index 0000000..772ac4f Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.class new file mode 100755 index 0000000..0db0b61 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.class new file mode 100755 index 0000000..94ba16c Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.class new file mode 100755 index 0000000..ae20843 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.class new file mode 100755 index 0000000..07617f2 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.class new file mode 100755 index 0000000..14d8ff7 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.class new file mode 100755 index 0000000..27319db Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.class new file mode 100755 index 0000000..216b950 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.class new file mode 100755 index 0000000..7590a7e Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.class new file mode 100755 index 0000000..4144f9a Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.class b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.class new file mode 100755 index 0000000..be7b218 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository$RepoEntry.class b/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository$RepoEntry.class new file mode 100755 index 0000000..cf550d9 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository$RepoEntry.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.class b/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.class new file mode 100755 index 0000000..1651a34 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType$Type.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType$Type.class new file mode 100755 index 0000000..6e62645 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType$Type.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType.class new file mode 100755 index 0000000..eb29aa5 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrDataType.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$DataLink.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$DataLink.class new file mode 100755 index 0000000..0db2e8e Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$DataLink.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$NodeType.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$NodeType.class new file mode 100755 index 0000000..207c1c6 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$NodeType.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation$TaskImplementationType.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation$TaskImplementationType.class new file mode 100755 index 0000000..ee85242 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation$TaskImplementationType.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation.class new file mode 100755 index 0000000..c477ca9 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode$TaskImplementation.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode.class new file mode 100755 index 0000000..ca2ed60 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrNode.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort$PortType.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort$PortType.class new file mode 100755 index 0000000..1b9ee05 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort$PortType.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort.class new file mode 100755 index 0000000..c12e13c Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPort.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct$IrStructType.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct$IrStructType.class new file mode 100755 index 0000000..606d708 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct$IrStructType.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct.class new file mode 100755 index 0000000..7d3a2f4 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrPortStruct.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrProgram.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrProgram.class new file mode 100755 index 0000000..f135430 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrProgram.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/ir/IrScope.class b/build/classes/at/ac/uibk/iwir2wfr/ir/IrScope.class new file mode 100755 index 0000000..adadbe3 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/ir/IrScope.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/utils/NameUtils.class b/build/classes/at/ac/uibk/iwir2wfr/utils/NameUtils.class new file mode 100755 index 0000000..4362a82 Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/utils/NameUtils.class differ diff --git a/build/classes/at/ac/uibk/iwir2wfr/utils/PrintIR.class b/build/classes/at/ac/uibk/iwir2wfr/utils/PrintIR.class new file mode 100755 index 0000000..01bab0c Binary files /dev/null and b/build/classes/at/ac/uibk/iwir2wfr/utils/PrintIR.class differ diff --git a/cmake/iwir2wfr-config.cmake b/cmake/iwir2wfr-config.cmake new file mode 100755 index 0000000..d3c6666 --- /dev/null +++ b/cmake/iwir2wfr-config.cmake @@ -0,0 +1,8 @@ + +set(SELF_DIR ${CMAKE_CURRENT_LIST_DIR}) + +if (NOT IWIR2WFR_DIR) + set(IWIR2WFR_DIR "$SELF_DIR") +endif() +set(IWIR2WFR_BIN_DIR "${SELF_DIR}/bin") +set(IWIR2WFR_EXE "${IWIR2WFR_BIN_DIR}/iwir2wfr.sh") diff --git a/lib/agwl2iwir-1.4.3.jar b/lib/agwl2iwir-1.4.3.jar new file mode 100755 index 0000000..a3e7b26 Binary files /dev/null and b/lib/agwl2iwir-1.4.3.jar differ diff --git a/lib/commons-cli-2.0.jar b/lib/commons-cli-2.0.jar new file mode 100755 index 0000000..bbe1632 Binary files /dev/null and b/lib/commons-cli-2.0.jar differ diff --git a/lib/iwir2agwl-1.4.4.jar b/lib/iwir2agwl-1.4.4.jar new file mode 100755 index 0000000..dd3ded0 Binary files /dev/null and b/lib/iwir2agwl-1.4.4.jar differ diff --git a/lib/iwirtool-1.1.11.jar b/lib/iwirtool-1.1.11.jar new file mode 100755 index 0000000..e0aa487 Binary files /dev/null and b/lib/iwirtool-1.1.11.jar differ diff --git a/lib/xstream-1.3.1.jar b/lib/xstream-1.3.1.jar new file mode 100755 index 0000000..4ef4219 Binary files /dev/null and b/lib/xstream-1.3.1.jar differ diff --git a/manifest.mf b/manifest.mf new file mode 100755 index 0000000..09c3592 --- /dev/null +++ b/manifest.mf @@ -0,0 +1,2 @@ +Class-Path: agwl2iwir-1.4.3.jar commons-cli-2.0.jar iwir2agwl-1.4.4.jar iwirtool-1.1.11.jar xstream-1.3.1.jar + diff --git a/src/at/ac/uibk/iwir2wfr/GlobalConfig.java b/src/at/ac/uibk/iwir2wfr/GlobalConfig.java new file mode 100755 index 0000000..58edaa1 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/GlobalConfig.java @@ -0,0 +1,144 @@ +package at.ac.uibk.iwir2wfr; + +import java.io.File; +import java.util.Map; + +import org.apache.commons.cli.BasicParser; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; + +public class GlobalConfig { + + static private GlobalConfig singleton = null; + + static public GlobalConfig getInstance() { + if (singleton == null) { + singleton = new GlobalConfig(); + } + return singleton; + } + + private GlobalConfig() {} + + private String inputFileName = null; + private File inputFile = null; + + private String outputFileBaseName = null; + private File outputFileHeader = null; + private File outputFileSource = null; + private boolean skipmain = false; + private boolean printir = false; + private String codeRepoConfig = null; + + public boolean parseCommandLine(String[] args) { + Options options = new Options(); + options.addOption("i", true, "input file"); + options.addOption("o", true, "output file"); + options.addOption("skipmain", false, "skip main"); + options.addOption("printir", false, "print ir"); + options.addOption("repoconfig", true, "code repository config file"); + CommandLineParser parser = new BasicParser(); + try { + CommandLine cmd = parser.parse(options, args); + inputFileName = cmd.getOptionValue("i"); + if (inputFileName == null) { + return false; + } else { + inputFile = new File(inputFileName); + } + outputFileBaseName = cmd.getOptionValue("o"); + if (outputFileBaseName == null) { + return false; + } else { + outputFileHeader = new File(outputFileBaseName + ".h"); + outputFileSource = new File(outputFileBaseName + ".cpp"); + } + skipmain = cmd.hasOption("skipmain"); + printir = cmd.hasOption("printir"); + if (cmd.hasOption("repoconfig")) { + codeRepoConfig = cmd.getOptionValue("repoconfig"); + } + return true; + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + + public String getInputFileName() { + return inputFileName; + } + + + public void setInputFileName(String inputFileName) { + this.inputFileName = inputFileName; + } + + + public File getInputFile() { + return inputFile; + } + + + public void setInputFile(File inputFile) { + this.inputFile = inputFile; + } + + + public String getOutputFileBaseName() { + return outputFileBaseName; + } + + + public void setOutputFileBaseName(String outputFileBaseName) { + this.outputFileBaseName = outputFileBaseName; + } + + + public File getOutputFileHeader() { + return outputFileHeader; + } + + + public void setOutputFileHeader(File outputFileHeader) { + this.outputFileHeader = outputFileHeader; + } + + + public File getOutputFileSource() { + return outputFileSource; + } + + + public void setOutputFileSource(File outputFileSource) { + this.outputFileSource = outputFileSource; + } + + + public boolean isSkipmain() { + return skipmain; + } + + + public void setSkipmain(boolean skipmain) { + this.skipmain = skipmain; + } + + public boolean isPrintIr() { + return printir; + } + + public void setPrintIr(boolean printir) { + this.printir = printir; + } + + public String getCodeRepoConfig() { + return codeRepoConfig; + } + + + +} diff --git a/src/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.java b/src/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.java new file mode 100755 index 0000000..274b08f --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/IWIR2WFRcompiler.java @@ -0,0 +1,54 @@ +package at.ac.uibk.iwir2wfr; + +import java.io.FileNotFoundException; +import java.io.IOException; + +import org.shiwa.fgi.iwir.IWIR; +import org.shiwa.fgi.iwir.NotWellFormedException; + +import at.ac.uibk.iwir2wfr.codegenerator.HeaderFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.coderepository.CodeRepository; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.utils.PrintIR; + +public class IWIR2WFRcompiler { + + + /** + * @param args + */ + public static void main(String[] args) { + GlobalConfig config = GlobalConfig.getInstance(); + config.parseCommandLine(args); + + IWIR iwir = null; + try { + iwir = new IWIR(config.getInputFile()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + System.exit(1); + } catch (NotWellFormedException e) { + e.printStackTrace(); + System.exit(1); + } + + CodeRepository.getInstance(); + + IrProgram program = new IrProgram(); + program.analyseIwirProgram(iwir); + + if (config.isPrintIr()) { + PrintIR.printIR(System.out, program); + } + + try { + HeaderFileGenerator.generateHeaderFile(program); + SourceFileGenerator.generateSourceFile(program); + } catch (IOException e) { + e.printStackTrace(); + } + + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.java new file mode 100755 index 0000000..8ab0f5a --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/HeaderFileGenerator.java @@ -0,0 +1,169 @@ +package at.ac.uibk.iwir2wfr.codegenerator; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Vector; + +import at.ac.uibk.iwir2wfr.GlobalConfig; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrDataType.Type; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; +import at.ac.uibk.iwir2wfr.ir.IrPortStruct; +import at.ac.uibk.iwir2wfr.ir.IrPortStruct.IrStructType; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.utils.NameUtils; + +public class HeaderFileGenerator { + + public static void generateHeaderFile(IrProgram program) throws IOException { + GlobalConfig config = GlobalConfig.getInstance(); + FileWriter writer = new FileWriter(config.getOutputFileHeader()); + + // Prolog + String useOnceId = NameUtils.escapeIdentifierName(config.getOutputFileHeader().getName()).toUpperCase().replace('-', '_'); + writer.write("#ifndef " + useOnceId + " \n#define " + useOnceId + " \n\n"); + writer.write("#include \n\n"); + + // Retrieve sorted list of PortStructs + Collection portStructs = program.getGlobalScope().getPortStructs(); + List sortedPortStructs = new Vector(portStructs); + Collections.sort(sortedPortStructs, new Comparator() { + @Override + public int compare(IrPortStruct o1, IrPortStruct o2) { + return (int) (o1.getId() - o2.getId()); + } + }); + + for (IrPortStruct s : sortedPortStructs) { + writer.write("\n/* " + s.getParentNode().getNodeName() + " " + s.getStructType() + " */\n"); + writer.write("WFR_PORT_STRUCT( " + s.getName() + ", " + s.getId() + ", \\\n"); + for (IrPort p : s.getMembers()) { + if (p.getPortType() == PortType.LoopPort && s.getStructType() == IrStructType.INSTRUCT) { + switch (p.getDataType().getType()) { + case IWIRBOOL: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_bool) \\\n"); + break; + case IWIRINT: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_int) \\\n"); + break; + case IWIRDOUBLE: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_double) \\\n"); + break; + case IWIRSTRING: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_string) \\\n"); + break; + case IWIRFILE: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_file) \\\n"); + break; + case IWIRCOLLECTION: + if (p.getDataType().getCollectionNestingLevel() > 1) { + throw new RuntimeException("Collection with nesting level > 1 not supported yet."); + } + if (p.getDataType().getCollectionDataType() == Type.CUSTOMTYPE) { + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_collection<" + p.getDataType().getCustomType() + ">) \\\n"); + } else { + String typestr = ""; + switch (p.getDataType().getCollectionDataType()) { + case IWIRBOOL: + typestr = "wfr::lwd::_lwd_iwir_basetype_bool"; + break; + case IWIRDOUBLE: + typestr = "wfr::lwd::_lwd_iwir_basetype_double"; + break; + case IWIRINT: + typestr = "wfr::lwd::_lwd_iwir_basetype_int"; + break; + case IWIRSTRING: + typestr = "wfr::lwd::_lwd_iwir_basetype_string"; + break; + case IWIRFILE: + typestr = "wfr::lwd::_lwd_iwir_basetype_file"; + break; + default: + throw new RuntimeException("Error"); + } + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::iwir_collection<" + typestr + ">) \\\n"); + } + break; + case CUSTOMTYPE: + writer.write("\tWFR_PORT_MEMBER_LOOPPORT(" + p.getName() + ", wfr::lwd::_lwd_member_type<" + p.getDataType().getCustomType() + ">) \\\n"); + break; + default: + writer.write("\t<> \\\n"); + break; + } + } else { + switch (p.getDataType().getType()) { + case IWIRBOOL: + writer.write("\tWFR_PORT_MEMBER_IWIRBOOL(" + p.getName() + ") \\\n"); + break; + case IWIRINT: + writer.write("\tWFR_PORT_MEMBER_IWIRINT(" + p.getName() + ") \\\n"); + break; + case IWIRDOUBLE: + writer.write("\tWFR_PORT_MEMBER_IWIRDOUBLE(" + p.getName() + ") \\\n"); + break; + case IWIRSTRING: + writer.write("\tWFR_PORT_MEMBER_IWIRSTRING(" + p.getName() + ") \\\n"); + break; + case IWIRFILE: + writer.write("\tWFR_PORT_MEMBER_IWIRFILE(" + p.getName() + ") \\\n"); + break; + case IWIRCOLLECTION: + { + String baseType = ""; + if (p.getDataType().getCollectionDataType() == Type.CUSTOMTYPE) { + baseType = p.getDataType().getCustomType(); + } else { + switch (p.getDataType().getCollectionDataType()) { + case IWIRBOOL: + baseType = "wfr::lwd::_lwd_iwir_basetype_bool"; + break; + case IWIRDOUBLE: + baseType = "wfr::lwd::_lwd_iwir_basetype_double"; + break; + case IWIRINT: + baseType = "wfr::lwd::_lwd_iwir_basetype_int"; + break; + case IWIRSTRING: + baseType = "wfr::lwd::_lwd_iwir_basetype_string"; + break; + case IWIRFILE: + baseType = "wfr::lwd::_lwd_iwir_basetype_file"; + break; + default: + throw new RuntimeException("Error"); + } + } + writer.write("\tWFR_PORT_MEMBER_IWIRCOLLECTION(" + p.getName() + ", " + baseType + ", " + p.getDataType().getCollectionNestingLevel() + ") \\\n"); + break; + } + case CUSTOMTYPE: + writer.write("\tWFR_PORT_MEMBER(" + p.getName() + ", " + p.getDataType().getCustomType() + ") \\\n"); + break; + default: + writer.write("\t<> \\\n"); + break; + } + } + } + writer.write(")\n"); + } + + // Epilog + IrNode topLevel = program.getTopLeveNode(); + writer.write("\n\nint wfstart(" + topLevel.getInPortStruct().getName() + " &wfInput, " + topLevel.getOutPortStruct().getName() + " &wfOutput, int argc = 0, char** argv = nullptr);\n\n"); + writer.write("\n#endif /* " + useOnceId + " */\n"); + + writer.flush(); + writer.close(); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.java new file mode 100755 index 0000000..db43451 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/SourceFileGenerator.java @@ -0,0 +1,434 @@ +package at.ac.uibk.iwir2wfr.codegenerator; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Vector; + +import at.ac.uibk.iwir2wfr.GlobalConfig; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.BlockScopeGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.ForEachGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.ForGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.IfGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.ParallelForEachGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.ParallelForGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.TaskGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.taskspecific.WhileGenerator; +import at.ac.uibk.iwir2wfr.coderepository.CodeRepository; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; + + +public class SourceFileGenerator { + + public static void generateSourceFile(IrProgram program) throws IOException { + GlobalConfig config = GlobalConfig.getInstance(); + FileWriter writer = new FileWriter(config.getOutputFileSource()); + IrNode tlNode = program.getTopLeveNode(); + + Vector nodes = program.getNodes(); + + // Prolog + writer.write("#include \"" + config.getOutputFileHeader().getName() + "\"\n"); + writer.write("#include \n"); + writer.write("#include \n"); + CodeRepository repo = CodeRepository.getInstance(); + String sourceIncludes = repo.getSourceIncludes(); + if (sourceIncludes != null && !sourceIncludes.isEmpty()) { + writer.write(sourceIncludes); + } + writer.write("\n"); + + // Hook functions + for (IrNode n : program.getNodes()) { + writeHookFunctions(writer, n, program); + } + + // Activity implementations tables + for (IrNode n : program.getNodes()) { + if (n.getNodeType() == NodeType.AtomicNode) { + writeImplementationTables(writer, n, program); + } + } + + // Workflow table + writer.write("\n\n" + StringConstants.wfStructMacro + "(" + StringConstants.wfStructDefaultName + ", \"" + program.getWfName() + "\", " + + StringConstants.wfActivityStructDefaultName + ", " + tlNode.getId() + ", \\\n"); + for (IrNode n : nodes) { + writeActivityTableEntry(writer, n, program); + } + writer.write(");\n"); + + // wfstart function + writer.write("\n\nint wfstart(" + tlNode.getInPortStruct().getName() + " &wfInput, " + tlNode.getOutPortStruct().getName() + + " &wfOutput, int argc, char** argv) {\n" + + "\twfr::WorkflowRuntime::init(argc, argv);\n" + + "\t" + StringConstants.wfStructDefaultName + "->execute(&wfInput, &wfOutput);\n" + + "\twfr::WorkflowRuntime::finish();\n" + + "\treturn 0;\n" + + "}\n"); + + // main function + if (config.isSkipmain()) { + String wfInputCode = repo.getWfInputCode(); + String wfOutputCode = repo.getWfOutputCode(); + writer.write("\n\nint main(int argc, char** argv) {\n" + + "\n\t" + tlNode.getInPortStruct().getName() + " wfInput;\n" + + "\t// Fill workflow input struct\n" + + (wfInputCode == null ? "" : wfInputCode) + + "\n\t" + tlNode.getOutPortStruct().getName() + " wfOutput;\n" + + "\n\twfstart(wfInput, wfOutput, argc, argv);\n" + + "\t// Do something with workflow output\n" + + (wfOutputCode == null ? "" : wfOutputCode) + + "\n\treturn 0;\n" + + "}\n"); + } + + writer.flush(); + writer.close(); + } + + + private static void writeActivityTableEntry(FileWriter writer, IrNode node, IrProgram program) throws IOException { + switch (node.getNodeType()) { + case AtomicNode: + TaskGenerator.writeActivityTableEntry(writer, program, node); + break; + case BlockScopeNode: + BlockScopeGenerator.writeActivityTableEntry(writer, program, node); + break; + case ForEachNode: + ForEachGenerator.writeActivityTableEntry(writer, program, node); + break; + case ForNode: + ForGenerator.writeActivityTableEntry(writer, program, node); + break; + case IfNode: + IfGenerator.writeActivityTableEntry(writer, program, node); + break; + case ParallelForEachNode: + ParallelForEachGenerator.writeActivityTableEntry(writer, program, node); + break; + case ParallelForNode: + ParallelForGenerator.writeActivityTableEntry(writer, program, node); + break; + case WhileNode: + WhileGenerator.writeActivityTableEntry(writer, program, node); + break; + default: + break; + } + } + + private static void writeHookFunctions(FileWriter writer, IrNode node, IrProgram program) throws IOException { + if (node.getInputHookName() == null) { + node.setInputHookName(node.getNodeName() + StringConstants.inputHookFuncPostfix); + } + if (node.getOutputHookName() == null) { + node.setOutputHookName(node.getNodeName() + StringConstants.outputHookFuncPostfix); + } + if (node.getForCounterHookName() == null) { + node.setForCounterHookName(node.getNodeName() + StringConstants.forCounterHookFuncPostfix); + } + if (node.getLoopIterationHookName() == null) { + node.setLoopIterationHookName(node.getNodeName() + StringConstants.loopIterationHookFuncPostfix); + } + if (node.getWhileConditionHookName() == null) { + node.setWhileConditionHookName(node.getNodeName() + StringConstants.whileConditionHookFuncPostfix); + } + if (node.getBranchConditionHookName() == null) { + node.setBranchConditionHookName(node.getNodeName() + StringConstants.branchConditionHookFuncPostfix); + } + if (node.getBranchConditionHookName() == null) { + node.setBranchConditionHookName(node.getNodeName() + StringConstants.branchConditionHookFuncPostfix); + } + if (node.getExecHookName() == null) { + node.setExecHookName(node.getNodeName() + StringConstants.execHookFuncPostfix); + } + switch (node.getNodeType()) { + case AtomicNode: + TaskGenerator.writeHookFunctions(writer, program, node); + break; + case BlockScopeNode: + BlockScopeGenerator.writeHookFunctions(writer, program, node); + break; + case ForEachNode: + ForEachGenerator.writeHookFunctions(writer, program, node); + break; + case ForNode: + ForGenerator.writeHookFunctions(writer, program, node); + break; + case IfNode: + IfGenerator.writeHookFunctions(writer, program, node); + break; + case ParallelForEachNode: + ParallelForEachGenerator.writeHookFunctions(writer, program, node); + break; + case ParallelForNode: + ParallelForGenerator.writeHookFunctions(writer, program, node); + break; + case WhileNode: + WhileGenerator.writeHookFunctions(writer, program, node); + break; + default: + break; + } + } + + private static void writeImplementationTables(FileWriter writer, IrNode node, IrProgram program) throws IOException { + if (node.getNodeType() == NodeType.AtomicNode) { + TaskGenerator.writeImplementationTables(writer, node, program); + } + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.inputHookMacroName + "(" + task.getInputHookName() + ") {\n"); + writer.write("\t" + StringConstants.inputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfInputBufferInitMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + + // Iterate through input ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getInPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sin->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sin->" + pm.getName() + ".isReady()"; + } + + // Fetch values from predecessors + int varIndex = 1; + for (IrNode fn : task.getInPortNodeMap().keySet()) { + + // predecessor is parent (therefore we access the parents input buffer) + if (task.getParent() == fn) { + // Write get macro and after that the beginning of the protecting if block + writer.write("\t" + StringConstants.parentInputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + task.getParent().getInPortStruct().getName() + ", a" + varIndex + ");\n"); + + // predecessor is on same level (therefore we access the predecessors output buffer) + } else if (fn.getParent() == task.getParent()) { // same-level tasks + writer.write("\t" + StringConstants.predOutputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + ", " + + task.getPredecessorsIndex(fn, true) + ");\n"); + + // Error: unexpected predecessor level + } else { + throw new RuntimeException("writeInputHookFunction - remote task \"" + fn.getNodeName() + "\" is not a child nor a parent"); + } + + writer.write("\tif (a" + varIndex + "in != nullptr) {\n"); + // Inside if block iterate over all data-links from same predecessor + Vector fnPorts = task.getInPortNodeMap().get(fn); + for (IrPort toPort : fnPorts) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + if (fromPort.getPortType() == PortType.LoopElements) { + if (toPort.getPortType() == PortType.LoopPort) { + writer.write("\t\t" + StringConstants.loopPortBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, + StringConstants.selfGetIterationIdMacro + "()", "1", true) + ";\n"); + } else { + writer.write("\t\t" + StringConstants.loopPortBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, + StringConstants.selfGetIterationIdMacro + "()", true) + ";\n"); + } + } else if (fromPort.getPortType() == PortType.LoopCounter) { + + writer.write("\t\t" + StringConstants.forloopGetCounterValue + "(a" + varIndex + ", sin->" + toPort.getName() + ");\n"); + + } else if (fromPort.getPortType() == PortType.LoopPort) { + + if (toPort.getDataType().equals(fromPort.getDataType())) { + if (fromPort.getParentNode().equals(toPort.getParentNode().getParent())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, StringConstants.selfGetIterationIdMacro + "()", true) + ";\n"); + } else { + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, true) + ";\n"); + } + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + throw new RuntimeException("ToDo: Not implemented yet."); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + + } else if (toPort.getPortType() == PortType.LoopPort) { + + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, "1", true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + throw new RuntimeException("ToDo: Not implemented yet."); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + + } else { + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", toPort, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t" + StringConstants.finalizeCollection + "(sin, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + } + writer.write("\t}\n"); + + varIndex++; + } + + // Build check2-string (adds loop checks to check-string if parent is a loop) + String check2 = ""; + isFirst = true; + if (task.getParent() != null) { + if (task.getParent().getNodeType() == NodeType.ForEachNode + || task.getParent().getNodeType() == NodeType.ForNode + || task.getParent().getNodeType() == NodeType.WhileNode) { + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + check2 += StringConstants.parentIsPrevIterFinished + "()"; + } + } + // write checkReadyForExecution Macro + if (task.getNodeType() != NodeType.ForEachNode + && task.getNodeType() != NodeType.ParallelForEachNode + && task.getNodeType() != NodeType.ForNode + && task.getNodeType() != NodeType.ParallelForNode + && task.getNodeType() != NodeType.WhileNode + && task.getNodeType() != NodeType.IfNode + && task.getNodeType() != NodeType.BlockScopeNode) { + if (!check2.isEmpty() && !checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckReadyForExecution2 + "(" + checkString + ", " + check2 + ");\n"); + } else if (!check2.isEmpty() && checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckReadyForExecution2 + "(true, " + check2 + ");\n"); + } else if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckReadyForExecution + "(" + checkString + ");\n"); + } + } + // Epilog + writer.write("\t" + StringConstants.inputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + // Fetch values from remotely connected ports (only for output-ports) + int varIndex = 1; + + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + if (task.getParent() == fn) { // parent task + writer.write("\t" + StringConstants.parentOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + ");\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + } else if (fn.getParent() == task) { // child task + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + + ", " + fn.getId() +", " + fn.inParentBranch() + ");\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } + writer.write("\t}\n"); + } else if (task == fn) { // same node + throw new RuntimeException("task and fn are the same node"); + } + varIndex++; + } + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static String getIrNodeSuccessorString(IrNode task) { + String sucs = "{"; + boolean isFirst = true; + for (IrNode n : task.getSuccessors(true)) { + if (n != task) { + if (isFirst) { + isFirst = false; + } else { + sucs += ", "; + } + sucs += n.getId(); + } + } + sucs += "}"; + return sucs; + } + + + public static String getIrNodePredecessorString(IrNode task) { + String preds = "{"; + boolean isFirst = true; + for (IrNode n : task.getPredecessors(true)) { + if (n != task) { + if (isFirst) { + isFirst = false; + } else { + preds += ", "; + } + preds += n.getId(); + } + } + preds += "}"; + return preds; + } + + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.java b/src/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.java new file mode 100755 index 0000000..7003d95 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/StringConstants.java @@ -0,0 +1,216 @@ +package at.ac.uibk.iwir2wfr.codegenerator; + +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrDataType.Type; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; + +public class StringConstants { + + public static final String inputHookMacroName = "WFR_INPUT_HOOK"; + public static final String inputHookFuncPostfix = "InputFunc"; + public static final String inputPrologMacroName = "WFR_INPUT_HOOK_PROLOG"; + public static final String inputEpilogMacroName = "WFR_INPUT_HOOK_EPILOG"; + + public static final String outputHookMacroName = "WFR_OUTPUT_HOOK"; + public static final String outputHookFuncPostfix = "OutputFunc"; + public static final String outputPrologMacroName = "WFR_OUTPUT_HOOK_PROLOG"; + public static final String outputEpilogMacroName = "WFR_OUTPUT_HOOK_EPILOG"; + + public static final String selfInputBufferInitMacro = "WFR_SELF_INBUFFER_INIT"; + public static final String selfInputBufferGetMacro = "WFR_SELF_INBUFFER_GET"; + public static final String childInputBufferInitMacro = "WFR_CHILD_INBUFFER_INIT"; + public static final String childInputBufferGetMacro = "WFR_CHILD_INBUFFER_GET"; + public static final String parentInputBufferInitMacro = "WFR_PARENT_INBUFFER_INIT"; + public static final String parentInputBufferGetMacro = "WFR_PARENT_INBUFFER_GET"; + public static final String instanceInputBufferInitMacro = "WFR_INSTANCE_INBUFFER_INIT"; + public static final String instanceInputBufferGetMacro = "WFR_INSTANCE_INBUFFER_GET"; + public static final String predInputBufferInitMacro = "WFR_PRED_INBUFFER_INIT"; + public static final String predInputBufferGetMacro = "WFR_PRED_INBUFFER_GET"; + public static final String succInputBufferInitMacro = "WFR_SUCC_INBUFFER_INIT"; + public static final String succInputBufferGetMacro = "WFR_SUCC_INBUFFER_GET"; + + public static final String selfOutputBufferInitMacro = "WFR_SELF_OUTBUFFER_INIT"; + public static final String selfOutputBufferGetMacro = "WFR_SELF_OUTBUFFER_GET"; + public static final String childOutputBufferInitMacro = "WFR_CHILD_OUTBUFFER_INIT"; + public static final String childOutputBufferGetMacro = "WFR_CHILD_OUTBUFFER_GET"; + public static final String parentOutputBufferInitMacro = "WFR_PARENT_OUTBUFFER_INIT"; + public static final String parentOutputBufferGetMacro = "WFR_PARENT_OUTBUFFER_GET"; + public static final String instanceOutputBufferInitMacro = "WFR_INSTANCE_OUTBUFFER_INIT"; + public static final String instanceOutputBufferGetMacro = "WFR_INSTANCE_OUTBUFFER_GET"; + public static final String predOutputBufferInitMacro = "WFR_PRED_OUTBUFFER_INIT"; + public static final String predOutputBufferGetMacro = "WFR_PRED_OUTBUFFER_GET"; + public static final String succOutputBufferInitMacro = "WFR_SUCC_OUTBUFFER_INIT"; + public static final String succOutputBufferGetMacro = "WFR_SUCC_OUTBUFFER_GET"; + + public static final String outbufferVarPostfix = "out"; + public static final String inbufferVarPostfix = "in"; + + public static final String hookSetRetvalMacro = "WFR_HOOK_SET_RETVAL"; + public static final String portbufferCopyMacro = "portbuffer_copy"; + public static final String portbufferCopyFlattenMacro = "portbuffer_copy_flatten"; + + public static final String execHookMacroName = "WFR_EXEC_HOOK"; + public static final String execHookFuncPostfix = "ExecFunc"; + public static final String execPrologMacroName = "WFR_EXEC_HOOK_PROLOG"; + public static final String execEpilogMacroName = "WFR_EXEC_HOOK_EPILOG"; + + public static final String forCounterHookMacroName = "WFR_FORCOUNTER_HOOK"; + public static final String forCounterHookFuncPostfix = "CounterFunc"; + public static final String forCounterPrologMacroName = "WFR_FORCOUNTER_HOOK_PROLOG"; + public static final String forCounterEpilogMacroName = "WFR_FORCOUNTER_HOOK_EPILOG"; + + public static final String loopIterationHookMacroName = "WFR_LOOPITERATION_HOOK"; + public static final String loopIterationHookFuncPostfix = "IterationFunc"; + public static final String loopIterationPrologMacroName = "WFR_LOOPITERATION_HOOK_PROLOG"; + public static final String loopIterationEpilogMacroName = "WFR_LOOPITERATION_HOOK_EPILOG"; + + public static final String whileConditionHookMacroName = "WFR_WHILECONDITION_HOOK"; + public static final String whileConditionHookFuncPostfix = "WhileConditionFunc"; + public static final String whileConditionPrologMacroName = "WFR_WHILECONDITION_HOOK_PROLOG"; + public static final String whileConditionEpilogMacroName = "WFR_WHILECONDITION_HOOK_EPILOG"; + + public static final String branchConditionHookMacroName = "WFR_BRANCHCONDITION_HOOK"; + public static final String branchConditionHookFuncPostfix = "BranchConditionFunc"; + public static final String branchConditionPrologMacroName = "WFR_BRANCHCONDITION_HOOK_PROLOG"; + public static final String branchConditionEpilogMacroName = "WFR_BRANCHCONDITION_HOOK_EPILOG"; + + public static final String portInitCollectionMacro = "WFR_PORT_INIT_COLLECTION"; + + public static final String activityImpementationsMacro = "WFR_ACTIVITY_IMPLEMENTATIONS"; + public static final String activityImplementationsStructPostfix = "Implementations"; + public static final String activityImplementationPthreadsClass = "wfr::wfs::AtomicActivityImplementation::PThread"; + public static final String activityImplementationCudaClass = "wfr::wfs::AtomicActivityImplementation::CUDA"; + public static final String activityImplementationOpenClClass = "wfr::wfs::AtomicActivityImplementation::OpenCL"; + public static final String activityImplementationUnknownClass = "wfr::wfs::ActivityImplementation::UnknownImplementation"; + + public static final String wfStructMacro = "WFR_WORKFLOW"; + public static final String wfStructDefaultName = "workflow"; + public static final String wfActivityStructDefaultName = "wfActivityTable"; + + public static final String activityTemplateAtomicConstructor = "wfr::wfs::ActivityTemplate::atomic"; + public static final String activityTemplateAssignConstructor = "wfr::wfs::ActivityTemplate::assign"; + public static final String activityTemplateContainerConstructor = "wfr::wfs::ActivityTemplate::container"; + public static final String activityTemplateForLoopConstructor = "wfr::wfs::ActivityTemplate::forLoop"; + public static final String activityTemplateWhileLoopConstructor = "wfr::wfs::ActivityTemplate::whileLoop"; + public static final String activityTemplateConditionalConstructor = "wfr::wfs::ActivityTemplate::conditional"; + + public static final String collectOutvaluesFromChildrenMacro = "WFR_COLLECT_OUTVALUES_FROM_CHILDREN"; + public static final String collectOutvaluesFromChildrenFlattenMacro = "WFR_COLLECT_OUTVALUES_FROM_CHILDREN_FLATTEN"; + + public static final String selfCheckAllInputsAvailable = "WFR_SELF_CHECK_AREALLINPUTSAVAILABLE"; + public static final String selfCheckReadyForExecution = "WFR_SELF_CHECK_ISREADYFOREXECUTION"; + public static final String selfCheckReadyForExecution2 = "WFR_SELF_CHECK_ISREADYFOREXECUTION2"; + + public static final String selfCheckAllOutputsAvailable = "WFR_SELF_CHECK_AREALLOUTPUTSAVAILABLE"; + + public static final String parentIsPrevIterFinished = "WFR_PARENT_ISPREVITERFINISHED"; + + public static final String selfGetIterationIdMacro = "WFR_SELF_GETITERATIONID"; + + public static final String selfGetIterationCountMacro = "WFR_SELF_GETITERATIONCOUNT"; + + public static final String selfGetCondBranchIdMacro = "WFR_SELF_GETCONDBRANCHID"; + + public static final String loopFinalizeCollection = "WFR_LOOP_FINALIZE_COLLECTION"; + + public static final String finalizeCollection = "WFR_FINALIZE_COLLECTION"; + + public static final String loopFinalize = "WFR_LOOP_FINALIZE"; + + public static final String forloopGetCounterValue = "WFR_FORLOOP_GET_COUNTER_VALUE"; + + public static final String selfSetForLoopCounterValues = "WFR_SELF_SETFORLOOPCOUNTERVALUES"; + + public static final String selfGetHandledIterationCount = "WFR_SELF_GETHANDLEDITERATIONCOUNT"; + + public static final String iwirConstraintFlattenCollection = "flatten-collection"; + + public static final String iwirPropertyAssignActivity = "assign-activity"; + + + + public static String portBufferCopy(String destStruct, IrPort dest, String srcStruct, IrPort src, boolean retvalHook) { + String retval = ""; + if (dest.getDataType().equals(src.getDataType())) { + if (dest.hasIwirConstraint(iwirConstraintFlattenCollection)) { + String flattenValue = dest.getIwirConstraint(iwirConstraintFlattenCollection); + retval = portbufferCopyFlattenMacro + "<" + flattenValue + ">(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ")"; + } else { + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ")"; + } + } else { + throw new RuntimeException("portBufferCopy: src and dest differ in data type."); + } + if (retvalHook) { + return hookSetRetvalMacro + "( " + retval + ")"; + } else { + return retval; + } + } + + public static String portBufferCopy(String destStruct, IrPort dest, String srcStruct, IrPort src, String index, boolean retvalHook) { + String retval = ""; + // ToDo Validity Checks. + //if (dest.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION || dest.getPortType() == PortType.LoopPort || src.getPortType() == PortType.LoopPort) { + if ( (dest.getDataType().getCollectionNestingLevel() > 0 && dest.getDataType().getCollectionNestingLevel() > src.getDataType().getCollectionNestingLevel()) + || dest.getPortType() == PortType.LoopPort || src.getPortType() == PortType.LoopPort ) { + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ", " + index + ")"; + } else { + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ".getEntry(" + index + "))"; + } + if (retvalHook) { + return hookSetRetvalMacro + "( " + retval + ")"; + } else { + return retval; + } + } + + public static String portBufferCopyLoopPortDest(String destStruct, IrPort dest, String srcStruct, IrPort src, String index, boolean retvalHook) { + String retval = ""; + // ToDo Validity Checks. + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ".getValue(), " + srcStruct + src.getName() + ", " + index + ")"; + if (retvalHook) { + return hookSetRetvalMacro + "( " + retval + ")"; + } else { + return retval; + } + } + + public static String loopPortBufferCopy(String destStruct, IrPort dest, String srcStruct, IrPort src, String index, boolean retvalHook) { + String retval = ""; + if (IrDataType.loopPortMatch(src, dest)) { + //if (dest.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION || dest.getPortType() == PortType.LoopPort || src.getPortType() == PortType.LoopPort) { + if ( (dest.getDataType().getCollectionNestingLevel() > 0 && dest.getDataType().getCollectionNestingLevel() > src.getDataType().getCollectionNestingLevel()) + || dest.getPortType() == PortType.LoopPort || src.getPortType() == PortType.LoopPort ) { + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ", " + index + ")"; + } else { + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ".getEntry(" + index + "))"; + } + } else { + throw new RuntimeException("loopPortBufferCopy: src and dest types do not match."); + } + if (retvalHook) { + return hookSetRetvalMacro + "( " + retval + ")"; + } else { + return retval; + } + } + + public static String loopPortBufferCopy(String destStruct, IrPort dest, String srcStruct, IrPort src, String index, String nextIter, boolean retvalHook) { + String retval = ""; + if (IrDataType.loopPortMatch(src, dest)) { + //retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ", " + index + ", " + nextIter + ")"; + retval = portbufferCopyMacro + "(" + destStruct + dest.getName() + ", " + srcStruct + src.getName() + ".getEntry(" + index + "), " + nextIter + ")"; + } else { + throw new RuntimeException("loopPortBufferCopy: src and dest types do not match."); + } + if (retvalHook) { + return hookSetRetvalMacro + "( " + retval + ")"; + } else { + return retval; + } + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.java new file mode 100755 index 0000000..553e990 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/BlockScopeGenerator.java @@ -0,0 +1,126 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrDataType; + + +public class BlockScopeGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + // Fetch values from childrens output ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + + // child task + if (fn.getParent() == task) { + // Write get macro and after that the beginning of the protecting if block + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + + ", " + fn.getId() +", 0);\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + // Inside if block iterate over all data-links from same predecessor + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + } else if (fn == task) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (sin != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode() == task) { + fromPort = tmp; + break; + } + } + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "sin->", fromPort, true) + ";\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + // Error: unexpected predecessor level + } else { + throw new RuntimeException("writeInputHookFunction - remote task \"" + fn.getNodeName() + "\" is not a child nor a parent"); + } + varIndex++; + } + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateContainerConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.java new file mode 100755 index 0000000..6d3fcc1 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForEachGenerator.java @@ -0,0 +1,250 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import java.io.IOException; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; +import at.ac.uibk.iwir2wfr.ir.IrProgram; + +public class ForEachGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeCounterHookFunction(writer, program, task); + writeIterationHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getCollectionNestingLevel() > 0) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + writer.write("\n"); + // Fetch values from childrens output ports + // At first union ports + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Union Port + if (toPort.getPortType() == PortType.UnionPort) { + if (toPort.hasIwirConstraint(StringConstants.iwirConstraintFlattenCollection)) { + String flattenValue = toPort.getIwirConstraint(StringConstants.iwirConstraintFlattenCollection); + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenFlattenMacro + "(sout->" + toPort.getName() + + ", " + flattenValue + ", " + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + + fn.getId() + ");\n"); + } else { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenMacro + "(sout->" + toPort.getName() + ", " + + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + fn.getId() + ");\n"); + writer.write("\t" + StringConstants.loopFinalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } + } + } + } + } + // Then the other ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + // Write get macro and after that the beginning of the protecting if block + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + + ", " + fn.getId() +", " + StringConstants.selfGetHandledIterationCount + "()-1" + ");\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Out Port + if (toPort.getPortType() == PortType.OutPort) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t\tif (" + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + // Loop Port + } else if (toPort.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t\tif (" + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + } else { + throw new RuntimeException("fromPort is null."); + } + } + } + writer.write("\t}\n"); + varIndex++; + } else if (fn == task) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (sin != nullptr && "+ StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode() == task) { + fromPort = tmp; + break; + } + } + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "sin->", fromPort, StringConstants.selfGetHandledIterationCount + "()", true) + ";\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + } + } + writer.write("\n"); + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + + public static void writeCounterHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.forCounterHookMacroName + "(" + task.getForCounterHookName() + ") {\n"); + writer.write("\t" + StringConstants.forCounterPrologMacroName + ";\n"); + + String minCountString = "\t\twfr_size_t minLoopElementcount = std::min({"; + String portCheckString = ""; + // iterate through inport-struct members + boolean isFirst = true; + for (IrPort pm : task.getInPortStruct().members) { + if (pm.getPortType() == PortType.LoopElements) { + if (isFirst) { + isFirst = false; + } else { + minCountString += ", "; + } + portCheckString += " && sin->" + pm.getName() + ".isReady()"; + minCountString += "sin->" + pm.getName() + ".getSize()"; + } + } + minCountString += "});\n"; + + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (sin != nullptr" + portCheckString + " && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution) {\n"); + + + writer.write(minCountString); + writer.write("\t\tWFR_SELF_SETITERATIONCOUNT(minLoopElementcount);\n"); + writer.write("\t\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t}\n"); + + writer.write("\t" + StringConstants.forCounterEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeIterationHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.loopIterationHookMacroName + "(" + task.getLoopIterationHookName() + ") {\n"); + writer.write("\t" + StringConstants.loopIterationPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + int varIndex = 1; + for (IrPort pm : task.getInPortStruct().members) { + if (pm.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : pm.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + fromPort.getParentNode().getOutPortStruct().getName() + ", a" + varIndex + ", " + + fromPort.getParentNode().getId() + ", sin->" + pm.getName() + ".getNextIterationID()-1);\n"); + writer.write("\tif (a" + varIndex + "in != nullptr) {\n"); + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", pm, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, "sin->" + pm.getName() + ".getNextIterationID()+1", true) + ";\n"); + writer.write("\t}\n"); + } + } + varIndex++; + } + + writer.write("\t" + StringConstants.loopIterationEpilogMacroName + ";\n"); + writer.write("}\n"); + + } + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateForLoopConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getForCounterHookName() + ", " + + task.getLoopIterationHookName() + ", " + + task.isParallel() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.java new file mode 100755 index 0000000..d6c0f19 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ForGenerator.java @@ -0,0 +1,282 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; + +import org.shiwa.fgi.iwir.AbstractPort; +import org.shiwa.fgi.iwir.LoopCounter; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; + +public class ForGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeCounterHookFunction(writer, program, task); + writeIterationHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getCollectionNestingLevel() > 0) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + writer.write("\n"); + // Fetch values from childrens output ports + // At first union ports + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Union Port + if (toPort.getPortType() == PortType.UnionPort) { + if (toPort.hasIwirConstraint(StringConstants.iwirConstraintFlattenCollection)) { + String flattenValue = toPort.getIwirConstraint(StringConstants.iwirConstraintFlattenCollection); + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenFlattenMacro + "(sout->" + toPort.getName() + + ", " + flattenValue + ", " + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + + fn.getId() + ");\n"); + } else { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenMacro + "(sout->" + toPort.getName() + ", " + + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + fn.getId() + ");\n"); + writer.write("\t" + StringConstants.loopFinalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } + } + } + } + } + // Then the other ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + // Write get macro and after that the beginning of the protecting if block + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + + ", " + fn.getId() +", " + StringConstants.selfGetHandledIterationCount + "()-1" + ");\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Out Port + if (toPort.getPortType() == PortType.OutPort) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t\tif (" + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + // Loop Port + } else if (toPort.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t\tif (" + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + } else { + throw new RuntimeException("fromPort is null."); + } + } + } + writer.write("\t}\n"); + } else if (fn == task) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (sin != nullptr && "+ StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode() == task) { + fromPort = tmp; + break; + } + } + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "sin->", fromPort, StringConstants.selfGetHandledIterationCount + "()", true) + ";\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + } + varIndex++; + } + writer.write("\n"); + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeCounterHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.forCounterHookMacroName + "(" + task.getForCounterHookName() + ") {\n"); + writer.write("\t" + StringConstants.forCounterPrologMacroName + ";\n"); + + String sPortCheck = ""; + boolean isFirst = true; + if (task.getLoopCounterFrom() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterFrom().getName() + ".isReady()"; + } + if (task.getLoopCounterStep() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterStep().getName() + ".isReady()"; + } + if (task.getLoopCounterTo() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterTo().getName() + ".isReady()"; + } + if (!sPortCheck.isEmpty()) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif(sin != nullptr && " + sPortCheck + ") {\n"); + String fromValue = ""; + if (task.getLoopCounterFrom() != null) { + fromValue = "sin->" + task.getLoopCounterFrom().getName() + ".getValue()"; + } else { + fromValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getFrom(); + } + String stepValue = ""; + if (task.getLoopCounterStep() != null) { + stepValue = "sin->" + task.getLoopCounterStep().getName() + ".getValue()"; + } else { + stepValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getStep(); + } + String toValue = ""; + if (task.getLoopCounterTo() != null) { + toValue = "sin->" + task.getLoopCounterTo().getName() + ".getValue()"; + } else { + toValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getTo(); + } + writer.write("\t\t" + StringConstants.selfSetForLoopCounterValues + "(" + fromValue + ", " + stepValue + ", " + toValue + ")" + "\n"); + writer.write("\t\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t}\n"); + } else { + String fromValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getFrom(); + String stepValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getStep(); + String toValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getTo(); + writer.write("\t" + StringConstants.selfSetForLoopCounterValues + "(" + fromValue + ", " + stepValue + ", " + toValue + ")" + "\n"); + writer.write("\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + } + writer.write("\t" + StringConstants.forCounterEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static void writeIterationHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.loopIterationHookMacroName + "(" + task.getLoopIterationHookName() + ") {\n"); + writer.write("\t" + StringConstants.loopIterationPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + int varIndex = 1; + for (IrPort pm : task.getInPortStruct().members) { + if (pm.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : pm.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + fromPort.getParentNode().getOutPortStruct().getName() + ", a" + varIndex + ", " + + fromPort.getParentNode().getId() + ", sin->" + pm.getName() + ".getNextIterationID()-1);\n"); + writer.write("\tif (a" + varIndex + "in != nullptr) {\n"); + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", pm, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, "sin->" + pm.getName() + ".getNextIterationID()+1", true) + ";\n"); + writer.write("\t}\n"); + } + } + } + + writer.write("\t" + StringConstants.loopIterationEpilogMacroName + ";\n"); + writer.write("}\n"); + + } + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateForLoopConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getForCounterHookName() + ", " + + task.getLoopIterationHookName() + ", " + + task.isParallel() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.java new file mode 100755 index 0000000..df45dba --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/IfGenerator.java @@ -0,0 +1,277 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Vector; + +import javax.management.RuntimeErrorException; + +import org.shiwa.fgi.iwir.ConditionExpression; +import org.shiwa.fgi.iwir.IfTask; +import org.shiwa.fgi.iwir.condition.ConditionNode; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; + +public class IfGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeBranchConditionHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + // Fetch values from childrens output ports + int varIndex = 1; + for (IrPort pm : task.getOutPortStruct().members) { + IrPort elsePred = null; + isFirst = true; + for (IrPort pred : pm.getPredecessors()) { + if (pred.getParentNode() == task) { + elsePred = pred; + } else { + if (isFirst) { + writer.write("\tif (" + StringConstants.selfGetCondBranchIdMacro + "() == " + + pred.getParentNode().inParentBranch() + ") {\n"); + + writer.write("\t\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + pred.getParentNode().getOutPortStruct().getName() + ", a" + varIndex + ", " + + pred.getParentNode().getId() + ", 0);\n"); + writer.write("\t\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + + if (pm.getDataType().equals(pred.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", pm, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", pred, true) + ";\n"); + } else if (pm.getDataType().implicitCollectionCastPossible(pred.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", pm, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", pred, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + pm.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + + writer.write("\t}"); + isFirst = false; + } else { + writer.write(" else if (" + StringConstants.selfGetCondBranchIdMacro + "() == " + + pred.getParentNode().inParentBranch() + ") {\n"); + + writer.write("\t\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + pred.getParentNode().getOutPortStruct().getName() + ", a" + varIndex + ", " + + pred.getParentNode().getId() + ", " + pred.getParentNode().inParentBranch() + ");\n"); + writer.write("\t\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + + if (pm.getDataType().equals(pred.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", pm, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", pred, true) + ";\n"); + } else if (pm.getDataType().implicitCollectionCastPossible(pred.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", pm, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", pred, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + pm.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + + writer.write("\t}"); + } + } + } + if (elsePred != null) { + writer.write(" else {\n"); + + writer.write("\t\t" + StringConstants.selfInputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + elsePred.getParentNode().getInPortStruct().getName() + ");\n"); + writer.write("\t\tif (a" + varIndex + StringConstants.inbufferVarPostfix + " != nullptr) {\n"); + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", pm, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", elsePred, true) + ";\n"); + writer.write("\t\t\tif (retval) {\n"); + writer.write("\t\t\t\tinstance.setInstanceStatus(wfs::ActivityInstanceStatus::Finished);\n"); + writer.write("\t\t\t\t((wfs::CompositeActivityInstance&)instance).notifyChildHasFinished(instance);\n"); + writer.write("\t\t\t}\n"); + writer.write("\t\t}\n"); + writer.write("\t}"); + } + writer.write("\n"); + } + + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeBranchConditionHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.branchConditionHookMacroName + "(" + task.getBranchConditionHookName() + ") {\n"); + writer.write("\t" + StringConstants.branchConditionPrologMacroName + ";\n"); + + Vector involvedPorts = new Vector(); + ConditionExpression rawCondition = ((IfTask)task.getIwirTask()).getCondition(); + String condString = writeConditionCode(writer, program, task, rawCondition.getConditionAsNode(), involvedPorts); + + String portCheckString = ""; + for (IrPort p : involvedPorts) { + portCheckString += " && sin->" + p.getName() + ".isReady()"; + } + if (!portCheckString.isEmpty()) { + portCheckString += " "; + } + + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().getName() + ");\n"); + writer.write("\tif (sin != nullptr && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution" + portCheckString + ") {\n"); + writer.write("\t\tif (" + condString + ") {\n"); + writer.write("\t\t\tinstance.setExecutionBranchID(0);\n"); + writer.write("\t\t} else {\n"); + writer.write("\t\t\tinstance.setExecutionBranchID(1);\n"); + writer.write("\t\t}\n"); + writer.write("\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t}\n"); + + writer.write("\t" + StringConstants.branchConditionEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + private static String writeConditionCode(FileWriter writer, IrProgram program, IrNode task, ConditionNode expr, Vector involvedPorts) { + String retval = ""; + + switch (expr.getOp()) { + case AND: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " && "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case OR: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " || "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case BOOL: + retval += expr.getBool(); + break; + case DOUBLE: + retval += expr.getDob(); + break; + case INT: + retval += expr.getNum(); + break; + case STRING: + retval += "\"" + expr.getString() + "\""; + break; + case PORT: + String iwirPortName = expr.getPort(); + IrPort foundPort = null; + for (IrPort p : task.getInPortStruct().getMembers()) { + if (p.getIwirPort().getName().equals(iwirPortName)) { + foundPort = p; + break; + } + } + if (foundPort != null) { + involvedPorts.add(foundPort); + retval += "sin->" + foundPort.getName() + ".getValue()"; + } else { + retval += ""; + } + break; + case LP: + retval += "(" + writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts) + ")"; + break; + case NOT: + retval += "!" + writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + break; + case NEQ: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " != "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case EQ: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " == "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case GT: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " > "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case GTE: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " >= "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case LT: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " < "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case LTE: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " <= "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case RP: + throw new RuntimeException("Found a use of \"RP\"!"); + default: + throw new RuntimeException("Unknown node op \"" + expr.getOp() + "\"."); + } + + return retval; + } + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateConditionalConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getBranchConditionHookName() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.java new file mode 100755 index 0000000..fd23be1 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForEachGenerator.java @@ -0,0 +1,147 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; + +public class ParallelForEachGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeCounterHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } else { // since is is parallel for each loop, all output ports need to be of type collection + throw new RuntimeException("Error: output port of parallel for each loop is not a collection"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + writer.write("\n"); + // Fetch values from childrens output ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + + // child task + if (fn.getParent() == task) { + // Inside if block iterate over all data-links from same predecessor + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + if (toPort.hasIwirConstraint(StringConstants.iwirConstraintFlattenCollection)) { + String flattenValue = toPort.getIwirConstraint(StringConstants.iwirConstraintFlattenCollection); + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenFlattenMacro + "(sout->" + toPort.getName() + + ", " + flattenValue + ", " + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + + fn.getId() + ");\n"); + } else { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenMacro + "(sout->" + toPort.getName() + ", " + + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + fn.getId() + ");\n"); + writer.write("\t" + StringConstants.loopFinalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } + } + + // Error: unexpected predecessor level + } else { + throw new RuntimeException("writeInputHookFunction - remote task \"" + fn.getNodeName() + "\" is not a child nor a parent"); + } + varIndex++; + } + writer.write("\n"); + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeCounterHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.forCounterHookMacroName + "(" + task.getForCounterHookName() + ") {\n"); + writer.write("\t" + StringConstants.forCounterPrologMacroName + ";\n"); + + String minCountString = "\t\twfr_size_t minLoopElementcount = std::min({"; + String portCheckString = ""; + // iterate through inport-struct members + boolean isFirst = true; + for (IrPort pm : task.getInPortStruct().members) { + if (pm.getPortType() == PortType.LoopElements) { + if (isFirst) { + isFirst = false; + } else { + minCountString += ", "; + } + portCheckString += " && sin->" + pm.getName() + ".isReady()"; + minCountString += "sin->" + pm.getName() + ".getSize()"; + } + } + minCountString += "});\n"; + + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (sin != nullptr" + portCheckString + " && instance.getInstanceStatus() < wfr::wfs::ActivityInstanceStatus::ReadyForExecution) {\n"); + + + writer.write(minCountString); + writer.write("\t\tWFR_SELF_SETITERATIONCOUNT(minLoopElementcount);\n"); + writer.write("\t\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t}\n"); + + writer.write("\t" + StringConstants.forCounterEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateForLoopConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getForCounterHookName() + ", " + + "nullptr, " + + task.isParallel() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.java new file mode 100755 index 0000000..2a2b64c --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/ParallelForGenerator.java @@ -0,0 +1,184 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; + +import org.shiwa.fgi.iwir.LoopCounter; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; + +public class ParallelForGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeCounterHookFunction(writer, program, task); + writeIterationHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } else { // since is is parallel for each loop, all output ports need to be of type collection + throw new RuntimeException("Error: output port of parallel for each loop is not a collection"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + writer.write("\n"); + // Fetch values from childrens output ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + + // child task + if (fn.getParent() == task) { + // Inside if block iterate over all data-links from same predecessor + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + if (toPort.hasIwirConstraint(StringConstants.iwirConstraintFlattenCollection)) { + String flattenValue = toPort.getIwirConstraint(StringConstants.iwirConstraintFlattenCollection); + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenFlattenMacro + "(sout->" + toPort.getName() + + ", " + flattenValue + ", " + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + + fn.getId() + ");\n"); + } else { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenMacro + "(sout->" + toPort.getName() + ", " + + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + fn.getId() + ");\n"); + writer.write("\t" + StringConstants.loopFinalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } + } + + // Error: unexpected predecessor level + } else { + throw new RuntimeException("writeInputHookFunction - remote task \"" + fn.getNodeName() + "\" is not a child nor a parent"); + } + varIndex++; + } + writer.write("\n"); + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeCounterHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.forCounterHookMacroName + "(" + task.getForCounterHookName() + ") {\n"); + writer.write("\t" + StringConstants.forCounterPrologMacroName + ";\n"); + + String sPortCheck = ""; + boolean isFirst = true; + if (task.getLoopCounterFrom() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterFrom().getName() + ".isReady()"; + } + if (task.getLoopCounterStep() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterStep().getName() + ".isReady()"; + } + if (task.getLoopCounterTo() != null) { + if (isFirst) { + isFirst = false; + } else { + sPortCheck += " && "; + } + sPortCheck += "sin->" + task.getLoopCounterTo().getName() + ".isReady()"; + } + if (!sPortCheck.isEmpty()) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif(sin != nullptr && " + sPortCheck + ") {\n"); + String fromValue = ""; + if (task.getLoopCounterFrom() != null) { + fromValue = "sin->" + task.getLoopCounterFrom().getName() + ".getValue()"; + } else { + fromValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getFrom(); + } + String stepValue = ""; + if (task.getLoopCounterStep() != null) { + stepValue = "sin->" + task.getLoopCounterStep().getName() + ".getValue()"; + } else { + stepValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getStep(); + } + String toValue = ""; + if (task.getLoopCounterTo() != null) { + toValue = "sin->" + task.getLoopCounterTo().getName() + ".getValue()"; + } else { + toValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getTo(); + } + writer.write("\t\t" + StringConstants.selfSetForLoopCounterValues + "(" + fromValue + ", " + stepValue + ", " + toValue + ")" + "\n"); + writer.write("\t\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t}\n"); + } else { + String fromValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getFrom(); + String stepValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getStep(); + String toValue = ((LoopCounter)task.getLoopCounter().getIwirPort()).getTo(); + writer.write("\t" + StringConstants.selfSetForLoopCounterValues + "(" + fromValue + ", " + stepValue + ", " + toValue + ")" + "\n"); + writer.write("\t" + StringConstants.loopFinalize + "();\n"); + writer.write("\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + } + writer.write("\t" + StringConstants.forCounterEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static void writeIterationHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + + } + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateForLoopConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getForCounterHookName() + ", " + + "nullptr, " + + task.isParallel() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.java new file mode 100755 index 0000000..37c9cdc --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/TaskGenerator.java @@ -0,0 +1,132 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; + +import org.shiwa.fgi.iwir.AbstractTask; +import org.shiwa.fgi.iwir.Task; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.coderepository.CodeRepository; +import at.ac.uibk.iwir2wfr.ir.IrDataType; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; + +public class TaskGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + int implementationCount = CodeRepository.getInstance().getImplementationCount(task); + for (int t = 0; t < implementationCount; t++) { + writeExecHookFunction(writer, program, task, t); + } + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeExecHookFunction(FileWriter writer, IrProgram program, IrNode task, int index) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.execHookMacroName + "(" + task.getExecHookName() + "_" + index + ") {\n"); + writer.write("\t" + StringConstants.execPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().name + ");\n"); + + // Init collections + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getType() == IrDataType.Type.IWIRCOLLECTION) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + } + + CodeRepository repo = CodeRepository.getInstance(); + String code = repo.getAtomicTaskCode(task, index); + if (code != null) { + writer.write(code); + } else { + writer.write("\n\t// ToDo: Add actual atomic task code here.\n"); + writer.write("\t// And then store the results into the output struct.\n\n"); + } + // Epilog + writer.write("\t" + StringConstants.execEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + public static void writeImplementationTables(FileWriter writer, IrNode node, IrProgram program) throws IOException { + int implementationCount = CodeRepository.getInstance().getImplementationCount(node); + System.out.println("Debug01: " + node.getNodeName()); + if (node.hasIwirProperty(StringConstants.iwirPropertyAssignActivity)) { + node.setNumberOfImplementations(1); + } else { + if (node.getImplementationTableName() == null) { + node.setImplementationTableName(node.getNodeName() + "Implementations"); + } + node.setNumberOfImplementations(implementationCount); + writer.write("\n" + StringConstants.activityImpementationsMacro + "( " + node.getImplementationTableName() + ", \"" + node.getImplementationTableName() + "\", \\\n"); + for (int t = 0; t < implementationCount; t++) { + String name = CodeRepository.getInstance().getAtomicTaskCodeName(node, t); + String type = CodeRepository.getInstance().getAtomicTaskCodeType(node, t); + String meta = CodeRepository.getInstance().getAtomicTaskCodeMetadata(node, t); + if (name == null) { + name = node.getExecHookName()+ "_" + t; + } + if (type.equalsIgnoreCase("pthreads") || type.equalsIgnoreCase("pthread")) { + writer.write("\t" + StringConstants.activityImplementationPthreadsClass + "(" + node.getExecHookName()+ "_" + t + ", \"" + name + "\""); + } else if (type.equalsIgnoreCase("cuda")) { + writer.write("\t" + StringConstants.activityImplementationCudaClass + "(" + node.getExecHookName()+ "_" + t + ", \"" + name + "\""); + } else if (type.equalsIgnoreCase("opencl")) { + writer.write("\t" + StringConstants.activityImplementationOpenClClass + "(" + node.getExecHookName()+ "_" + t + ", \"" + name + "\""); + } else { + //writer.write("\t" + StringConstants.activityImplementationUnknownClass + "(" + node.getExecHookName()+ "_" + t + ", \"" + name + "\""); + } + if (meta != null) { + writer.write(", " + meta + " )"); + } else { + writer.write(" )"); + } + + if (t < implementationCount-1) { + writer.write(",\n"); + } + } + writer.write("\n);\n"); + } + } + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + AbstractTask at = task.getIwirTask(); + if (task.hasIwirProperty(StringConstants.iwirPropertyAssignActivity)) { + writer.write("\t" + StringConstants.activityTemplateAssignConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getExecHookName() + "_0), \\\n"); + } else { + writer.write("\t" + StringConstants.activityTemplateAtomicConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getImplementationTableName() + "), \\\n"); + } + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.java b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.java new file mode 100755 index 0000000..60b8fa7 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/codegenerator/taskspecific/WhileGenerator.java @@ -0,0 +1,337 @@ +package at.ac.uibk.iwir2wfr.codegenerator.taskspecific; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.Vector; + +import org.shiwa.fgi.iwir.ConditionExpression; +import org.shiwa.fgi.iwir.LoopCounter; +import org.shiwa.fgi.iwir.WhileTask; +import org.shiwa.fgi.iwir.condition.ConditionNode; + +import at.ac.uibk.iwir2wfr.codegenerator.SourceFileGenerator; +import at.ac.uibk.iwir2wfr.codegenerator.StringConstants; +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrPort; +import at.ac.uibk.iwir2wfr.ir.IrProgram; +import at.ac.uibk.iwir2wfr.ir.IrPort.PortType; + +public class WhileGenerator { + + public static void writeHookFunctions(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writeInputHookFunction(writer, program, task); + writeOutputHookFunction(writer, program, task); + writeConditionHookFunction(writer, program, task); + writeIterationHookFunction(writer, program, task); + } + + + public static void writeInputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + SourceFileGenerator.writeInputHookFunction(writer, program, task); + } + + + public static void writeOutputHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + // Prolog + writer.write("\n\n" + StringConstants.outputHookMacroName + "(" + task.getOutputHookName() +") {\n"); + writer.write("\t" + StringConstants.outputPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfOutputBufferInitMacro + "(sout, " + task.getOutPortStruct().getName() + ");\n"); + + // Iterate through output ports, initialise collections and build check-string + boolean isFirst = true; + String checkString = ""; + for ( IrPort pm : task.getOutPortStruct().members) { + if (pm.getDataType().getCollectionNestingLevel() > 0) { + writer.write("\t" + StringConstants.portInitCollectionMacro + "(sout->" + pm.getName() + ");\n"); + } + if (isFirst) { + isFirst = false; + } else { + checkString += " && "; + } + checkString += "sout->" + pm.getName() + ".isReady()"; + } + + writer.write("\n"); + // Fetch values from childrens output ports + // At first union ports + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Union Port + if (toPort.getPortType() == PortType.UnionPort) { + if (toPort.hasIwirConstraint(StringConstants.iwirConstraintFlattenCollection)) { + String flattenValue = toPort.getIwirConstraint(StringConstants.iwirConstraintFlattenCollection); + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenFlattenMacro + "(sout->" + toPort.getName() + + ", " + flattenValue + ", " + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + + fn.getId() + ");\n"); + } else { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t" + StringConstants.collectOutvaluesFromChildrenMacro + "(sout->" + toPort.getName() + ", " + + fn.getOutPortStruct().name + ", " + fromPort.getName() + ", " + fn.getId() + ");\n"); + writer.write("\t" + StringConstants.loopFinalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } + } + } + } + } + // Then the other ports + int varIndex = 1; + for (IrNode fn : task.getOutPortNodeMap().keySet()) { + // child task + if (fn.getParent() == task) { + // Write get macro and after that the beginning of the protecting if block + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.outbufferVarPostfix + ", " + fn.getOutPortStruct().getName() + ", a" + varIndex + + ", " + fn.getId() +", " + StringConstants.selfGetHandledIterationCount + "()-1" + ");\n"); + writer.write("\tif (a" + varIndex + StringConstants.outbufferVarPostfix + " != nullptr) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + // Out Port + if (toPort.getPortType() == PortType.OutPort) { + IrPort fromPort = toPort.getPredecessors().iterator().next(); + writer.write("\t\tif (((wfr::wfs::LoopActivityInstance&)instance).isFinalised() && " + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + // Loop Port + } else if (toPort.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t\tif (((wfr::wfs::LoopActivityInstance&)instance).isFinalised() && " + StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, true) + ";\n"); + } else if (toPort.getDataType().implicitCollectionCastPossible(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "a" + varIndex + StringConstants.outbufferVarPostfix + "->", fromPort, "0", true) + ";\n"); + writer.write("\t\t\t" + StringConstants.finalizeCollection + "(sout, " + toPort.getName() + ");\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + writer.write("\t\t}\n"); + } else { + throw new RuntimeException("fromPort is null."); + } + } + } + writer.write("\t}\n"); + } else if (fn == task) { + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + writer.write("\tif (((wfr::wfs::LoopActivityInstance&)instance).isFinalised() && sin != nullptr && "+ StringConstants.selfGetIterationCountMacro + "() <= " + StringConstants.selfGetHandledIterationCount + "()) {\n"); + for (IrPort toPort : task.getOutPortNodeMap().get(fn)) { + IrPort fromPort = null; + for (IrPort tmp : toPort.getPredecessors()) { + if (tmp.getParentNode() == task) { + fromPort = tmp; + break; + } + } + if (toPort.getDataType().equals(fromPort.getDataType())) { + writer.write("\t\t\t" + StringConstants.portBufferCopy("sout->", toPort, + "sin->", fromPort, StringConstants.selfGetHandledIterationCount + "()", true) + ";\n"); + } else { + throw new RuntimeException("Don't known which portBufferCopy to apply."); + } + } + writer.write("\t}\n"); + } + varIndex++; + } + writer.write("\n"); + // Write checkAllOutputsAvailable Macro + if (!checkString.isEmpty()) { + writer.write("\t" + StringConstants.selfCheckAllOutputsAvailable + "(" + checkString + ");\n"); + } + // Epilog + writer.write("\t" + StringConstants.outputEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + public static void writeConditionHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.whileConditionHookMacroName + "(" + task.getWhileConditionHookName() + ") {\n"); + writer.write("\t" + StringConstants.whileConditionPrologMacroName + ";\n"); + + Vector involvedPorts = new Vector(); + ConditionExpression rawCondition = ((WhileTask)task.getIwirTask()).getCondition(); + String condString = writeConditionCode(writer, program, task, rawCondition.getConditionAsNode(), involvedPorts); + + String portCheckString = ""; + for (IrPort p : involvedPorts) { + portCheckString += " && sin->" + p.getName() + ".isReady()"; + } + if (!portCheckString.isEmpty()) { + portCheckString += " "; + } + + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().getName() + ");\n"); + writer.write("\tif (sin != nullptr && instance.getInstanceStatus() <= wfr::wfs::ActivityInstanceStatus::ReadyForExecution" + portCheckString + ") {\n"); + writer.write("\t\tif (" + condString + ") {\n"); + writer.write("\t\t\t" + StringConstants.selfCheckReadyForExecution + "(true);\n"); + writer.write("\t\t\tWFR_SELF_SETITERATIONCOUNT(WFR_SELF_GETITERATIONCOUNT()+1);\n"); + writer.write("\t\t\tretval = true;\n"); + writer.write("\t\t} else {\n"); + writer.write("\t\t\t((wfr::wfs::WhileLoopActivityInstance&)instance).setFinalised(true);\n"); + writer.write("\t\t\tretval = false;\n"); + writer.write("\t\t}\n"); + writer.write("\t}\n"); + + writer.write("\t" + StringConstants.whileConditionEpilogMacroName + ";\n"); + writer.write("}\n"); + } + + + private static String writeConditionCode(FileWriter writer, IrProgram program, IrNode task, ConditionNode expr, Vector involvedPorts) { + String retval = ""; + + switch (expr.getOp()) { + case AND: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " && "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case OR: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " || "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case BOOL: + retval += expr.getBool(); + break; + case DOUBLE: + retval += expr.getDob(); + break; + case INT: + retval += expr.getNum(); + break; + case STRING: + retval += "\"" + expr.getString() + "\""; + break; + case PORT: + String iwirPortName = expr.getPort(); + IrPort foundPort = null; + for (IrPort p : task.getInPortStruct().getMembers()) { + if (p.getIwirPort().getName().equals(iwirPortName)) { + foundPort = p; + break; + } + } + if (foundPort != null) { + involvedPorts.add(foundPort); + retval += "sin->" + foundPort.getName() + ".getValue()"; + } else { + retval += ""; + } + break; + case LP: + retval += "(" + writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts) + ")"; + break; + case NOT: + retval += "!" + writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + break; + case NEQ: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " != "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case EQ: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " == "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case GT: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " > "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case GTE: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " >= "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case LT: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " < "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case LTE: + retval += writeConditionCode(writer, program, task, expr.getLeft(), involvedPorts); + retval += " <= "; + retval += writeConditionCode(writer, program, task, expr.getRight(), involvedPorts); + break; + case RP: + throw new RuntimeException("Found a use of \"RP\"!"); + default: + throw new RuntimeException("Unknown node op \"" + expr.getOp() + "\"."); + } + + return retval; + } + + + + public static void writeIterationHookFunction(FileWriter writer, IrProgram program, IrNode task) throws IOException { + writer.write("\n\n" + StringConstants.loopIterationHookMacroName + "(" + task.getLoopIterationHookName() + ") {\n"); + writer.write("\t" + StringConstants.loopIterationPrologMacroName + ";\n"); + writer.write("\t" + StringConstants.selfInputBufferGetMacro + "(sin, " + task.getInPortStruct().name + ");\n"); + int varIndex = 1; + for (IrPort pm : task.getInPortStruct().members) { + if (pm.getPortType() == PortType.LoopPort) { + IrPort fromPort = null; + for (IrPort tmp : pm.getPredecessors()) { + if (tmp.getParentNode().getParent() == task) { + fromPort = tmp; + break; + } + } + if (fromPort != null) { + writer.write("\t" + StringConstants.childOutputBufferGetMacro + "(a" + varIndex + + StringConstants.inbufferVarPostfix + ", " + fromPort.getParentNode().getOutPortStruct().getName() + ", a" + varIndex + ", " + + fromPort.getParentNode().getId() + ", sin->" + pm.getName() + ".getNextIterationID()-1);\n"); + writer.write("\tif (a" + varIndex + "in != nullptr) {\n"); + writer.write("\t\t" + StringConstants.portBufferCopy("sin->", pm, + "a" + varIndex + StringConstants.inbufferVarPostfix + "->", fromPort, "sin->" + pm.getName() + ".getNextIterationID()+1", true) + ";\n"); + writer.write("\t}\n"); + } + } + } + + writer.write("\t" + StringConstants.loopIterationEpilogMacroName + ";\n"); + writer.write("}\n"); + + } + + + public static void writeActivityTableEntry(FileWriter writer, IrProgram program, IrNode task) throws IOException { + String sucs = SourceFileGenerator.getIrNodeSuccessorString(task); + String preds = SourceFileGenerator.getIrNodePredecessorString(task); + + writer.write("\t" + StringConstants.activityTemplateWhileLoopConstructor + "(" + + task.getId() + ", " + + "\"" + task.getNodeName() + "\", " + + (task.getParent() == null ? 0 : task.getParent().getId()) + ", " + + task.inParentBranch() + ", " + + sucs + ", " + + preds + ", " + + (task.getParent() == null ? "nullptr" : task.getInputHookName()) + ", " + + task.getOutputHookName() + ", " + + task.getWhileConditionHookName() + ", " + + task.getLoopIterationHookName() + "), \\\n"); + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.java b/src/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.java new file mode 100755 index 0000000..a3c307f --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/coderepository/CodeRepository.java @@ -0,0 +1,257 @@ +package at.ac.uibk.iwir2wfr.coderepository; + +import java.io.File; +import java.io.FileInputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import org.shiwa.fgi.iwir.AbstractTask; +import org.shiwa.fgi.iwir.Property; +import org.shiwa.fgi.iwir.Task; + +import com.thoughtworks.xstream.converters.extended.FileConverter; + +import at.ac.uibk.iwir2wfr.GlobalConfig; +import at.ac.uibk.iwir2wfr.ir.IrNode; + +public class CodeRepository { + + private static CodeRepository singleton = null; + + public static CodeRepository getInstance() { + if (singleton == null) { + singleton = new CodeRepository(); + } + return singleton; + } + + + private class RepoEntry { + public String code; + public String name; + public String type; + public String metaInfo; + } + + private Map> repository = new HashMap>(); + + private String wfInputCode = null; + private String wfOutputCode = null; + private String sourceIncludes = null; + + private CodeRepository() { + GlobalConfig config = GlobalConfig.getInstance(); + String repoConfig = config.getCodeRepoConfig(); + File repoConfigFile = null; + if (repoConfig != null && !repoConfig.isEmpty()) { + repoConfigFile = new File(repoConfig); + } + Properties repoProps = new Properties(); + try { + if (repoConfigFile != null && repoConfigFile.exists() && repoConfigFile.isFile()) { + repoProps.load(new FileInputStream(repoConfigFile)); + String tmp = repoProps.getProperty("wfinput"); + if (tmp != null) { + wfInputCode = repoConfigFile.getParent() + "/" + tmp; + } + tmp = repoProps.getProperty("wfoutput"); + if (tmp != null) { + wfOutputCode = repoConfigFile.getParent() + "/" + tmp; + } + tmp = repoProps.getProperty("includes"); + if (tmp != null) { + sourceIncludes = repoConfigFile.getParent() + "/" + tmp; + } + for (Object o : repoProps.keySet()) { + String key = (String)o; + if (key.startsWith("atomicTask.")) { + String taskConfig = repoProps.getProperty(key); + File taskConfigFile = null; + if (taskConfig != null && !taskConfig.isEmpty()) { + taskConfigFile = new File(repoConfigFile.getParent() + "/" + taskConfig); + } + Properties taskProps = new Properties(); + taskProps.load(new FileInputStream(taskConfigFile)); + int entries = Integer.parseInt(taskProps.getProperty("entries")); + String name = taskProps.getProperty("name"); + Vector repoEntries = new Vector(); + for (int t = 0; t < entries; t++) { + String codeFile = taskConfigFile.getParent() + "/" + taskProps.getProperty("entry." + t); + String codeName = taskProps.getProperty("entryname." + t); + String codeType = taskProps.getProperty("entrytype." + t, "pthreads"); + String codeMetadata = taskProps.getProperty("entrymetadata." + t); + RepoEntry entry = new RepoEntry(); + entry.code = codeFile; + entry.name = codeName; + entry.type = codeType; + entry.metaInfo = codeMetadata; + repoEntries.add(entry); + } + repository.put(name, repoEntries); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + public String getAtomicTaskCode(IrNode task, int index) { + String retval = null; + AbstractTask at = task.getIwirTask(); + if (at instanceof Task) { + String taskName = ((Task)at).getTasktype(); + try { + Vector entry = repository.get(taskName); + if (entry != null && index < entry.size()) { + FileInputStream istream = new FileInputStream(entry.get(index).code); + byte[] tmp = new byte[istream.available()]; + istream.read(tmp); + retval = new String(tmp) + "\n"; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getAtomicTaskCodeName(IrNode task, int index) { + String retval = null; + AbstractTask at = task.getIwirTask(); + if (at instanceof Task) { + String taskName = ((Task)at).getTasktype(); + try { + Vector entry = repository.get(taskName); + if (entry != null && index < entry.size()) { + retval = entry.get(index).name; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getAtomicTaskCodeType(IrNode task, int index) { + String retval = null; + AbstractTask at = task.getIwirTask(); + if (at instanceof Task) { + String taskName = ((Task)at).getTasktype(); + try { + Vector entry = repository.get(taskName); + if (entry != null && index < entry.size()) { + retval = entry.get(index).type; + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getAtomicTaskCodeMetadata(IrNode task, int index) { + String retval = null; + AbstractTask at = task.getIwirTask(); + if (at instanceof Task) { + String taskName = ((Task)at).getTasktype(); + try { + Vector entry = repository.get(taskName); + if (entry != null && index < entry.size()) { + retval = entry.get(index).metaInfo; + } + } catch (Exception e) { + e.printStackTrace(); + } + String propsString = ""; + boolean isFirst = true; + for (Property prop : at.getProperties()) { + if (isFirst) { + isFirst = false; + } else { + propsString += ","; + } + propsString += "{\"" + prop.getName() + "\",\"" + prop.getValue() + "\"}"; + } + if (!isFirst) { + if (retval == null) { + retval = "{" + propsString + "}"; + } else if (retval.endsWith("}}")) { + retval = retval.substring(0, retval.length()-1) + "," + propsString + "}"; + } else { + retval = retval + "," + propsString; + } + } + if (retval != null && !retval.endsWith("}}")) { + retval = "{" + retval + "}"; + } + } + return retval; + } + + public int getImplementationCount(IrNode task) { + int retval = 0; + AbstractTask at = task.getIwirTask(); + if (at instanceof Task) { + String taskName = ((Task)at).getTasktype(); + try { + Vector entry = repository.get(taskName); + if (entry != null) { + retval = entry.size(); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + return retval; + } + + public String getWfInputCode() { + String retval = null; + try { + if (wfInputCode != null) { + FileInputStream istream = new FileInputStream(wfInputCode); + byte[] tmp = new byte[istream.available()]; + istream.read(tmp); + retval = new String(tmp) + "\n"; + } + } catch (Exception e) { + e.printStackTrace(); + } + return retval; + } + + public String getWfOutputCode() { + String retval = null; + try { + if (wfOutputCode != null) { + FileInputStream istream = new FileInputStream(wfOutputCode); + byte[] tmp = new byte[istream.available()]; + istream.read(tmp); + retval = new String(tmp) + "\n"; + } + } catch (Exception e) { + e.printStackTrace(); + } + return retval; + } + + public String getSourceIncludes() { + String retval = null; + try { + if (sourceIncludes != null) { + FileInputStream istream = new FileInputStream(sourceIncludes); + byte[] tmp = new byte[istream.available()]; + istream.read(tmp); + retval = new String(tmp) + "\n"; + } + } catch (Exception e) { + e.printStackTrace(); + } + return retval; + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrDataType.java b/src/at/ac/uibk/iwir2wfr/ir/IrDataType.java new file mode 100755 index 0000000..bd43eaf --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrDataType.java @@ -0,0 +1,200 @@ +package at.ac.uibk.iwir2wfr.ir; + +import org.shiwa.fgi.iwir.CollectionType; +import org.shiwa.fgi.iwir.DataType; +import org.shiwa.fgi.iwir.SimpleType; + +public class IrDataType { + + public static enum Type { + IWIRINT("wfr::lwd::iwir_int"), + IWIRDOUBLE("wfr::lwd::iwir_double"), + IWIRBOOL("wfr::lwd::iwir_bool"), + IWIRSTRING("wfr::lwd::iwir_string"), + IWIRFILE("wfr::lwd::iwir_file"), + IWIRCOLLECTION("__collection"), + CUSTOMTYPE("__customtype"), + UNKNOWNTYPE("__unknown"); + + Type(String name) { + this.name = name; + } + private String name; + public String toString() { + return name; + } + } + + protected Type type; + protected int collectionNestingLevel = 0; + protected Type collectionDataType; + protected String customType; + protected DataType iwirType; + + public IrDataType(Type type, int collectionNestingLevel, + Type collectionDataType, String customType, DataType iwirType) { + super(); + this.type = type; + this.collectionNestingLevel = collectionNestingLevel; + this.collectionDataType = collectionDataType; + this.customType = customType; + this.iwirType = iwirType; + } + + public static IrDataType createIrDataType(DataType type, IrNode node) { + IrDataType dataType = null; + Type baseType = iwirTypeToIrType(type, false); + int nestingLevel = 0; + String customType = null; + Type collectionType = iwirTypeToIrType(type, true); + if (baseType == Type.IWIRCOLLECTION) { + CollectionType ct = (CollectionType) type; + nestingLevel = ct.getNestingLevel(); + customType = getCustomType(type, true); + } else if (baseType == Type.CUSTOMTYPE) { + customType = getCustomType(type, false); + } + dataType = new IrDataType(baseType, nestingLevel, collectionType, customType, type); + return dataType; + } + + public static Type iwirTypeToIrType(DataType type, boolean collectionType) { + Type ret = Type.UNKNOWNTYPE; + DataType t = type; + if (type instanceof CollectionType) { + if (collectionType) { + t = ((CollectionType)t).getType(); + } else { + return Type.IWIRCOLLECTION; + } + } + if (t instanceof CollectionType) { + return iwirTypeToIrType(t, collectionType); + //throw new RuntimeException("Collection in collection not supported."); + } + SimpleType st = (SimpleType)t; + switch (st.getType()) { + case BOOLEAN: + ret = Type.IWIRBOOL; + break; + case DOUBLE: + ret = Type.IWIRDOUBLE; + break; + case INTEGER: + ret = Type.IWIRINT; + break; + case STRING: + ret = Type.IWIRSTRING; + break; + case FILE: + ret = Type.IWIRFILE; + break; + case CUSTOM: + ret = Type.CUSTOMTYPE; + break; + default: + break; + } + return ret; + } + + public static String getCustomType(DataType type, boolean collectionType) { + SimpleType st = null; + if (type instanceof CollectionType) { + if (collectionType) { + st = type.getSimpleType(); + } else { + return null; + } + } else { + st = (SimpleType)type; + } + return st.getCustomType(); + } + + public Type getType() { + return type; + } + public void setType(Type type) { + this.type = type; + } + public int getCollectionNestingLevel() { + return collectionNestingLevel; + } + public void setCollectionNestingLevel(int collectionNestingLevel) { + this.collectionNestingLevel = collectionNestingLevel; + } + public Type getCollectionDataType() { + return collectionDataType; + } + public void setCollectionDataType(Type collectionDataType) { + this.collectionDataType = collectionDataType; + } + public String getCustomType() { + return customType; + } + public void setCustomType(String customType) { + this.customType = customType; + } + public DataType getIwirType() { + return iwirType; + } + public void setIwirType(DataType iwirType) { + this.iwirType = iwirType; + } + + public String convertTypeToString() { + if (type == Type.CUSTOMTYPE) { + return getCustomType(); + } else { + return type.toString(); + } + } + + public boolean equals(Object obj) { + if (obj instanceof IrDataType) { + IrDataType tobj = (IrDataType)obj; + if (this.type == tobj.type && this.collectionNestingLevel == tobj.collectionNestingLevel + && this.collectionDataType == tobj.collectionDataType && (this.customType == null || this.customType.equals(customType))) { + return true; + } else { + return false; + } + } else { + return super.equals(obj); + } + } + + public boolean implicitCollectionCastPossible(Object obj) { + if (obj instanceof IrDataType) { + IrDataType tobj = (IrDataType)obj; + if (this.type == Type.IWIRCOLLECTION && this.collectionNestingLevel-1 == tobj.collectionNestingLevel + && this.collectionDataType == tobj.collectionDataType) { + return true; + } else { + return false; + } + } else { + return false; + } + } + + public static boolean loopPortMatch(IrPort from, IrPort to) { + if (from.getDataType().collectionNestingLevel == 1) { + if (to.getDataType().collectionNestingLevel == 0 && from.getDataType().collectionDataType == to.getDataType().type) { + return true; + } else { + return false; + } + } else if (from.getDataType().collectionNestingLevel > 1) { + if (to.getDataType().collectionNestingLevel == from.getDataType().collectionNestingLevel-1 && from.getDataType().collectionDataType == to.getDataType().collectionDataType) { + return true; + } else { + return false; + } + } else { + throw new RuntimeException("Not implemented"); + } + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrNode.java b/src/at/ac/uibk/iwir2wfr/ir/IrNode.java new file mode 100755 index 0000000..2242fa2 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrNode.java @@ -0,0 +1,472 @@ +package at.ac.uibk.iwir2wfr.ir; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +import org.shiwa.fgi.iwir.AbstractTask; +import org.shiwa.fgi.iwir.Constraint; +import org.shiwa.fgi.iwir.Property; + +public class IrNode { + + public static class DataLink { + public IrPort fromPort; + public IrPort toPort; + public IrNode fromNode; + public IrNode toNode; + } + + public static class TaskImplementation { + public static enum TaskImplementationType { + PThreadImplementation + } + public String execHookFuncName; + public TaskImplementationType implementationType; + } + + private static long nextID = 1; + + public static enum NodeType { + BlockScopeNode, + ForEachNode, + ForNode, + IfNode, + ParallelForEachNode, + ParallelForNode, + WhileNode, + AtomicNode, + UnknownNode + } + + protected long id; + protected String nodeName; + protected NodeType nodeType; + protected AbstractTask iwirTask; + protected IrNode parent; + protected Map> children = new HashMap>(); + protected int branchCount = 0; + protected int parentBranch = 0; + protected boolean parallelFlag; + + protected Vector inputPorts = new Vector(); + protected Vector outputPorts = new Vector(); + protected Vector unionPorts = new Vector(); + protected Vector loopPorts = new Vector(); + protected Vector loopElements = new Vector(); + protected IrPort loopCounter = null; + protected IrPort loopCounterFrom = null; + protected IrPort loopCounterTo = null; + protected IrPort loopCounterStep = null; + protected Vector unknownPorts = new Vector(); + + protected IrPortStruct inPortStruct = null; + protected IrPortStruct outPortStruct = null; + + protected Set controlPredecessors = new HashSet(); + protected Set controlSuccessors = new HashSet(); + + protected Set dataPredecessors = new HashSet(); + protected Set dataSuccessors = new HashSet(); + + protected Set dataLinks = new HashSet(); + + protected Map> inPortNodeMap = new HashMap>(); + + protected Map> outPortNodeMap = new HashMap>(); + + protected Properties iwirProperties = new Properties(); + protected Properties iwirConstraints = new Properties(); + + + protected String inputHookName = null; + protected String outputHookName = null; + protected String forCounterHookName = null; + protected String loopIterationHookName = null; + protected String whileConditionHookName = null; + protected String branchConditionHookName = null; + protected String execHookName = null; + protected String implementationTableName = null; + int numberOfImplementations = 0; + + protected String taskImplementationStructName = null; + protected Vector taskImplementations = new Vector(); + + + + public IrNode(String nodeName, NodeType nodeType, + AbstractTask iwirTask, IrNode parent) { + this(nodeName, nodeType, iwirTask, parent, 1); + } + + public IrNode(String nodeName, NodeType nodeType, + AbstractTask iwirTask, IrNode parent, int branchCount) { + super(); + synchronized (this) { + id = nextID; + nextID++; + } + this.nodeName = nodeName; + this.nodeType = nodeType; + this.iwirTask = iwirTask; + this.parent = parent; + this.branchCount = branchCount; + for (Constraint c : iwirTask.getConstraints()) { + iwirConstraints.put(c.getName(), c.getValue()); + } + for (Property p : iwirTask.getProperties()) { + iwirProperties.put(p.getName(), p.getValue()); + } + for (int t = 0; t < branchCount; t++) { + children.put(t, new Vector()); + } + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public NodeType getNodeType() { + return nodeType; + } + + public void setNodeType(NodeType nodeType) { + this.nodeType = nodeType; + } + + public AbstractTask getIwirTask() { + return iwirTask; + } + + public void setIwirTask(AbstractTask iwirTask) { + this.iwirTask = iwirTask; + } + + public Vector getChildren(int branch) { + return children.get(branch); + } + + public IrNode getParent() { + return parent; + } + + public void setParent(IrNode parent) { + this.parent = parent; + } + + public int getBranchCount() { + return branchCount; + } + + public int inParentBranch() { + return parentBranch; + } + + public void setParentBranch(int branch) { + parentBranch = branch; + } + + + + public Vector getInputPorts() { + return inputPorts; + } + + public Vector getOutputPorts() { + return outputPorts; + } + + public Vector getUnionPorts() { + return unionPorts; + } + + public Vector getLoopPorts() { + return loopPorts; + } + + public Vector getLoopElements() { + return loopElements; + } + + public IrPort getLoopCounter() { + return loopCounter; + } + + public void setLoopCounter(IrPort port) { + loopCounter = port; + } + + public IrPort getLoopCounterFrom() { + return loopCounterFrom; + } + + public void setLoopCounterFrom(IrPort loopCounterFrom) { + this.loopCounterFrom = loopCounterFrom; + } + + public IrPort getLoopCounterTo() { + return loopCounterTo; + } + + public void setLoopCounterTo(IrPort loopCounterTo) { + this.loopCounterTo = loopCounterTo; + } + + public IrPort getLoopCounterStep() { + return loopCounterStep; + } + + public void setLoopCounterStep(IrPort loopCounterStep) { + this.loopCounterStep = loopCounterStep; + } + + public Vector getUnknownPorts() { + return unknownPorts; + } + + public IrPortStruct getInPortStruct() { + return inPortStruct; + } + + public void setInPortStruct(IrPortStruct inPortStruct) { + this.inPortStruct = inPortStruct; + } + + public IrPortStruct getOutPortStruct() { + return outPortStruct; + } + + public void setOutPortStruct(IrPortStruct outPortStruct) { + this.outPortStruct = outPortStruct; + } + + public Set getControlPredecessors() { + return controlPredecessors; + } + + public Set getControlSuccessors() { + return controlSuccessors; + } + + public Set getDataPredecessors() { + return dataPredecessors; + } + + public Set getDataSuccessors() { + return dataSuccessors; + } + + public Set getSuccessors(boolean sameLevelOnly) { + Set succs = new HashSet(); + for (IrNode n : dataSuccessors) { + if (n.getParent() == this.getParent() || !sameLevelOnly) { + succs.add(n); + } + } + for (IrNode n : controlSuccessors) { + if (!succs.contains(n) && (n.getParent() == this.getParent() || !sameLevelOnly)) { + succs.add(n); + } + } + return succs; + } + + public int getSuccessorIndex(IrNode succ, boolean sameLevelOnly) { + Set succs = getSuccessors(sameLevelOnly); + int i = 0; + boolean found = false; + for (IrNode n : succs) { + if (n == succ) { + found = true; + break; + } else { + i++; + } + } + if (found) { + return i; + } else { + return -1; + } + } + + public Vector getPredecessors(boolean sameLevelOnly) { + Vector preds = new Vector(); + for (IrNode n : dataPredecessors) { + if (n.getParent() == this.getParent() || !sameLevelOnly) { + preds.add(n); + } + } + for (IrNode n : controlPredecessors) { + if (!preds.contains(n) && (n.getParent() == this.getParent() || !sameLevelOnly)) { + preds.add(n); + } + } + return preds; + } + + public int getPredecessorsIndex(IrNode pred, boolean sameLevelOnly) { + Vector preds = getPredecessors(sameLevelOnly); + int i = 0; + boolean found = false; + for (IrNode n : preds) { + if (n == pred) { + found = true; + break; + } else if (n != this) { + i++; + } + } + if (found) { + return i; + } else { + return -1; + } + } + + public Properties getIwirProperties() { + return iwirProperties; + } + + public String getIwirProperty(String key) { + return iwirProperties.getProperty(key); + } + + public boolean hasIwirProperty(String key) { + return iwirProperties.containsKey(key); + } + + public Properties getIwirConstraints() { + return iwirConstraints; + } + + public String getIwirConstraint(String key) { + return iwirConstraints.getProperty(key); + } + + public boolean hasIwirConstraint(String key) { + return iwirConstraints.containsKey(key); + } + + public Set getDataLinks() { + return dataLinks; + } + + public String getInputHookName() { + return inputHookName; + } + + public void setInputHookName(String inputHookName) { + this.inputHookName = inputHookName; + } + + public String getOutputHookName() { + return outputHookName; + } + + public void setOutputHookName(String outputHookName) { + this.outputHookName = outputHookName; + } + + public String getForCounterHookName() { + return forCounterHookName; + } + + public void setForCounterHookName(String forCounterHookName) { + this.forCounterHookName = forCounterHookName; + } + + public String getLoopIterationHookName() { + return loopIterationHookName; + } + + public void setLoopIterationHookName(String loopIterationHookName) { + this.loopIterationHookName = loopIterationHookName; + } + + public String getWhileConditionHookName() { + return whileConditionHookName; + } + + public void setWhileConditionHookName(String whileConditionHookName) { + this.whileConditionHookName = whileConditionHookName; + } + + public String getBranchConditionHookName() { + return branchConditionHookName; + } + + public void setBranchConditionHookName(String branchConditionHookName) { + this.branchConditionHookName = branchConditionHookName; + } + + public Vector getTaskImplementations() { + return taskImplementations; + } + + public String getTaskImplementationStructName() { + return taskImplementationStructName; + } + + public void setTaskImplementationStructName(String name) { + taskImplementationStructName = name; + } + + public String getExecHookName() { + return execHookName; + } + + public void setExecHookName(String execHookName) { + this.execHookName = execHookName; + } + + public String getImplementationTableName() { + return implementationTableName; + } + + public void setImplementationTableName(String implementationTableName) { + this.implementationTableName = implementationTableName; + } + + public int getNumberOfImplementations() { + return numberOfImplementations; + } + + public void setNumberOfImplementations(int numberOfImplementations) { + this.numberOfImplementations = numberOfImplementations; + } + + public Map> getInPortNodeMap() { + return inPortNodeMap; + } + + public Map> getOutPortNodeMap() { + return outPortNodeMap; + } + + public boolean isParallel() { + return parallelFlag; + } + + public void setParallel(boolean parallel) { + this.parallelFlag = parallel; + } + + + +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrPort.java b/src/at/ac/uibk/iwir2wfr/ir/IrPort.java new file mode 100755 index 0000000..769a301 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrPort.java @@ -0,0 +1,320 @@ +package at.ac.uibk.iwir2wfr.ir; + +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; +import java.util.Vector; + +import org.shiwa.fgi.iwir.AbstractPort; +import org.shiwa.fgi.iwir.BlockScope; +import org.shiwa.fgi.iwir.Constraint; +import org.shiwa.fgi.iwir.ForEachTask; +import org.shiwa.fgi.iwir.ForTask; +import org.shiwa.fgi.iwir.IfTask; +import org.shiwa.fgi.iwir.InputPort; +import org.shiwa.fgi.iwir.LoopCounter; +import org.shiwa.fgi.iwir.LoopCounterSPort; +import org.shiwa.fgi.iwir.LoopElement; +import org.shiwa.fgi.iwir.LoopPort; +import org.shiwa.fgi.iwir.OutputPort; +import org.shiwa.fgi.iwir.ParallelForEachTask; +import org.shiwa.fgi.iwir.ParallelForTask; +import org.shiwa.fgi.iwir.Property; +import org.shiwa.fgi.iwir.Task; +import org.shiwa.fgi.iwir.UnionPort; +import org.shiwa.fgi.iwir.WhileTask; + +import at.ac.uibk.iwir2wfr.utils.NameUtils; + +public class IrPort { + + public static enum PortType { + InPort, + OutPort, + UnionPort, + LoopPort, + LoopElements, + LoopCounter, + LoopCounterSPort, + UnknownPort + } + + protected String name; + protected IrDataType dataType; + protected AbstractPort iwirPort; + protected PortType portType; + protected IrNode parentNode; + + protected Properties iwirProperties = new Properties(); + protected Properties iwirConstraints = new Properties(); + + protected Vector predecessors = new Vector(); + protected Vector successors = new Vector(); + + public IrPort(String name, IrDataType type, + AbstractPort iwirPort, PortType portType, IrNode parent) { + super(); + this.name = name; + this.dataType = type; + this.iwirPort = iwirPort; + this.portType = portType; + this.parentNode = parent; + for (Constraint c : iwirPort.getConstraints()) { + iwirConstraints.put(c.getName(), c.getValue()); + } + for (Property p : iwirPort.getProperties()) { + iwirProperties.put(p.getName(), p.getValue()); + } + } + + public static IrPort createIrPort(AbstractPort iwirPort, IrNode parent, IrProgram program) { + IrPort port = null; + String portName = NameUtils.escapeIdentifierName(iwirPort.getName()); + IrDataType type = IrDataType.createIrDataType(iwirPort.getType(), parent); + PortType pType = PortType.UnknownPort; + if (iwirPort instanceof InputPort) { + pType = PortType.InPort; + } else if (iwirPort instanceof OutputPort) { + pType = PortType.OutPort; + } else if (iwirPort instanceof UnionPort) { + pType = PortType.UnionPort; + } else if (iwirPort instanceof LoopPort) { + pType = PortType.LoopPort; + } else if (iwirPort instanceof LoopElement) { + pType = PortType.LoopElements; + } else if (iwirPort instanceof LoopCounter) { + pType = PortType.LoopCounter; + } else if (iwirPort instanceof LoopCounterSPort) { + pType = PortType.LoopCounterSPort; + } else { + throw new RuntimeException("debug2"); + } + port = new IrPort(portName, type, iwirPort, pType, parent); + program.getGlobalScope().addIrPort(port); + return port; + } + + public String getName() { + return name; + } + public IrDataType getDataType() { + return dataType; + } + public AbstractPort getIwirPort() { + return iwirPort; + } + public PortType getPortType() { + return portType; + } + public IrNode getParentNode() { + return parentNode; + } + public Vector getPredecessors() { + return predecessors; + } + public Vector getSuccessors() { + return successors; + } + + public Properties getIwirProperties() { + return iwirProperties; + } + + public String getIwirProperty(String key) { + return iwirProperties.getProperty(key); + } + + public boolean hasIwirProperty(String key) { + return iwirProperties.containsKey(key); + } + + public Properties getIwirConstraints() { + return iwirConstraints; + } + + public String getIwirConstraint(String key) { + return iwirConstraints.getProperty(key); + } + + public boolean hasIwirConstraint(String key) { + return iwirConstraints.containsKey(key); + } + + public static void parseIrNodePorts(IrNode node, IrProgram program) { + switch (node.getNodeType()) { + case AtomicNode: + { + Task task = (Task)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + } + break; + case BlockScopeNode: + { + BlockScope task = (BlockScope)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + } + break; + case ForEachNode: + { + ForEachTask task = (ForEachTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + for (LoopPort p : task.getLoopPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getLoopPorts().add(irPort); + } + for (UnionPort p : task.getUnionPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getUnionPorts().add(irPort); + } + for (LoopElement p : task.getLoopElements()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getLoopElements().add(irPort); + } + } + break; + case ForNode: + { + ForTask task = (ForTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + for (LoopPort p : task.getLoopPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getLoopPorts().add(irPort); + } + for (UnionPort p : task.getUnionPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getUnionPorts().add(irPort); + } + IrPort irPort = IrPort.createIrPort(task.getLoopCounter(), node, program); + node.setLoopCounter(irPort); + AbstractPort fromPort = ((LoopCounter)task.getLoopCounter()).getFromPort(); + if (fromPort != null) { + IrPort IrPortFrom = IrPort.createIrPort(fromPort, node, program); + node.setLoopCounterFrom(IrPortFrom); + } + AbstractPort toPort = ((LoopCounter)task.getLoopCounter()).getToPort(); + if (toPort != null) { + IrPort IrPortTo = IrPort.createIrPort(toPort, node, program); + node.setLoopCounterTo(IrPortTo); + } + AbstractPort stepPort = ((LoopCounter)task.getLoopCounter()).getStepPort(); + if (stepPort != null) { + IrPort IrPortStep = IrPort.createIrPort(stepPort, node, program); + node.setLoopCounterStep(IrPortStep); + } + } + break; + case IfNode: + { + IfTask task = (IfTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + } + break; + case ParallelForEachNode: + { + ParallelForEachTask task = (ParallelForEachTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + for (LoopElement p : task.getLoopElements()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getLoopElements().add(irPort); + } + } + break; + case ParallelForNode: + { + ParallelForTask task = (ParallelForTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + IrPort irPort = IrPort.createIrPort(task.getLoopCounter(), node, program); + node.setLoopCounter(irPort); + AbstractPort fromPort = ((LoopCounter)task.getLoopCounter()).getFromPort(); + if (fromPort != null) { + IrPort IrPortFrom = IrPort.createIrPort(fromPort, node, program); + node.setLoopCounterFrom(IrPortFrom); + } + AbstractPort toPort = ((LoopCounter)task.getLoopCounter()).getToPort(); + if (toPort != null) { + IrPort IrPortTo = IrPort.createIrPort(toPort, node, program); + node.setLoopCounterTo(IrPortTo); + } + AbstractPort stepPort = ((LoopCounter)task.getLoopCounter()).getStepPort(); + if (stepPort != null) { + IrPort IrPortStep = IrPort.createIrPort(stepPort, node, program); + node.setLoopCounterStep(IrPortStep); + } + } + break; + case WhileNode: + { + WhileTask task = (WhileTask)node.iwirTask; + for (InputPort p : task.getInputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getInputPorts().add(irPort); + } + for (OutputPort p : task.getOutputPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getOutputPorts().add(irPort); + } + for (LoopPort p : task.getLoopPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getLoopPorts().add(irPort); + } + for (UnionPort p : task.getUnionPorts()) { + IrPort irPort = IrPort.createIrPort(p, node, program); + node.getUnionPorts().add(irPort); + } + } + break; + default: + throw new RuntimeException("Unknown node type."); + } + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrPortStruct.java b/src/at/ac/uibk/iwir2wfr/ir/IrPortStruct.java new file mode 100755 index 0000000..8333f25 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrPortStruct.java @@ -0,0 +1,91 @@ +package at.ac.uibk.iwir2wfr.ir; + +import java.util.Vector; + +public class IrPortStruct { + + private static long nextID = 1; + + public static enum IrStructType { + INSTRUCT, + OUTSTRUCT + } + + public long id; + public String name; + public Vector members = new Vector(); + public IrNode parentNode; + IrStructType structType; + + public IrPortStruct(String name, IrNode parentNode, IrStructType structType) { + super(); + synchronized (this) { + id = nextID; + nextID++; + } + this.name = name; + this.parentNode = parentNode; + this.structType = structType; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public Vector getMembers() { + return members; + } + + public IrNode getParentNode() { + return parentNode; + } + + public IrStructType getStructType() { + return structType; + } + + + public static void createPortStructs(IrNode node, IrProgram program) { + // Inport Struct + String nameIn = node.getNodeName() + "_in"; + IrPortStruct inStruct = new IrPortStruct(nameIn, node, IrStructType.INSTRUCT); + for (IrPort p : node.getInputPorts()) { + inStruct.getMembers().add(p); + } + for (IrPort p : node.getLoopElements()) { + inStruct.getMembers().add(p); + } + if (node.getLoopCounterFrom() != null) { + inStruct.getMembers().add(node.getLoopCounterFrom()); + } + if (node.getLoopCounterStep() != null) { + inStruct.getMembers().add(node.getLoopCounterStep()); + } + if (node.getLoopCounterTo() != null) { + inStruct.getMembers().add(node.getLoopCounterTo()); + } + for (IrPort p : node.getLoopPorts()) { + inStruct.getMembers().add(p); + } + node.setInPortStruct(inStruct); + program.getGlobalScope().addIrPortStruct(inStruct); + // Outport Struct + String nameOut = node.getNodeName() + "_out"; + IrPortStruct outStruct = new IrPortStruct(nameOut, node, IrStructType.OUTSTRUCT); + for (IrPort p : node.getOutputPorts()) { + outStruct.getMembers().add(p); + } + for (IrPort p : node.getUnionPorts()) { + outStruct.getMembers().add(p); + } + for (IrPort p : node.getLoopPorts()) { + outStruct.getMembers().add(p); + } + node.setOutPortStruct(outStruct); + program.getGlobalScope().addIrPortStruct(outStruct); + } +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrProgram.java b/src/at/ac/uibk/iwir2wfr/ir/IrProgram.java new file mode 100755 index 0000000..6910d9b --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrProgram.java @@ -0,0 +1,250 @@ +package at.ac.uibk.iwir2wfr.ir; + +import java.util.List; +import java.util.Vector; + +import org.shiwa.fgi.iwir.AbstractCompoundTask; +import org.shiwa.fgi.iwir.AbstractPort; +import org.shiwa.fgi.iwir.AbstractTask; +import org.shiwa.fgi.iwir.BlockScope; +import org.shiwa.fgi.iwir.ControlLink; +import org.shiwa.fgi.iwir.DataLink; +import org.shiwa.fgi.iwir.ForEachTask; +import org.shiwa.fgi.iwir.ForTask; +import org.shiwa.fgi.iwir.IWIR; +import org.shiwa.fgi.iwir.IfTask; +import org.shiwa.fgi.iwir.InputPort; +import org.shiwa.fgi.iwir.LoopCounter; +import org.shiwa.fgi.iwir.LoopElement; +import org.shiwa.fgi.iwir.LoopPort; +import org.shiwa.fgi.iwir.OutputPort; +import org.shiwa.fgi.iwir.ParallelForEachTask; +import org.shiwa.fgi.iwir.ParallelForTask; +import org.shiwa.fgi.iwir.Task; +import org.shiwa.fgi.iwir.UnionPort; +import org.shiwa.fgi.iwir.WhileTask; + +import at.ac.uibk.iwir2wfr.GlobalConfig; +import at.ac.uibk.iwir2wfr.ir.IrNode.NodeType; +import at.ac.uibk.iwir2wfr.ir.IrPortStruct.IrStructType; +import at.ac.uibk.iwir2wfr.utils.NameUtils; + +public class IrProgram { + + private IrScope globalScope = new IrScope(); + + private IWIR iwirProgram = null; + + private IrNode topLeveNodel = null; + + private Vector nodes = new Vector(); + + private String wfName; + + public IrProgram() { + } + + public void analyseIwirProgram(IWIR iwir) { + wfName = iwir.getWfname(); + // Go through activities and create IR-Nodes IR-Port-Structs + iwirProgram = iwir; + AbstractTask topLevelTask = iwir.getTask(); + doFirstPass(topLevelTask, null); + doSecondPass(); + } + + /* + * Parse all tasks, ports & other stuff + */ + public void doFirstPass(AbstractTask task, IrNode parent) { + // Get activity name + String nodeName = NameUtils.escapeIdentifierName(task.getName()); + // Get activity type + NodeType nodeType; + boolean parallelFlag = false; + if (task instanceof BlockScope) { + nodeType = NodeType.BlockScopeNode; + } else if (task instanceof ForEachTask) { + nodeType = NodeType.ForEachNode; + } else if (task instanceof ForTask) { + nodeType = NodeType.ForNode; + } else if (task instanceof IfTask) { + nodeType = NodeType.IfNode; + } else if (task instanceof ParallelForEachTask) { + nodeType = NodeType.ParallelForEachNode; + parallelFlag = true; + } else if (task instanceof ParallelForTask) { + nodeType = NodeType.ParallelForNode; + parallelFlag = true; + } else if (task instanceof WhileTask) { + nodeType = NodeType.WhileNode; + } else if (task instanceof Task) { + nodeType = NodeType.AtomicNode; + } else { + nodeType = NodeType.UnknownNode; + } + // Create new node + IrNode node = null; + if (nodeType == NodeType.IfNode) { + node = new IrNode(nodeName, nodeType, task, parent, 2); // if-node has a branch-count of 2 + } else { + node = new IrNode(nodeName, nodeType, task, parent); + } + node.setParallel(parallelFlag); + globalScope.addIrNode(node); + nodes.add(node); + // Set parent and add to parent + if (parent != null && parent.getNodeType() == NodeType.IfNode) { // with if we need to find the branch the child is in + IfTask ifTask = (IfTask)parent.getIwirTask(); + boolean found = false; + for (AbstractTask t : ifTask.getThenTasks()) { + if (t == task) { + parent.getChildren(0).add(node); + node.setParentBranch(0); + found = true; + break; + } + } + if (!found) { + for (AbstractTask t : ifTask.getElseTasks()) { + if (t == task) { + parent.getChildren(1).add(node); + node.setParentBranch(1); + found = true; + break; + } + } + } + } else if (parent != null) { + parent.getChildren(0).add(node); + } + // Parse node ports + IrPort.parseIrNodePorts(node, this); + IrPortStruct.createPortStructs(node, this); + // Set top-level node + if (parent == null) { + topLeveNodel = node; + } + // Iterate over children + List children = task.getChildren(); + for (AbstractTask c : children) { + if (globalScope.getIrNode(c) == null) { + doFirstPass(c, node); + } + } + } + + + /* + * Parse all data-/control-links between ports/tasks + */ + public void doSecondPass() { + for (IrNode n : globalScope.getAllIrNodes()) { + AbstractTask iwirTask = n.getIwirTask(); + if (iwirTask instanceof AbstractCompoundTask) { // A task can only contain links if it is a composite task + AbstractCompoundTask compoundTask = (AbstractCompoundTask)iwirTask; + // Iterating over control-flow links + List clinks = compoundTask.getControlLinks(); + for (ControlLink cl : clinks) { + // retrieve from/to ir-nodes and let them get to know each other + IrNode fromNode = globalScope.getIrNode(cl.getFromTask()); + IrNode toNode = globalScope.getIrNode(cl.getToTask()); + fromNode.getControlSuccessors().add(toNode); + toNode.getControlPredecessors().add(fromNode); + } + // Iterating over data-flow links + List dlinks = compoundTask.getDataLinks(); + for (DataLink dl : dlinks) { + // retrieve from/to ir-ports + IrPort fromPort = globalScope.getIrPort(dl.getFromPort()); + IrPort toPort = globalScope.getIrPort(dl.getToPort()); + // retrieve associated from/to ir-nodes + IrNode fromNode = fromPort.getParentNode(); + IrNode toNode = toPort.getParentNode(); + // let them all know each other + fromNode.getDataSuccessors().add(toNode); + toNode.getDataPredecessors().add(fromNode); + IrNode.DataLink datalink = new IrNode.DataLink(); + datalink.fromNode = fromNode; + datalink.toNode = toNode; + datalink.fromPort = fromPort; + datalink.toPort = toPort; + fromNode.getDataLinks().add(datalink); + toNode.getDataLinks().add(datalink); + fromPort.getSuccessors().add(toPort); + toPort.getPredecessors().add(fromPort); + // Build in-port map + switch (toPort.getPortType()) { + case LoopPort: + // From is child of to => loop port back edge + if (fromPort.getParentNode().getParent() == toPort.getParentNode()) { + } else { + Vector pmap = toNode.getInPortNodeMap().get(fromNode); + if (pmap == null) { + pmap = new Vector(); + toNode.getInPortNodeMap().put(fromNode, pmap); + } + pmap.add(toPort); + } + break; + case InPort: + case LoopElements: + case LoopCounter: + case LoopCounterSPort: + Vector pmap = toNode.getInPortNodeMap().get(fromNode); + if (pmap == null) { + pmap = new Vector(); + toNode.getInPortNodeMap().put(fromNode, pmap); + } + pmap.add(toPort); + break; + default: + break; + } + // Build out-port map + switch (toPort.getPortType()) { + case OutPort: + case UnionPort: + case LoopPort: + if (fromPort.getParentNode().getParent() == toPort.getParentNode()) { + Vector pmap = toNode.getOutPortNodeMap().get(fromNode); + if (pmap == null) { + pmap = new Vector(); + toNode.getOutPortNodeMap().put(fromNode, pmap); + } + pmap.add(toPort); + } else if (fromPort.getParentNode() == toPort.getParentNode()) { + Vector pmap = toNode.getOutPortNodeMap().get(fromNode); + if (pmap == null) { + pmap = new Vector(); + toNode.getOutPortNodeMap().put(fromNode, pmap); + } + pmap.add(toPort); + } + break; + default: + break; + } + } + } + } + } + + + public IrScope getGlobalScope() { + return globalScope; + } + + public IrNode getTopLeveNode() { + return topLeveNodel; + } + + public Vector getNodes() { + return nodes; + } + + public String getWfName() { + return wfName; + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/ir/IrScope.java b/src/at/ac/uibk/iwir2wfr/ir/IrScope.java new file mode 100755 index 0000000..72c9e39 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/ir/IrScope.java @@ -0,0 +1,49 @@ +package at.ac.uibk.iwir2wfr.ir; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.shiwa.fgi.iwir.AbstractPort; +import org.shiwa.fgi.iwir.AbstractTask; + +public class IrScope { + + public Map nodeIdMap = new HashMap(); + public Map nodeAbstractTaskMap = new HashMap(); + + public Map portStructIdMap = new HashMap(); + + public Map portIwirMap = new HashMap(); + + public boolean addIrNode(IrNode node) { + nodeIdMap.put(node.getId(), node); + nodeAbstractTaskMap.put(node.getIwirTask(), node); + return true; + } + + public IrNode getIrNode(AbstractTask task) { + return nodeAbstractTaskMap.get(task); + } + + public Collection getAllIrNodes() { + return nodeIdMap.values(); + } + + public boolean addIrPortStruct(IrPortStruct portStruct) { + portStructIdMap.put(portStruct.getId(), portStruct); + return true; + } + + public Collection getPortStructs() { + return portStructIdMap.values(); + } + + public void addIrPort(IrPort port) { + portIwirMap.put(port.getIwirPort(), port); + } + + public IrPort getIrPort(AbstractPort iwirPort) { + return portIwirMap.get(iwirPort); + } +} diff --git a/src/at/ac/uibk/iwir2wfr/utils/NameUtils.java b/src/at/ac/uibk/iwir2wfr/utils/NameUtils.java new file mode 100755 index 0000000..1b5ae30 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/utils/NameUtils.java @@ -0,0 +1,13 @@ +package at.ac.uibk.iwir2wfr.utils; + +public class NameUtils { + + public static String escapeIdentifierName(String name) { + String ename = name.trim().replace(".", "_").replace(" ", "_").replace("/", "_").replace("-", "_"); + if (ename.charAt(0) >= '0' && ename.charAt(0) <= '9') { + ename = "_" + ename; + } + return ename; + } + +} diff --git a/src/at/ac/uibk/iwir2wfr/utils/PrintIR.java b/src/at/ac/uibk/iwir2wfr/utils/PrintIR.java new file mode 100755 index 0000000..202e825 --- /dev/null +++ b/src/at/ac/uibk/iwir2wfr/utils/PrintIR.java @@ -0,0 +1,28 @@ +package at.ac.uibk.iwir2wfr.utils; + +import java.io.PrintStream; + +import at.ac.uibk.iwir2wfr.ir.IrNode; +import at.ac.uibk.iwir2wfr.ir.IrProgram; + +public class PrintIR { + + public static void printIR(PrintStream stream, IrProgram program) { + IrNode tlNode = program.getTopLeveNode(); + printIRnode(stream, tlNode, ""); + } + + public static void printIRnode(PrintStream stream, IrNode node, String prefix) { + stream.println(); + stream.println(prefix + "Node-ID: " + node.getId()); + stream.println(prefix + "Node-Name: " + node.getNodeName()); + stream.println(prefix + "Node-Type: " + node.getNodeType()); + for (int t = 0; t < node.getBranchCount(); t++) { + System.out.println(prefix + "Children of branch " + t + ":"); + for (IrNode n : node.getChildren(t)) { + printIRnode(stream, n, prefix + "\t"); + } + } + } + +}