From be49c4b943aa8fc9e2ebd6302287a4f81edfa4dc Mon Sep 17 00:00:00 2001 From: Alexander Diewald <diewald@fortiss.org> Date: Thu, 22 Mar 2018 20:29:00 +0000 Subject: [PATCH] Exploration.alg: Add Channels Export for Partitions. * Adds a sub-method to the Partition Transformation Strategy that adds Ports and Channels to a PartitionAchitecture. * The required Ports and Channels are derived from the Signals exchanged between Tasks. * Ports and Channels are only added for InterPartitionCommunication (logically). * The Sampling and Queuing characteristics of PartitionPorts is derived from their corresponding TaskPorts. refs 3257 --- .../modeltransformation/partition/.ratings | 2 +- .../partition/PartitionTransformer.java | 115 +++++++++++++++++- .../fortiss/af3/exploration/alg/plot/.ratings | 2 +- .../af3/exploration/alg/plot/XYPlotter.java | 67 ++++++---- 4 files changed, 154 insertions(+), 32 deletions(-) diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/.ratings b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/.ratings index 08a954b4..35170dce 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/.ratings +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/.ratings @@ -1,2 +1,2 @@ PartitionTransformationStrategy.java 220d5175ac8ff958f82c053a934095880540fcd3 YELLOW -PartitionTransformer.java b2f9f2dc793c73b35bef529646e449012f747750 RED +PartitionTransformer.java 3226c719980e12590e02eea5b01652b19b290577 RED diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/PartitionTransformer.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/PartitionTransformer.java index b3141909..d61f8d06 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/PartitionTransformer.java +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/dse/modeltransformation/partition/PartitionTransformer.java @@ -19,6 +19,11 @@ import static org.fortiss.af3.allocation.utils.AllocationModelElementFactory.cre import static org.fortiss.af3.allocation.utils.AllocationUtils.addAllocationEntry; import static org.fortiss.af3.exploration.alg.dse.modeltransformation.ITransformationModule.TransformationState.INITIALIZING; import static org.fortiss.af3.exploration.alg.util.TransformationUtils.getArchitectureOfAllocSuperSet; +import static org.fortiss.af3.partition.util.PartitionModelElementFactory.createPartitionChannel; +import static org.fortiss.af3.partition.util.PartitionModelElementFactory.createPartitionQueuingInputPort; +import static org.fortiss.af3.partition.util.PartitionModelElementFactory.createPartitionQueuingOutputPort; +import static org.fortiss.af3.partition.util.PartitionModelElementFactory.createPartitionSamplingInputPort; +import static org.fortiss.af3.partition.util.PartitionModelElementFactory.createPartitionSamplingOutputPort; import static org.fortiss.tooling.common.util.LambdaUtils.getFirst; import java.util.Collection; @@ -38,6 +43,9 @@ import org.fortiss.af3.exploration.alg.service.IExplorationTransformationService import org.fortiss.af3.exploration.dsl_v2.model.expression.SuperSet; import org.fortiss.af3.partition.model.Partition; import org.fortiss.af3.partition.model.PartitionArchitecture; +import org.fortiss.af3.partition.model.PartitionChannel; +import org.fortiss.af3.partition.model.PartitionInputPort; +import org.fortiss.af3.partition.model.PartitionOutputPort; import org.fortiss.af3.partition.model.allocation.PartitionToExecutionUnitAllocationEntry; import org.fortiss.af3.partition.model.allocation.PartitionToExecutionUnitAllocationTable; import org.fortiss.af3.partition.model.allocation.TaskToPartitionAllocationEntry; @@ -46,12 +54,23 @@ import org.fortiss.af3.partition.util.PartitionModelElementFactory; import org.fortiss.af3.platform.model.PlatformArchitecture; import org.fortiss.af3.project.model.FileProject; import org.fortiss.af3.project.utils.ProjectUtils; +import org.fortiss.af3.task.model.Signal; +import org.fortiss.af3.task.model.Task; import org.fortiss.af3.task.model.TaskArchitecture; +import org.fortiss.af3.task.model.TaskInputPort; +import org.fortiss.af3.task.model.TaskOutputPort; +import org.fortiss.af3.task.model.TaskQueuingInputPort; +import org.fortiss.af3.task.model.TaskQueuingOutputPort; +import org.fortiss.af3.task.model.TaskSamplingInputPort; +import org.fortiss.af3.task.model.TaskSamplingOutputPort; import org.fortiss.tooling.base.model.element.IHierarchicElement; import org.fortiss.tooling.common.util.LambdaUtils; import org.fortiss.tooling.kernel.extension.data.ITopLevelElement; import org.fortiss.tooling.kernel.service.IPersistencyService; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; + /** * Initializes a {@link Deployment} by creating a new model and setting its references to the given * {@link ComponentArchitecture} and {@link PlatformArchitecture}. @@ -59,6 +78,8 @@ import org.fortiss.tooling.kernel.service.IPersistencyService; * @author diewald */ public class PartitionTransformer extends TransformationModuleBase<AllocationTableCollection> { + /** Model context to attach model elements to others. */ + ITopLevelElement modelContext; /** Input {@link TaskArchitecture} passed to the DSE. */ private TaskArchitecture taskArchitecture; /** Input {@link PlatformArchitecture} passed to the DSE. */ @@ -93,7 +114,7 @@ public class PartitionTransformer extends TransformationModuleBase<AllocationTab LambdaUtils.getFirst(partToExU.getEntries()).get(); FileProject fp = ProjectUtils.getFileProject(LambdaUtils.getFirst(entry.getTargetElements()).get()); - ITopLevelElement modelContext = IPersistencyService.getInstance().getTopLevelElementFor(fp); + modelContext = IPersistencyService.getInstance().getTopLevelElementFor(fp); // TODO: The following step should be performed in a separate module. createPartitionArchitecture(inputs.getSuperSet(Partition.class), modelContext); @@ -101,17 +122,20 @@ public class PartitionTransformer extends TransformationModuleBase<AllocationTab // Create the allocations. allocTableCollection = createAllocationTableCollection("Generated Allocations"); - TaskToPartitionAllocationTable taskExUTable = + TaskToPartitionAllocationTable taskPartTable = createTaskToPartitionAllocationTable(inputs .getSuperSet(TaskToPartitionAllocationEntry.class)); modelContext.runAsNonDirtyingCommand(() -> allocTableCollection.getContainedElements().add( - taskExUTable)); + taskPartTable)); PartitionToExecutionUnitAllocationTable partExUTable = createPartitionToExecutionUnitAllocationTable(inputs .getSuperSet(PartitionToExecutionUnitAllocationEntry.class)); modelContext.runAsNonDirtyingCommand(() -> allocTableCollection.getContainedElements().add( partExUTable)); + // Create the Interpartition comm channels + createInterPartitionComm(taskPartTable, inputs.getSuperSet(Signal.class)); + return allocTableCollection; } @@ -130,14 +154,14 @@ public class PartitionTransformer extends TransformationModuleBase<AllocationTab * the given {@link SuperSet}. */ private TaskToPartitionAllocationTable createTaskToPartitionAllocationTable( - SuperSet<TaskToPartitionAllocationEntry> taskExecUnitAllocs) { + SuperSet<TaskToPartitionAllocationEntry> taskPartAllocs) { TaskToPartitionAllocationTable table = org.fortiss.af3.partition.util.PartitionModelElementFactory .createTaskToPartitionAllocationTable("Generated Task->Part Table"); table.setSourceView(taskArchitecture); table.setTargetView(partitionArchitecture); - for(TaskToPartitionAllocationEntry entry : taskExecUnitAllocs.getEntries()) { + for(TaskToPartitionAllocationEntry entry : taskPartAllocs.getEntries()) { Partition af3Partition = (Partition)entry.getTargetElement(); // TODO: We assume single Tasks in this place. addAllocationEntry(table, TaskToPartitionAllocationEntry.class, @@ -167,6 +191,87 @@ public class PartitionTransformer extends TransformationModuleBase<AllocationTab return table; } + private void createInterPartitionComm(TaskToPartitionAllocationTable taskPartAllocTable, + SuperSet<Signal> signals) { + // Extract sender / receiver information from the signals + Multimap<Task, Signal> senderTaskToSignal = HashMultimap.create(); + Multimap<Task, Partition> senderTaskToRecvPartition = HashMultimap.create(); + for(Signal signal : signals.getEntries()) { + Task senderTask = (Task)signal.getSource().getOwner(); + senderTaskToSignal.put(senderTask, signal); + } + + for(TaskToPartitionAllocationEntry alloc : taskPartAllocTable + .getAllocationEntries(TaskToPartitionAllocationEntry.class)) { + // TODO: currently, the supersets contain only 1:1 allocations. + Collection<Task> allocatedTasks = + (Collection<Task>)(Collection<?>)alloc.getSourceElements(); + Partition senderPartition = (Partition)alloc.getTargetElement(); + for(Task senderTask : allocatedTasks) { + // Get the target task. + for(Signal signal : senderTaskToSignal.get(senderTask)) { + TaskInputPort targetInputPort = signal.getTargetTaskPort(); + Task targetTask = (Task)targetInputPort.getOwner(); + Partition targetPartition = taskPartAllocTable.getPartition(targetTask); + // Only create channels for interpartition communication. + if(senderPartition != targetPartition) { + PartitionOutputPort senderPartitionPort = null; + // TODO: combine the following ifs using an enum to denote the port type. + TaskOutputPort senderPort = signal.getSourceTaskPort(); + if(senderPort instanceof TaskSamplingOutputPort) { + senderPartitionPort = + createPartitionSamplingOutputPort("Part_" + + senderPort.getName()); + } else if(senderPort instanceof TaskQueuingOutputPort) { + senderPartitionPort = + createPartitionQueuingOutputPort("Part_senderPort.getName()"); + } + addSenderPartitionPort(senderPartition, senderPartitionPort); + + PartitionInputPort targetPartitionPort = null; + if(targetInputPort instanceof TaskSamplingInputPort) { + targetPartitionPort = + createPartitionSamplingInputPort("Part_" + + targetInputPort.getName()); + } else if(targetInputPort instanceof TaskQueuingInputPort) { + targetPartitionPort = + createPartitionQueuingInputPort("Part_" + + targetInputPort.getName()); + } + addTargetPartitionPort(targetPartition, targetPartitionPort); + createAndAddPartitionChannel(senderPartitionPort, targetPartitionPort); + } + } + } + } + } + + private void addSenderPartitionPort(Partition senderPartition, + final PartitionOutputPort senderPartitionPort) { + modelContext.runAsNonDirtyingCommand(() -> senderPartition.getConnectors().add( + senderPartitionPort)); + } + + private void addTargetPartitionPort(Partition targetPartition, + final PartitionInputPort targetPartitionPort) { + modelContext.runAsNonDirtyingCommand(() -> targetPartition.getConnectors().add( + targetPartitionPort)); + } + + private void createAndAddPartitionChannel(final PartitionOutputPort senderPartitionPort, + final PartitionInputPort targetPartitionPort) { + modelContext + .runAsNonDirtyingCommand(() -> { + PartitionChannel partitionChannel = + createPartitionChannel( + senderPartitionPort, + targetPartitionPort, + senderPartitionPort.getName() + " --> " + + targetPartitionPort.getName()); + partitionArchitecture.getConnections().add(partitionChannel); + }); + } + /** {@inheritDoc} */ @Override public Class<AllocationTableCollection> getOutputType() { diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/.ratings b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/.ratings index 98ccaf4e..3d0c634c 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/.ratings +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/.ratings @@ -4,4 +4,4 @@ ScheduleLabelGenerator.java 0ceecedfec9802bbcaa33525d61e1a60a70d3841 RED SchedulePlotter.java 29b1156c9419d4ff3314c4b2c932aeb46f4749f8 RED ScheduleToolTipGenerator.java cedfa0dd7ebc7b48d7cc70e966eebaeee9636caf RED TaskSeriesCollectionFromSchedule.java b53b7af649c48980520ad572da8c7bbdbae0aed5 RED -XYPlotter.java bdea08cbfbaea8755a225c149a5aba8830a68549 RED +XYPlotter.java b8abd061e80509c7c8af83baf584e9549c98a4d9 RED diff --git a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/XYPlotter.java b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/XYPlotter.java index e6d38d79..8374540a 100644 --- a/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/XYPlotter.java +++ b/org.fortiss.af3.exploration.alg/trunk/src/org/fortiss/af3/exploration/alg/plot/XYPlotter.java @@ -19,6 +19,7 @@ import static javax.swing.JOptionPane.YES_OPTION; import static org.fortiss.af3.exploration.alg.ExplorationAlgActivator.PLUGIN_ID; import static org.fortiss.af3.exploration.alg.service.ExplorationService.getService; import static org.fortiss.af3.exploration.alg.service.IExplorationTransformationService.TransformationContext.EXPORT; +import static org.fortiss.af3.exploration.util.DesignSpaceExplorationModelElementFactory.createSuperSetMap; import static org.fortiss.af3.exploration.util.ExplorationUtils.createExceptionStatus; import static org.fortiss.af3.project.utils.ProjectUtils.getFileProject; import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getRootElements; @@ -59,6 +60,7 @@ import org.fortiss.af3.exploration.dsl_v2.model.expression.SuperSet; import org.fortiss.af3.exploration.model.ExplorationConstraint; import org.fortiss.af3.exploration.model.ExplorationSpecification; import org.fortiss.af3.exploration.model.ExplorationTarget; +import org.fortiss.af3.exploration.model.SuperSetMap; import org.fortiss.af3.exploration.model.solutions.ExplorationResult; import org.fortiss.af3.exploration.model.solutions.ExplorationSolution; import org.fortiss.af3.exploration.model.solutions.SingleExplorationSolution; @@ -216,11 +218,11 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe public void createPlot() { // TODO: Do we want to add constraints here? goalList = new ArrayList<ExplorationTarget<?>>(); - goalList.addAll( - expSpec.getTargets().stream() - .filter(t -> !(t instanceof ExplorationConstraint && - ((ExplorationConstraint<?>)t).isImplicit())) - .collect(Collectors.toList())); + goalList.addAll(expSpec + .getTargets() + .stream() + .filter(t -> !(t instanceof ExplorationConstraint && ((ExplorationConstraint<?>)t) + .isImplicit())).collect(Collectors.toList())); goalList.stream().forEach(t -> targetUIMap.put(t, new ExplorationTargetItem(t))); @@ -406,7 +408,7 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe PlotOrientation.VERTICAL, true, // include legend true, // tooltips false // urls - ); + ); chart.setBackgroundPaint(Color.white); chart.getLegend().setPosition(RectangleEdge.TOP); @@ -491,8 +493,9 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe XYDataItem item = new XYDataItem(x, y); currentSolution = coordinateToSolution.get(item); - Optional<SingleExplorationSolution> singleExpSol = explorationResult.getSolutions() - .stream().filter(r -> r == currentSolution).findAny(); + Optional<SingleExplorationSolution> singleExpSol = + explorationResult.getSolutions().stream().filter(r -> r == currentSolution) + .findAny(); if(singleExpSol.isPresent()) { SingleExplorationSolution currentSolMap = singleExpSol.get(); // TODO: identifying the elements by their names is not good style, the map is not @@ -505,8 +508,8 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe ExplorationResult<?> expResult = currentSolMap.get(target); if(objectiveToGuiItems.get(target) != null && (expResult != null && expResult.getResult() instanceof Double)) { - objectiveToGuiItems.get(target).objTextField - .setText(Double.toString((Double)expResult.getResult())); + objectiveToGuiItems.get(target).objTextField.setText(Double + .toString((Double)expResult.getResult())); } } } @@ -535,9 +538,10 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe } else if("generateDeployment".equals(e.getActionCommand())) { if(currentSolution != null) { - String deploymentName = (String)JOptionPane.showInputDialog(this, - "Generate Deployment", "Enter a name for the Deployment", - JOptionPane.QUESTION_MESSAGE, null, null, "_Deployment"); + String deploymentName = + (String)JOptionPane.showInputDialog(this, "Generate Deployment", + "Enter a name for the Deployment", JOptionPane.QUESTION_MESSAGE, + null, null, "_Deployment"); int generateSCSpcec = 0; if(deploymentName != null) { // if(pickFirstInstanceOf(SafetyComplianceConstraint.class, dse @@ -559,9 +563,10 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe "Cannot perform model transformation : No Exploration Solution Selected!"); } } else if("generateAllDeployments".equals(e.getActionCommand())) { - String deploymentName = (String)JOptionPane.showInputDialog(this, - "Generate All Deployments", "Enter a name prefix for the resulting deployments", - JOptionPane.QUESTION_MESSAGE, null, null, "GenDeployment_"); + String deploymentName = + (String)JOptionPane.showInputDialog(this, "Generate All Deployments", + "Enter a name prefix for the resulting deployments", + JOptionPane.QUESTION_MESSAGE, null, null, "GenDeployment_"); if(deploymentName != null) { int generateSCSpcec = 0; // if(pickFirstInstanceOf(SafetyComplianceConstraint.class, dse @@ -582,8 +587,8 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe } } else if("showschedule".equals(e.getActionCommand())) { JOptionPane.showMessageDialog(this, - "The schedule view is currently disabled due to a rework of the solution" + - " transformation framework."); + "The schedule view is currently disabled due to a rework of the solution" + + " transformation framework."); // IScheduleSolution<?> scheduleSolution = // currentSolution.getSolutionModel(IScheduleSolution.class); // if(scheduleSolution instanceof StrictTTSchedule<?, ?>) { @@ -639,8 +644,9 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe solutionMap.getSolutionSets().get(PartitionToExecutionUnitAllocationEntry.class); PartitionToExecutionUnitAllocationEntry entry = LambdaUtils.getFirst(partToExU.getEntries()).get(); - ITopLevelElement modelContext = IPersistencyService.getInstance() - .getTopLevelElementFor(LambdaUtils.getFirst(entry.getTargetElements()).get()); + ITopLevelElement modelContext = + IPersistencyService.getInstance().getTopLevelElementFor( + LambdaUtils.getFirst(entry.getTargetElements()).get()); Collection<Class<?>> solutionModelTypes = new HashSet<>(); // solutionModelTypes.add(Deployment.class); @@ -649,8 +655,18 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe // solutionModelTypes.add(SafetyComplianceSpecification.class); } + // TODO: clearer separation between In- and output models. + // Create a new SuperSet Map that combines in and outputs. + SuperSetMap solutionSuperSets = solutionMap.getSolutionSets(); + SuperSetMap superSetMap = createSuperSetMap(); + for(Class<?> setType : solutionSuperSets.keySet()) { + superSetMap.put((Class)setType, solutionSuperSets.get((Class)setType)); + } + for(Class<?> setType : expSpec.getSearchSpace().keySet()) { + superSetMap.put((Class)setType, expSpec.getSearchSpace().get((Class)setType)); + } ExplorationTransformationInputs inputs = - new ExplorationTransformationInputs(solutionMap.getSolutionSets(), null); + new ExplorationTransformationInputs(superSetMap, null); AllocationTableCollection deployment = null; Map<Class<EObject>, ?> solutionModels = getService(IExplorationTransformationService.class).getTransformedModels(EXPORT, @@ -706,8 +722,8 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe Integer deploymentNumber = 1; for(SingleExplorationSolution solution : explorationResult.getSolutions()) { - transformedDeployments.add(transformSingleDeployment(solution, - deploymentName + "_" + deploymentNumber, generateSCSpec)); + transformedDeployments.add(transformSingleDeployment(solution, deploymentName + "_" + + deploymentNumber, generateSCSpec)); deploymentNumber++; } @@ -739,8 +755,9 @@ public class XYPlotter extends JFrame implements ChartMouseListener, ActionListe */ private <S extends InstantiatedTaskMappingEntry, T extends InstantiatedTaskMappingEncoding<S>> void addDeploymentToProject(Deployment deployment) { - ComponentArchitecture deployedArchitecture = (ComponentArchitecture)deployment - .getComponentArchitectureReference().getReference(); + ComponentArchitecture deployedArchitecture = + (ComponentArchitecture)deployment.getComponentArchitectureReference() + .getReference(); FileProject fp = getFileProject(expSpec); if(!getRootElements(expSpec, ComponentArchitecture.class).contains(deployedArchitecture)) { fp.getRootElements().add(deployedArchitecture); -- GitLab