use of org.osate.aadl2.instance.ModeInstance in project osate2 by osate.
the class Binpack method binPackSystem.
protected AssignmentResult binPackSystem(final SystemInstance root, Expansor expansor, LowLevelBinPacker packer, final AnalysisErrorReporterManager errManager, final SystemOperationMode som) {
existsProcessorWithMIPS = false;
existsProcessorWithoutMIPS = false;
existsThreadWithReferenceProcessor = false;
existsThreadWithoutReferenceProcessor = false;
/*
* Map from AADL ComponentInstances representing threads to
* the bin packing SoftwareNode that models the thread.
*/
final Map<ComponentInstance, AADLThread> threadToSoftwareNode = new HashMap<>();
/*
* Set of thread components. This is is the keySet of
* threadToSoftwareNode.
*/
final Set<ComponentInstance> threads = threadToSoftwareNode.keySet();
/*
* Map from AADL ComponentInstances representing threads to
* the set of AADL ComponentInstances that cannot be collocated
* with it.
*/
final Map<ComponentInstance, Set<ComponentInstance>> notCollocated = new HashMap<>();
/*
* Map from AADL ComponentInstance representing processors to
* the bin packing Processor that models them.
*/
final Map<ComponentInstance, AADLProcessor> procToHardware = new HashMap<>();
/*
* Map from AADL BusInstance representing Buses to
* The bin packing Link that models them.
*/
final Map<ComponentInstance, AADLBus> busToHardware = new HashMap<>();
/*
* One site to rule them all! We don't care about the site
* architecture, so just create one site to hold everything.
* We aren't worried about power or space issues either, so
* we just set them to 100.0 because those are nice values.
* The site accepts AADL processors.
*/
final SiteArchitecture siteArchitecture = new SiteArchitecture();
AADLProcessor ap = AADLProcessor.PROTOTYPE;
final Site theSite = new Site(100.0, 100.0, new SiteGuest[] { ap });
siteArchitecture.addSite(theSite);
/*
* The hardware is fixed based on the AADL specification, so we
* use the NoExpansionExpansor to keep the hardware from being
* generated for us.
*/
expansor.setSiteArchitecture(siteArchitecture);
/*
* Populate the problem space based on the AADL specification. First
* we walk the instance model and add all the processors. Then we
* walk the instance model again to add all the threads.
*/
OutDegreeAssignmentProblem problem1 = new OutDegreeAssignmentProblem(new OutDegreeComparator(), new BandwidthComparator(), new CapacityComparator());
problem1.setErrorReporter(new BinPackErrorReporter());
final OutDegreeAssignmentProblem problem = problem1;
// Add procs
final ForAllElement addProcessors = new ForAllElement(errManager) {
@Override
public void process(Element obj) {
ComponentInstance ci = (ComponentInstance) obj;
// the createInstance method already assigns a default MIPS if none exists
double mips = GetProperties.getProcessorMIPS(ci);
// checking consistency;
existsProcessorWithMIPS |= (mips != 0);
existsProcessorWithoutMIPS |= (mips == 0);
final AADLProcessor proc = AADLProcessor.createInstance(ci);
if (proc != null) {
System.out.println("Processor cycles Per sec:" + proc.getCyclesPerSecond());
siteArchitecture.addSiteGuest(proc, theSite);
problem.getHardwareGraph().add(proc);
// add reverse mapping
procToHardware.put(ci, proc);
}
}
};
addProcessors.processPreOrderComponentInstance(root, ComponentCategory.PROCESSOR);
/*
* Get all the links
*/
final ForAllElement addBuses = new ForAllElement(errManager) {
@Override
public void process(Element obj) {
ComponentInstance bi = (ComponentInstance) obj;
final AADLBus bus = AADLBus.createInstance(bi);
busToHardware.put(bi, bus);
}
};
addBuses.processPreOrderComponentInstance(root, ComponentCategory.BUS);
/*
* create the links between processors and busses
* (i.e., process connections)
*/
for (final Iterator<ConnectionInstance> i = root.getAllConnectionInstances().iterator(); i.hasNext(); ) {
final ConnectionInstance connInst = i.next();
if (connInst.getKind() == ConnectionKind.ACCESS_CONNECTION) {
InstanceObject src = connInst.getSource();
InstanceObject dst = connInst.getDestination();
AADLBus bus = null;
AADLProcessor processor = null;
// swap if i got them in the opposite order
if (src instanceof FeatureInstance) {
InstanceObject tmp = dst;
dst = src;
src = tmp;
}
bus = busToHardware.get(src);
FeatureInstance fi = (FeatureInstance) dst;
processor = procToHardware.get(fi.getContainingComponentInstance());
if (bus != null && processor != null) {
bus.add(processor);
processor.attachToLink(bus);
}
}
}
for (Iterator<AADLBus> iBus = busToHardware.values().iterator(); iBus.hasNext(); ) {
AADLBus bus = iBus.next();
problem.addLink(bus);
siteArchitecture.addSiteGuest(bus, theSite);
}
// Add threads
final ForAllElement addThreads = new ForAllElement(errManager) {
@Override
public void process(Element obj) {
final ComponentInstance ci = (ComponentInstance) obj;
/**
* JD - check the modes according to what was
* suggested by Dave.
*/
boolean selected = true;
if (som.getCurrentModes().size() > 0) {
selected = false;
for (ModeInstance mi : ci.getInModes()) {
if (mi == som.getCurrentModes().get(0)) {
selected = true;
}
}
}
if (!selected) {
return;
}
final AADLThread thread = AADLThread.createInstance(ci);
double refmips = GetProperties.getReferenceMIPS(ci);
// validate consistency
existsThreadWithReferenceProcessor |= (refmips != 0);
existsThreadWithoutReferenceProcessor |= (refmips == 0);
problem.getSoftwareGraph().add(thread);
// logInfo(thread.getReport());
// add reverse mapping
threadToSoftwareNode.put(ci, thread);
// Process NOT_COLLOCATED property.
RecordValue disjunctFrom = GetProperties.getNotCollocated(ci);
if (disjunctFrom == null) {
return;
}
final Set<ComponentInstance> disjunctSet = new HashSet<>();
ListValue tvl = (ListValue) PropertyUtils.getRecordFieldValue(disjunctFrom, "Targets");
for (PropertyExpression ref : tvl.getOwnedListElements()) {
/*
* Add all the instances rooted at the named instance.
* For example, the thread may be declared to be disjunct
* from another process, so we really want to be disjunct
* from the other threads contained in that process.
*/
final InstanceReferenceValue rv = (InstanceReferenceValue) ref;
final ComponentInstance refCI = (ComponentInstance) rv.getReferencedInstanceObject();
disjunctSet.addAll(refCI.getAllComponentInstances());
}
if (!disjunctSet.isEmpty()) {
notCollocated.put(ci, disjunctSet);
}
}
};
addThreads.processPreOrderComponentInstance(root, ComponentCategory.THREAD);
// only some processors have mips
if (existsProcessorWithMIPS && existsProcessorWithoutMIPS) {
errManager.error(root, "Not all processors have MIPSCapacity");
return null;
}
// only some threads with reference processor
if (existsThreadWithReferenceProcessor && existsThreadWithoutReferenceProcessor) {
errManager.error(root, "Not all threads have execution time reference processor");
return null;
}
// threads and processors mips spec not consistent
if (existsProcessorWithMIPS && existsThreadWithoutReferenceProcessor) {
errManager.error(root, "There are some processors with MIPSCapacity but some threads without execution time reference processors");
return null;
}
if (existsProcessorWithoutMIPS && existsThreadWithReferenceProcessor) {
errManager.error(root, "There are some threads with execution time reference processors but not all processors have MIPSCapacity");
return null;
}
// Add thread connections (Messages)
for (final Iterator<ConnectionInstance> i = root.getAllConnectionInstances().iterator(); i.hasNext(); ) {
final ConnectionInstance connInst = i.next();
if (connInst.getKind() == ConnectionKind.PORT_CONNECTION) {
if (!(connInst.getSource() instanceof FeatureInstance && connInst.getDestination() instanceof FeatureInstance)) {
continue;
}
final FeatureInstance src = (FeatureInstance) connInst.getSource();
final FeatureInstance dst = (FeatureInstance) connInst.getDestination();
final ComponentInstance ci = src.getContainingComponentInstance();
AADLThread t1 = threadToSoftwareNode.get(ci);
AADLThread t2 = threadToSoftwareNode.get(dst.getContainingComponentInstance());
if (t1 != null && t2 != null) {
Feature srcAP = src.getFeature();
// TODO: get the property directly
Classifier cl = srcAP.getClassifier();
if (cl instanceof DataClassifier) {
DataClassifier srcDC = (DataClassifier) cl;
double dataSize = 0.0;
double threadPeriod = 0.0;
try {
dataSize = AadlContribUtils.getDataSize(srcDC, SizeUnits.BYTES);
} catch (Exception e) {
errManager.warning(connInst, "No Data Size for connection");
}
try {
threadPeriod = GetProperties.getPeriodinNS(ci);
} catch (Exception e) {
errManager.warning(connInst, "No Period for connection");
}
// Now I can create the Message
Message msg = new Message((long) dataSize, (long) threadPeriod, (long) threadPeriod, t1, t2);
System.out.println(">>>>>>>>>> Adding message (" + Long.toString((long) dataSize) + "/" + Long.toString((long) threadPeriod) + ") between " + t1.getName() + " and " + t2.getName() + " based on connection " + connInst.getName());
problem.addMessage(msg);
} else {
errManager.warning(connInst, "No Data Classifier for connection");
}
}
}
}
// Add collocation constraints
for (final Iterator<ComponentInstance> constrained = notCollocated.keySet().iterator(); constrained.hasNext(); ) {
final ComponentInstance ci = constrained.next();
final SoftwareNode sn = threadToSoftwareNode.get(ci);
final Set<ComponentInstance> disjunctFrom = notCollocated.get(ci);
for (final Iterator<ComponentInstance> dfIter = disjunctFrom.iterator(); dfIter.hasNext(); ) {
/*
* Items in the disjunctFrom set do not have to be thread
* instances because of the way we add items to it (see above).
* We are only interested in the thread instances here, in
* particular because we only create SoftwareNodes for the
* thread instances, and we don't want to get null return
* values from the threadToSoftwareNode map.
*/
final ComponentInstance ci2 = dfIter.next();
if (ci2.getCategory() == ComponentCategory.THREAD) {
final SoftwareNode sn2 = threadToSoftwareNode.get(ci2);
final SoftwareNode[] disjunction = new SoftwareNode[] { sn, sn2 };
problem.addConstraint(new Disjoint(disjunction));
}
}
}
/*
* Add Allowed_Processor_Binding and
* Allowed_Processor_Binding_Class constraints
*/
for (final Iterator<ComponentInstance> i = threads.iterator(); i.hasNext(); ) {
final ComponentInstance thr = i.next();
final SoftwareNode thrSN = threadToSoftwareNode.get(thr);
Collection<ComponentInstance> allowed = getActualProcessorBindings(thr);
if (allowed.size() == 0) {
allowed = getAllowedProcessorBindings(thr);
}
if (allowed.size() > 0) {
final Object[] allowedProcs = new Object[allowed.size()];
int idx = 0;
for (Iterator<ComponentInstance> j = allowed.iterator(); j.hasNext(); idx++) {
final ComponentInstance proc = j.next();
allowedProcs[idx] = procToHardware.get(proc);
}
problem.addConstraint(new SetConstraint(new SoftwareNode[] { thrSN }, allowedProcs));
}
}
// Try to bin pack
final NFCHoBinPacker highPacker = new NFCHoBinPacker(packer);
final boolean res = highPacker.solve(problem);
return new AssignmentResult(problem, res);
}
use of org.osate.aadl2.instance.ModeInstance in project osate2 by osate.
the class SystemOperationModeItemProvider method getChildren.
/**
* Manually added to show the individual modes of a SystemOperationMode.
*/
public Collection<?> getChildren(Object object) {
SystemOperationMode som = (SystemOperationMode) object;
List<SubModeItemProvider> result = new ArrayList<SubModeItemProvider>();
for (ModeInstance subMode : som.getCurrentModes()) {
result.add(new SubModeItemProvider(adapterFactory, som, subMode));
}
return result;
}
use of org.osate.aadl2.instance.ModeInstance in project osate2 by osate.
the class InstantiateModel method createSystemOperationModes.
// --------------------------------------------------------------------------------------------
// Methods related to system operation modes
// --------------------------------------------------------------------------------------------
/*
* Create the system operation mode objects for the instance model.
*/
protected void createSystemOperationModes(final SystemInstance root, final int limit) throws InterruptedException {
class SOMBuilder {
class Node {
ComponentInstance ci;
Node parentNode;
State state;
Node(ComponentInstance ci, Node parentNode) {
this.ci = ci;
this.parentNode = parentNode;
}
}
class State {
boolean active;
// mode is ignored if !active
ModeInstance mode;
State(boolean active) {
this.active = active;
}
}
ArrayList<Node> workState = new ArrayList<>();
int modalCount;
int createSoms() throws InterruptedException {
Node rootNode = new Node(null, null);
rootNode.state = new State(true);
initWorkState(root, rootNode);
modalCount = workState.size();
if (modalCount == 0) {
/*
* We have no modal components, but we need to create a special SOM to
* represent our single normal operating state.
*/
final SystemOperationMode som = InstanceFactory.eINSTANCE.createSystemOperationMode();
som.setName(NORMAL_SOM_NAME);
root.getSystemOperationModes().add(som);
return 0;
} else {
return enumerateSoms(0, 0);
}
}
protected int enumerateSoms(int depth, int index) throws InterruptedException {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
Node node = workState.get(depth);
State parentState = node.parentNode.state;
Iterator<ModeInstance> modes = parentState.active ? getActiveModes(node.ci, parentState.mode) : Collections.emptyIterator();
boolean active = parentState.active && modes.hasNext();
State state = new State(active);
node.state = state;
if (depth + 1 == modalCount) {
// here we add one or more SOMs
if (active) {
while (modes.hasNext()) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
state.mode = modes.next();
root.getSystemOperationModes().add(createSOM(index + 1));
if (index < 0 || ++index >= limit) {
return -1;
}
}
} else {
root.getSystemOperationModes().add(createSOM(index + 1));
if (index < 0 || ++index >= limit) {
return -1;
}
}
} else {
if (active) {
while (modes.hasNext()) {
state.mode = modes.next();
index = enumerateSoms(depth + 1, index);
if (index < 0) {
return -1;
}
}
} else {
index = enumerateSoms(depth + 1, index);
}
}
node.state = null;
return index;
}
protected Iterator<ModeInstance> getActiveModes(ComponentInstance ci, ModeInstance parentMode) {
List<ModeInstance> modes = ci.getModeInstances();
if (parentMode == null) {
// system instance
return modes.iterator();
} else if (!ci.getInModes().isEmpty() && !ci.getInModes().contains(parentMode)) {
// component not active in parent mode
return Collections.emptyIterator();
} else {
// limit derived modes to mapping
return modes.stream().filter(mi -> {
return !mi.isDerived() || mi.getParents().contains(parentMode);
}).iterator();
}
}
protected void initWorkState(ComponentInstance ci, Node parentNode) throws InterruptedException {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
if (!ci.getModeInstances().isEmpty()) {
parentNode = new Node(ci, parentNode);
workState.add(parentNode);
}
for (ComponentInstance sub : ci.getComponentInstances()) {
initWorkState(sub, parentNode);
}
}
protected SystemOperationMode createSOM(int somNo) throws InterruptedException {
final SystemOperationMode som;
som = InstanceFactory.eINSTANCE.createSystemOperationMode();
for (Node node : workState) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
if (!node.state.active) {
continue;
}
ModeInstance mi = node.state.mode;
List<SystemOperationMode> soms = mode2som.get(mi);
if (soms == null) {
soms = new ArrayList<SystemOperationMode>();
mode2som.put(mi, soms);
}
soms.add(som);
som.getCurrentModes().add(mi);
}
som.setName("som_" + somNo);
return som;
}
}
int index = new SOMBuilder().createSoms();
if (index < 0) {
errManager.warning(root, "List of system operation modes is incomplete (see project property 'Instantiation')");
}
}
use of org.osate.aadl2.instance.ModeInstance in project osate2 by osate.
the class InstantiateModel method instantiateFlowSpecs.
/**
* same method but with different name exists in createEndToEndFlowSwitch.
* It adds the flow instances on demand when ETEF is created
* @param ci
*/
private void instantiateFlowSpecs(ComponentInstance ci) throws InterruptedException {
for (FlowSpecification spec : getComponentType(ci).getAllFlowSpecifications()) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
FlowSpecificationInstance speci = ci.createFlowSpecification();
speci.setName(spec.getName());
speci.setFlowSpecification(spec);
FlowEnd inend = spec.getAllInEnd();
if (inend != null) {
Feature srcfp = inend.getFeature();
Context srcpg = inend.getContext();
if (srcpg == null) {
FeatureInstance fi = ci.findFeatureInstance(srcfp);
if (fi != null) {
speci.setSource(fi);
}
} else if (srcpg instanceof FeatureGroup) {
FeatureInstance pgi = ci.findFeatureInstance((FeatureGroup) srcpg);
if (pgi != null) {
FeatureInstance fi = pgi.findFeatureInstance(srcfp);
if (fi != null) {
speci.setSource(fi);
}
}
}
}
FlowEnd outend = spec.getAllOutEnd();
if (outend != null) {
Feature dstfp = outend.getFeature();
Context dstpg = outend.getContext();
if (dstpg == null) {
FeatureInstance fi = ci.findFeatureInstance(dstfp);
if (fi != null) {
speci.setDestination(fi);
}
} else if (dstpg instanceof FeatureGroup) {
FeatureInstance pgi = ci.findFeatureInstance((FeatureGroup) dstpg);
if (pgi != null) {
FeatureInstance fi = pgi.findFeatureInstance(dstfp);
if (fi != null) {
speci.setDestination(fi);
}
}
}
}
for (Mode mode : spec.getAllInModes()) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
ModeInstance mi = ci.findModeInstance(mode);
if (mi != null) {
speci.getInModes().add(mi);
}
}
for (ModeTransition mt : spec.getInModeTransitions()) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
ModeTransitionInstance ti = ci.findModeTransitionInstance(mt);
if (ti != null) {
speci.getInModeTransitions().add(ti);
}
}
}
}
use of org.osate.aadl2.instance.ModeInstance in project osate2 by osate.
the class InstantiateModel method fillModes.
private void fillModes(ComponentInstance ci, List<Mode> modes) throws InterruptedException {
for (Mode m : modes) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
ModeInstance mi = InstanceFactory.eINSTANCE.createModeInstance();
/*
* Used to add the mode instance to the component instance at the end of the loop,
* but moved it here so that we can report errors on it.
*/
ci.getModeInstances().add(mi);
mi.setMode(m);
mi.setName(m.getName());
mi.setInitial(m.isInitial());
/*
* If ci is the root object, ignore derived. This means that we are instantiating an implementation that
* contains derived modes. In this case, treat the derived modes as normal modes since there is no
* containing component to provide a parent mode.
*/
if (m.isDerived() && !(ci instanceof SystemInstance)) {
mi.setDerived(true);
Subcomponent sub = ci.getSubcomponent();
ComponentInstance parentci = ci.getContainingComponentInstance();
final EList<ModeBinding> ownedModeBindings = sub.getOwnedModeBindings();
if (ownedModeBindings == null || ownedModeBindings.isEmpty()) {
// Implicit mode map, must find modes of the same name in the containing component
ModeInstance foundParentMode = null;
for (ModeInstance pmi : parentci.getModeInstances()) {
if (pmi.getName().equalsIgnoreCase(m.getName())) {
foundParentMode = pmi;
break;
}
}
if (foundParentMode == null) {
errManager.error(mi, "Required mode '" + m.getName() + "' not found in containing component");
} else {
mi.getParents().add(foundParentMode);
}
} else {
for (ModeBinding mb : ownedModeBindings) {
if (monitor.isCanceled()) {
throw new InterruptedException();
}
if (mb.getDerivedMode() == m || mb.getDerivedMode() == null && mb.getParentMode().getName().equalsIgnoreCase(m.getName())) {
mi.getParents().add(parentci.findModeInstance(mb.getParentMode()));
}
}
}
}
}
}
Aggregations