use of org.osate.aadl2.instance.SystemInstance in project osate2 by osate.
the class FlowLatencyAnalysisSwitch method invokeOnSOM.
/**
* Invoke the analysis on all ETEF in system instance and return Result collection
*
* @param ci The component instance that owns the end to end flow instances
* @param som The mode to run the analysis in.
* @param asynchronousSystem Whether the system is treated as asynchronous
* @param majorFrameDelay Whether partition output is performed at a major frame (as opposed to the partition end)
* @param worstCaseDeadline Use deadline based processing (as opposed to max compute execution time)
* @param bestCaseEmptyQueue Assume empty queue (instead of full)
* @return A populated report in AnalysisResult format.
*
* @since org.osate.analysis.flows 3.0
*/
// NB. Called by CheckFlowLatency
public void invokeOnSOM(SystemInstance si, SystemOperationMode som, boolean asynchronousSystem, boolean majorFrameDelay, boolean worstCaseDeadline, boolean bestCaseEmptyQueue, boolean disableQueuingLatency) {
List<EndToEndFlowInstance> alletef = EcoreUtil2.getAllContentsOfType(si, EndToEndFlowInstance.class);
for (EndToEndFlowInstance etef : alletef) {
invokeOnSOM(etef, som, asynchronousSystem, majorFrameDelay, worstCaseDeadline, bestCaseEmptyQueue, disableQueuingLatency);
}
// Issue 1148
fillInQueuingTimes(si);
}
use of org.osate.aadl2.instance.SystemInstance in project osate2 by osate.
the class FlowLatencyAnalysisSwitch method invoke.
/**
* Invoke the analysis on all ETEF owned by the given component instance and return Result collection
*
* @param ci The component instance that owns the end to end flow instances
* @param som The mode to run the analysis in. If null then run all SOMs
* @param asynchronousSystem Whether the system is treated as asynchronous
* @param majorFrameDelay Whether partition output is performed at a major frame (as opposed to the partition end)
* @param worstCaseDeadline Use deadline based processing (as opposed to max compute execution time)
* @param bestCaseEmptyQueue Assume empty queue (instead of full)
* @param disableQueuingLatency <code>true</code> if queuing latency should always be reported as zero
* @return A populated report in AnalysisResult format.
*
* @since org.osate.analysis.flows 3.0
*/
public AnalysisResult invoke(ComponentInstance ci, SystemOperationMode som, boolean asynchronousSystem, boolean majorFrameDelay, boolean worstCaseDeadline, boolean bestCaseEmptyQueue, boolean disableQueuingLatency) {
SystemInstance root = ci.getSystemInstance();
if (som == null) {
if (root.getSystemOperationModes().isEmpty() || root.getSystemOperationModes().get(0).getCurrentModes().isEmpty()) {
// no SOM
invokeOnSOM(ci, root.getSystemOperationModes().get(0), asynchronousSystem, majorFrameDelay, worstCaseDeadline, bestCaseEmptyQueue, disableQueuingLatency);
} else {
// we need to run it for every SOM
for (SystemOperationMode eachsom : root.getSystemOperationModes()) {
root.setCurrentSystemOperationMode(eachsom);
invokeOnSOM(ci, eachsom, asynchronousSystem, majorFrameDelay, worstCaseDeadline, bestCaseEmptyQueue, disableQueuingLatency);
root.clearCurrentSystemOperationMode();
}
}
} else {
invokeOnSOM(ci, som, asynchronousSystem, majorFrameDelay, worstCaseDeadline, bestCaseEmptyQueue, disableQueuingLatency);
}
// Issue 1148
fillInQueuingTimes(ci.getSystemInstance());
final List<Result> finalizedResults = report.finalizeAllEntries();
return FlowLatencyUtil.recordAsAnalysisResult(finalizedResults, ci, asynchronousSystem, majorFrameDelay, worstCaseDeadline, bestCaseEmptyQueue, disableQueuingLatency);
}
use of org.osate.aadl2.instance.SystemInstance in project osate2 by osate.
the class LatencyCSVReport method getReportContent.
private static StringBuffer getReportContent(AnalysisResult ar) {
StringBuffer report = new StringBuffer();
String reportheader = "Latency analysis with preference settings: " + FlowLatencyUtil.getParametersAsDescriptions(ar);
report.append(reportheader + System.lineSeparator() + System.lineSeparator());
for (Result result : ar.getResults()) {
String flowname = ((InstanceObject) result.getModelElement()).getComponentInstancePath();
SystemInstance si = ((InstanceObject) result.getModelElement()).getSystemInstance();
String systemName = si.getComponentClassifier().getName();
String inMode = ResultUtil.getString(result, 0);
String analysisheader = "\"Latency results for end-to-end flow '" + flowname + "' of system '" + systemName + "' " + inMode + "\"";
report.append(analysisheader + System.lineSeparator() + System.lineSeparator());
report.append("Result,Min Specified,Min Actual,Min Method,Max Specified,Max Actual,Max Method,Comments" + System.lineSeparator());
for (Result contributor : result.getSubResults()) {
for (Result subc : contributor.getSubResults()) {
addContributor(report, subc, true);
}
addContributor(report, contributor, false);
}
report.append("Latency Total," + ResultUtil.getReal(result, 3) + "ms," + ResultUtil.getReal(result, 1) + "ms,," + ResultUtil.getReal(result, 4) + "ms," + ResultUtil.getReal(result, 2) + "ms" + System.lineSeparator());
report.append("Specified End To End Latency,," + ResultUtil.getReal(result, 5) + "ms,,," + ResultUtil.getReal(result, 6) + "ms" + System.lineSeparator());
report.append("End to end Latency Summary" + System.lineSeparator());
for (Diagnostic dia : result.getDiagnostics()) {
report.append(dia.getDiagnosticType() + "," + dia.getMessage() + System.lineSeparator());
}
report.append(System.lineSeparator() + System.lineSeparator() + System.lineSeparator());
}
return report;
}
use of org.osate.aadl2.instance.SystemInstance in project osate2 by osate.
the class LatencyReportEntry method export.
public Section export() {
Section section;
Line line;
String sectionName;
issues = new ArrayList<Diagnostic>();
String systemName;
if (relatedEndToEndFlow != null) {
sectionName = relatedEndToEndFlow.getComponentInstancePath();
SystemInstance si = (SystemInstance) relatedEndToEndFlow.getElementRoot();
systemName = si.getComponentClassifier().getName();
} else {
sectionName = "Unnamed flow";
systemName = "Unnamed system";
}
String inMode = Aadl2Util.isPrintableSOMName(som) ? " in mode " + som.getName() : "";
String SOMMembers = Aadl2Util.getPrintableSOMMembers(som);
section = new Section(sectionName + inMode);
line = new Line();
line.addHeaderContent("Latency results for end-to-end flow '" + sectionName + "' of system '" + systemName + "'" + inMode + SOMMembers);
section.addLine(line);
line = new Line();
section.addLine(line);
line = new Line();
line.addHeaderContent("Result");
line.addHeaderContent("Min Specified");
line.addHeaderContent("Min Actual");
line.addHeaderContent("Min Method");
line.addHeaderContent("Max Specified");
line.addHeaderContent("Max Actual");
line.addHeaderContent("Max Method");
line.addHeaderContent("Comments");
section.addLine(line);
// reporting each entry
for (LatencyContributor lc : this.contributors) {
for (Line l : lc.export()) {
section.addLine(l);
}
}
line = new Line();
line.addContent("Latency Total");
line.addContent(minSpecifiedValue + "ms");
line.addContent(minValue + "ms");
line.addContent("");
line.addContent(maxSpecifiedValue + "ms");
line.addContent(maxValue + "ms");
line.addContent("");
section.addLine(line);
line = new Line();
line.setSeverity(ReportSeverity.SUCCESS);
line.addContent("Specified End To End Latency");
line.addContent("");
line.addContent(expectedMinLatency + "ms");
line.addContent("");
line.addContent("");
line.addContent(expectedMaxLatency + "ms");
line.addContent("");
/*
* In that case, the end to end flow has a minimum latency
*/
if (expectedMaxLatency > 0) {
if (minSpecifiedValue > expectedMaxLatency) {
reportSummaryError("Minimum specified flow latency total " + BestDecPoint(minSpecifiedValue) + "ms exceeds expected maximum latency " + BestDecPoint(expectedMaxLatency) + "ms");
} else if (minSpecifiedValue < expectedMinLatency) {
reportSummaryWarning("Minimum specified flow latency total " + BestDecPoint(minSpecifiedValue) + "ms less than expected minimum end to end latency " + BestDecPoint(expectedMinLatency) + "ms (better response time)");
}
if (minValue > expectedMaxLatency) {
reportSummaryError("Minimum actual latency total " + BestDecPoint(minValue) + "ms exceeds expected maximum end to end latency " + BestDecPoint(expectedMaxLatency) + "ms");
} else if (minValue < expectedMinLatency) {
reportSummaryWarning("Minimum actual latency total " + BestDecPoint(minValue) + "ms less than expected minimum end to end latency " + BestDecPoint(expectedMinLatency) + "ms (faster actual minimum response time)");
} else {
reportSummaryInfo("Minimum actual latency total " + BestDecPoint(minValue) + "ms is greater or equal to expected minimum end to end latency " + BestDecPoint(expectedMinLatency) + "ms");
}
if (maxValue > 0) {
if (expectedMaxLatency < maxSpecifiedValue) {
reportSummaryError("Maximum specified flow latency total " + BestDecPoint(maxSpecifiedValue) + "ms exceeds expected maximum end to end latency " + BestDecPoint(expectedMaxLatency) + "ms");
}
if (expectedMaxLatency < maxValue) {
reportSummaryError("Maximum actual latency total " + BestDecPoint(maxValue) + "ms exceeds expected maximum end to end latency " + BestDecPoint(expectedMaxLatency) + "ms");
} else {
reportSummaryInfo("Maximum actual latency total " + BestDecPoint(maxValue) + "ms is less or equal to expected maximum end to end latency " + BestDecPoint(expectedMaxLatency) + "ms");
}
// do jitter analysis
if (maxSpecifiedValue - minSpecifiedValue > expectedMaxLatency - expectedMinLatency) {
reportSummaryWarning("Jitter of specified latency total " + BestDecPoint(minSpecifiedValue) + ".." + BestDecPoint(maxSpecifiedValue) + "ms exceeds expected end to end latency jitter " + BestDecPoint(expectedMinLatency) + ".." + BestDecPoint(expectedMaxLatency) + "ms");
}
if (maxValue - minValue > expectedMaxLatency - expectedMinLatency) {
reportSummaryWarning("Jitter of actual latency total " + BestDecPoint(minValue) + ".." + BestDecPoint(maxValue) + "ms exceeds expected end to end latency jitter " + BestDecPoint(expectedMinLatency) + ".." + BestDecPoint(expectedMaxLatency) + "ms");
}
if ((minValue > expectedMinLatency) && (expectedMaxLatency > maxValue)) {
reportSummaryInfo("Jitter of actual flow latency " + BestDecPoint(minValue) + ".." + BestDecPoint(maxValue) + "ms is within expected end to end latency jitter " + BestDecPoint(expectedMinLatency) + ".." + BestDecPoint(expectedMaxLatency) + "ms");
}
}
} else {
reportSummaryWarning("Expected end to end latency is not specified");
}
section.addLine(line);
if (issues.size() > 0) {
line = new Line();
line.addHeaderContent("End to end Latency Summary");
section.addLine(line);
for (Diagnostic issue : issues) {
line = new Line();
String msg = issue.getMessage();
ReportedCell issueLabel = new ReportedCell(issue.getDiagnosticType(), issue.getDiagnosticType().toString());
line.addCell(issueLabel);
line.addContent(msg);
section.addLine(line);
}
}
return section;
}
use of org.osate.aadl2.instance.SystemInstance 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);
}
Aggregations