Skip to content
Snippets Groups Projects
Commit 1bb92e43 authored by Alexander Diewald's avatar Alexander Diewald
Browse files

- Move the porting utils in order to reduce the...

- Move the porting utils in order to reduce the org.fortiss.af3.exploration.alg.ui plugin. The PortingUtil class shall be iteratively removed in a later state of porting.
parent b89f56d4
No related branches found
No related tags found
No related merge requests found
......@@ -182,4 +182,5 @@ Export-Package: com.google.common.annotations,
org.fortiss.af3.exploration.moea.model.solutions.impl,
org.fortiss.af3.exploration.moea.model.solutions.util,
org.fortiss.af3.exploration.moea.model.util,
org.fortiss.af3.exploration.port,
org.fortiss.af3.exploration.util
/*--------------------------------------------------------------------------+
$Id: codetemplates.xml 1 2011-01-01 00:00:01Z hoelzl $
| |
| Copyright 2017 ForTISS GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.exploration.port;
import static org.fortiss.af3.exploration.alg.dse.sysmodel.arch.IResourceConnectionAdapter.ConnectionType.BIDIRECTIONAL;
import static org.fortiss.af3.platform.utils.PlatformArchitectureUtils.getReferencedElementsWithType;
import static org.fortiss.tooling.common.util.LambdaUtils.filterStream;
import static org.fortiss.tooling.common.util.LambdaUtils.getFirst;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.getChildrenWithType;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import static org.fortiss.tooling.kernel.utils.KernelModelElementUtils.getParentElement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.conqat.lib.commons.collections.Pair;
import org.fortiss.af3.component.model.Component;
import org.fortiss.af3.component.model.ComponentArchitecture;
import org.fortiss.af3.component.model.OutputPort;
import org.fortiss.af3.component.model.Port;
import org.fortiss.af3.exploration.alg.dse.sysmodel.arch.IResourceConnectionAdapter.ConnectionType;
import org.fortiss.af3.exploration.alg.dse.sysmodel.arch.SystemParameterContainer;
import org.fortiss.af3.exploration.dsl_v2.model.booleanp.allocation.Allocation;
import org.fortiss.af3.exploration.extension.IDseInputParameters.DeployableComponents;
import org.fortiss.af3.exploration.extension.IDseInputParameters.SignalType;
import org.fortiss.af3.exploration.extension.IDseInputParameters.TemporalTriggers;
import org.fortiss.af3.exploration.model.ExplorationSpecification;
import org.fortiss.af3.exploration.moea.model.annotation.ComponentDiverseImplRef;
import org.fortiss.af3.exploration.projectmodel.DSE;
import org.fortiss.af3.expression.model.types.TBool;
import org.fortiss.af3.expression.model.types.TDouble;
import org.fortiss.af3.expression.model.types.TInt;
import org.fortiss.af3.platform.model.ExecutionUnit;
import org.fortiss.af3.platform.model.IPhysicalPlatformArchitectureElement;
import org.fortiss.af3.platform.model.IPlatformArchitectureElement;
import org.fortiss.af3.platform.model.IPlatformResource;
import org.fortiss.af3.platform.model.IVirtualizationPlatformArchitectureElement;
import org.fortiss.af3.platform.model.PlatformArchitecture;
import org.fortiss.af3.platform.model.TransmissionUnit;
import org.fortiss.af3.platform.utils.PlatformArchitectureUtils;
import org.fortiss.af3.project.model.FileProject;
import org.fortiss.af3.project.model.typesystem.IType;
import org.fortiss.af3.task.model.TaskAllocation;
import org.fortiss.af3.task.model.TaskArchitecture;
import org.fortiss.tooling.base.model.element.IConnector;
import org.fortiss.tooling.base.model.element.IModelElement;
import org.fortiss.tooling.kernel.utils.EcoreUtils;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
/**
*
* @author diewald
* @author $Author: hoelzl $
* @version $Rev: 18709 $
* @ConQAT.Rating RED Hash:
*/
public class DSEPortingUtils {
/**
* Lookup table for to determine the direction of a connection by the type of the target
* {@link IConnector}.
*/
// TODO: UsePlatformPort?
public static Map<Class<? extends IConnector>, ConnectionType> connectionTypeLUT = Collections
.unmodifiableMap(new HashMap<Class<? extends IConnector>, ConnectionType>() {
{
}
});
/**
* Returns the type of communication the given port can handle: incoming, outgoing, or
* bidirectional traffic.
*
* @param sourceConnector
* {@link IConnector} to be examined.
* @return The port type (default = bidirectional).
*/
public static ConnectionType getPortDirection(IConnector sourceConnector) {
ConnectionType connectionTypeSource = connectionTypeLUT.get(sourceConnector.getClass());
return connectionTypeSource != null ? connectionTypeSource : BIDIRECTIONAL;
}
/**
* Creates a collection of deployment targets (that are {@link ExecutionUnit}s) from the given
* collection of {@code platformArchitecture}s. Therefore, the {@link DeploymentGranularity}
* annotation is examined for each {@link ExecutionUnit} present in the given Platforms.
*
* @param platformArchitectures
* for which to extract the collection of deployment {@link ExecutionUnit}s.
* @return collection of deployment targets.
* @throws Exception
* if an invalid combination of {@link DeploymentGranularity} specifications has
* been detected.
*/
public static Collection<ExecutionUnit> createDeploymentTargets(
Collection<PlatformArchitecture> platformArchitectures) throws Exception {
Collection<ExecutionUnit> rval = new HashSet<>();
FileProject prj =
getParentElement(getFirst(platformArchitectures, x -> true).get(),
FileProject.class, false);
DSE af3DSE = pickFirstInstanceOf(DSE.class, prj.getRootElements());
ExplorationSpecification expSpec = af3DSE.getExplorationSpecification();
Collection<Allocation> allocConstrSet =
EcoreUtils.getChildrenWithType(expSpec, Allocation.class);
for(Allocation alloc : allocConstrSet) {
Collection<IModelElement> targetElementSet =
alloc.getRight().getSetReference().getEntries();
filterStream(targetElementSet, e -> e instanceof ExecutionUnit).map(
ExecutionUnit.class::cast).forEach(e -> rval.add(e));
}
// for(PlatformArchitecture curPA : platformArchitectures) {
// for(DeploymentGranularity deplAnn : getChildrenWithType(curPA,
// DeploymentGranularity.class)) {
// IModelElement execUnit = deplAnn.getSpecificationOf();
//
// // If the current deployment target is a virtual ExecutionUnit, e.g. a partition,
// // ensure that none its referenced physical ExecutionUnits (or any of theri parents)
// // are also selected as deployment targets.
// if(execUnit instanceof IVirtualizationPlatformArchitectureElement &&
// execUnit instanceof ExecutionUnit) {
// for(IHierarchicElement currentHardwareResource : getReferencedElementsWithType(
// execUnit, IHierarchicElement.class)) {
// if(isAnyParentDeploymentTarget(currentHardwareResource)) {
// String refHwResourceName = currentHardwareResource.toString();
// if(currentHardwareResource instanceof INamedElement) {
// refHwResourceName =
// ((INamedElement)currentHardwareResource).getName() +
// "(id: " +
// ((INamedElement)currentHardwareResource).getId() +
// ")";
// }
// throw new Exception("The referenced hardware resource " +
// refHwResourceName +
// " or one of its containers of the virtual element " +
// ((ExecutionUnit)execUnit).getName() + "(id: " +
// ((ExecutionUnit)execUnit).getId() +
// ") has been chosen as a deployment target.\n" +
// "This is not allowed for elements with a virtualization layer.");
// }
// }
// }
//
// if(execUnit instanceof ExecutionUnit && deplAnn.isIsDeploymentTarget()) {
// rval.add((ExecutionUnit)execUnit);
// }
// }
// }
if(rval.isEmpty()) {
throw new Exception(
"No deployment targets have been specified in the target platform architecture(s)."
+ " Please check whether the correct platform architecture was selected and whether"
+ " the desired Execution Units were selected as deployment targets"
+ " (Platform Model --> Annotation View --> Deployment Target)");
}
return rval;
}
// TODO: Why is the FailureRate annotation bound to IPhysicalPlatformElement instead of
// IPlatformResource?
/**
* Creates a Map that relates all annotated {@link IPlatformArchitectureElement}s with their
* specified {@link FailureRate}.
*/
public static Map<IPlatformArchitectureElement, Double> createFailureRateMap(
Collection<PlatformArchitecture> platformArchitectures) throws Exception {
Map<IPlatformArchitectureElement, Double> failureRateMap = new HashMap<>();
for(PlatformArchitecture pa : platformArchitectures) {
for(IPlatformArchitectureElement platformElement : getChildrenWithType(pa,
IPlatformArchitectureElement.class)) {
failureRateMap.put(platformElement, getResourceFailureRate(platformElement));
}
}
return failureRateMap;
}
/**
* Extracts the failure probability of a given {@link IPlatformResource}. If the
* {@code resourceElement} is a {@link IVirtualizationPlatformArchitectureElement}, the average
* value of the referenced {@link IPhysicalPlatformArchitectureElement}s is used.
*
* @param resourceElement
* resource for which to determine the failure probability.
* @return failure probability of the given {@code resourceElement}.
* @throws Exception
* if the failure probability is not correctly defined in the model.
*/
// TODO: check, whether it make sense to move the failure rate annotation to the AF3 platform
// since it would allow a simple analysis of hierarchical platforms.
public static Double getResourceFailureRate(IPlatformArchitectureElement resourceElement)
throws Exception {
// If the annotated element is a part of the system software, the resource links are used to
// determine the speed of the associated resources.
if(resourceElement instanceof IVirtualizationPlatformArchitectureElement) {
Collection<IPhysicalPlatformArchitectureElement> associatedResources =
getReferencedElementsWithType(resourceElement,
IPhysicalPlatformArchitectureElement.class);
if(!(associatedResources.isEmpty())) {
Double avgFailureRate = Double.valueOf(0);
for(IPhysicalPlatformArchitectureElement currentAssociatedResource : associatedResources) {
if(currentAssociatedResource instanceof IModelElement) {
// FIXME: For now, just use a default value.
return 10E-6;
// FailureRate failureRateAnnotation =
// getAnnotation((IModelElement)currentAssociatedResource,
// FailureRate.class);
//
// if(failureRateAnnotation != null) {
// avgFailureRate += failureRateAnnotation.getFailureRate_FIT();
// } else {
// throw new Exception("The platform resource " +
// currentAssociatedResource +
// " does not have a failure rate annotation.");
// }
}
}
return avgFailureRate / associatedResources.size();
} else if(resourceElement instanceof ExecutionUnit) {
// For now the failure rates are only evaluated for ExecutionUnits, so the failure
// rate annotation is only required for these resources.
throw new Exception("The virtual resource " + resourceElement.toString() +
" does not reference a physical resource");
}
} else {
// FIXME: For now, just use a default value.
return 10E-6;
// FailureRate failureRateAnnotation =
// pickFirstInstanceOf(FailureRate.class,
// ((IModelElement)resourceElement).getSpecifications());
//
// if(failureRateAnnotation != null) {
// return failureRateAnnotation.getFailureRate_FIT();
// }
// throw new Exception("The platform resource " + resourceElement +
// " does not have a failure rate annotation.");
}
return null;
// throw new Exception("The failure rate for the platform resource " + resourceElement +
// " coult not be determined.");
}
/**
* Creates a map of all {@link IPlatformResource} which have an annotated power consumption
* value and their specified value.
*/
public static Map<IPlatformResource, Double> createPowerConsumptionMap(
Collection<PlatformArchitecture> platformArchitectures) throws Exception {
Map<IPlatformResource, Double> powerConsumptionMap = new HashMap<>();
powerConsumptionMap.putAll(getTransmissionUnitPowerConsumption(platformArchitectures));
return powerConsumptionMap;
}
/** Maps all {@link TransmissionUnit}s to their annotated power consumption value. */
// TODO: We need a way to define the energy consumed by transmission units like busses: stand-by
// + active. Currently, we hard-code the consumed energy while a transmission Unit is active
// while we assue that it does not consume energy in the idle state.
public static Map<IPlatformResource, Double> getTransmissionUnitPowerConsumption(
Collection<PlatformArchitecture> platformArchitectures) {
Map<IPlatformResource, Double> powerConsumptionMap = new HashMap<>();
for(PlatformArchitecture pa : platformArchitectures) {
for(TransmissionUnit tu : getChildrenWithType(pa, TransmissionUnit.class)) {
powerConsumptionMap.put(tu, 1.0);
}
}
return powerConsumptionMap;
}
/**
* Maps all deployable {@link Component}s to their specified periodicities. Non-periodic
* {@link Component} are not supported.
*/
// FIXME: The period is hard-coded here. It must be taken from the yet-to-come timing model.
public static Map<Component, Double> createComponentPeriodMap(
Collection<Component> deployableComponents) {
Map<Component, Double> componentPeriodMap = new HashMap<>();
for(Component deployableComponent : deployableComponents) {
componentPeriodMap.put(deployableComponent, 10.0);
}
return componentPeriodMap;
}
/**
* Maps all "abstract" and deployable {@link Component}s the set of {@link Component}s which are
* selected as their diverse implementations by means of the {@link ComponentDiverseImplRef}
* annotation.
*/
public static Multimap<Component, Component> createComponentReplacementMap(
Collection<Component> deployableComponent) {
Multimap<Component, Component> replacementComponentMap = HashMultimap.create();
for(Component component : deployableComponent) {
// ComponentDiverseImplRef componentReplacementRef =
// AnnotationUtils.getAnnotation(component, ComponentDiverseImplRef.class);
// replacementComponentMap.putAll(component, componentReplacementRef.getComponentRef());
replacementComponentMap.putAll(component, Collections.emptyList());
}
return replacementComponentMap;
}
/**
* Maps all deployable {@link Component}s to their amount of minimal required and maximally
* allowed replicas. A value of 1 implies that the component is present only once (without
* actual replica in the resulting solution calculated by the DSE).
*/
// FIXME:
public static Map<Component, Pair<Integer, Integer>> createComponentReplicationMap(
Collection<Component> deployableComponents) throws Exception {
Map<Component, Pair<Integer, Integer>> replicationBoundMap = new HashMap<>();
for(Component component : deployableComponents) {
// TODO: where shall the replication bound be placed? ComponentArchitecture,
// TaskArchitecture?
// ReplicationBounds replicationBounds = getAnnotation(component,
// ReplicationBounds.class);
// if(replicationBounds == null) {
// throw new Exception("The replication bounds of the component " +
// component.getName() + " is not defined.");
// }
Pair<Integer, Integer> minMaxBounds = new Pair<>(1, 1);
replicationBoundMap.put(component, minMaxBounds);
}
return replicationBoundMap;
}
/**
* Returns the temporal triggers of the deployable {@link Component}s' {@link Port}s.
*
* @param deployableComponents
* Collection of {@link Component}s tthat shall be deployed.
* @return Map of the ports with a temporal trigger.
*/
public static TemporalTriggers
getPortTimingProperties(DeployableComponents deployableComponents) {
TemporalTriggers portSignalTypes = new TemporalTriggers();
Collection<Port> allPorts = new ArrayList<>();
for(Component currComp : deployableComponents) {
allPorts.addAll(getChildrenWithType(currComp, Port.class));
}
allPorts.parallelStream().forEach(p -> portSignalTypes.put(p, SignalType.PERIODIC));
return portSignalTypes;
}
/** Maps the {@link OutputPort}s of {@link Component}s to their respective bit size. */
public static Map<OutputPort, Long> createMessageSizeMap(
Collection<Component> deployableComponents) throws Exception {
Map<OutputPort, Long> messageSizes = new HashMap<>();
for(Component component : deployableComponents) {
for(OutputPort port : component.getOutputPorts()) {
IType outType = port.getVariableType();
// FIXME: Primitive fixed bit length assignments for the types. Should be done based
// on the platform.
if(outType instanceof TBool) {
messageSizes.put(port, (long)1);
} else if(outType instanceof TInt) {
messageSizes.put(port, (long)32);
} else if(outType instanceof TDouble) {
messageSizes.put(port, (long)64);
} else {
throw new Exception("No type has been defined for the output port" + port +
" that is compatible with the MOEA-based DSE exploration.");
}
}
}
return messageSizes;
}
/**
* Creates a container that contains all required and optional information to execute the
* MOEA-based DSE which are not AF3 standard parameters.
*/
public static SystemParameterContainer createSystemParameterContainer(
ComponentArchitecture componentArchitecture, PlatformArchitecture platformArchitecture,
TaskArchitecture taskArchitecture) throws Exception {
DeployableComponents deployableComponents = new DeployableComponents();
// FIXME: We select the atomic components from the ComponentArchitecture to be deployed at
// the moment. Instead, the TaskArchitecture should be used here.
for(TaskAllocation taskAlloc : taskArchitecture.getTaskAllocations()) {
deployableComponents.addAll(taskAlloc.getComponents());
}
// Set: if we have only a hardware platform, then it will be returned by getHardwarePlatform
// --> no duplicates.
Set<PlatformArchitecture> targetPlatforms = new HashSet<>();
targetPlatforms.add(platformArchitecture);
targetPlatforms.add(PlatformArchitectureUtils
.getPhysicalPlatformArchitecture(platformArchitecture));
Collection<ExecutionUnit> deploymentTargets = createDeploymentTargets(targetPlatforms);
return new SystemParameterContainer(deployableComponents,
getPortTimingProperties(deployableComponents), deploymentTargets,
createComponentPeriodMap(deployableComponents),
createComponentReplacementMap(deployableComponents),
createComponentReplicationMap(deployableComponents),
createMessageSizeMap(deployableComponents), createFailureRateMap(targetPlatforms),
createPowerConsumptionMap(targetPlatforms), connectionTypeLUT, null, null);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment