Search in sources :

Example 1 with AssignmentResult

use of EAnalysis.BinPacking.AssignmentResult 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);
}
Also used : HashMap(java.util.HashMap) SiteArchitecture(EAnalysis.BinPacking.SiteArchitecture) Feature(org.osate.aadl2.Feature) SetConstraint(EAnalysis.BinPacking.SetConstraint) ComponentInstance(org.osate.aadl2.instance.ComponentInstance) NFCHoBinPacker(EAnalysis.BinPacking.NFCHoBinPacker) HashSet(java.util.HashSet) ListValue(org.osate.aadl2.ListValue) AssignmentResult(EAnalysis.BinPacking.AssignmentResult) InstanceObject(org.osate.aadl2.instance.InstanceObject) Site(EAnalysis.BinPacking.Site) ConnectionInstance(org.osate.aadl2.instance.ConnectionInstance) ModeInstance(org.osate.aadl2.instance.ModeInstance) CapacityComparator(EAnalysis.BinPacking.CapacityComparator) Set(java.util.Set) HashSet(java.util.HashSet) Message(EAnalysis.BinPacking.Message) FeatureInstance(org.osate.aadl2.instance.FeatureInstance) SoftwareNode(EAnalysis.BinPacking.SoftwareNode) Element(org.osate.aadl2.Element) ForAllElement(org.osate.aadl2.modelsupport.modeltraversal.ForAllElement) NamedElement(org.osate.aadl2.NamedElement) Classifier(org.osate.aadl2.Classifier) SystemClassifier(org.osate.aadl2.SystemClassifier) ComponentClassifier(org.osate.aadl2.ComponentClassifier) DataClassifier(org.osate.aadl2.DataClassifier) ProcessorClassifier(org.osate.aadl2.ProcessorClassifier) DataClassifier(org.osate.aadl2.DataClassifier) InstanceObject(org.osate.aadl2.instance.InstanceObject) Disjoint(EAnalysis.BinPacking.Disjoint) PropertyExpression(org.osate.aadl2.PropertyExpression) RecordValue(org.osate.aadl2.RecordValue) InvalidModelException(org.osate.aadl2.properties.InvalidModelException) PropertyNotPresentException(org.osate.aadl2.properties.PropertyNotPresentException) Disjoint(EAnalysis.BinPacking.Disjoint) SetConstraint(EAnalysis.BinPacking.SetConstraint) OutDegreeAssignmentProblem(EAnalysis.BinPacking.OutDegreeAssignmentProblem) ForAllElement(org.osate.aadl2.modelsupport.modeltraversal.ForAllElement) BandwidthComparator(EAnalysis.BinPacking.BandwidthComparator) OutDegreeComparator(EAnalysis.BinPacking.OutDegreeComparator) InstanceReferenceValue(org.osate.aadl2.instance.InstanceReferenceValue)

Example 2 with AssignmentResult

use of EAnalysis.BinPacking.AssignmentResult in project osate2 by osate.

the class Binpack method analyzeInstanceModel.

@Override
protected void analyzeInstanceModel(final IProgressMonitor monitor, final AnalysisErrorReporterManager errManager, final SystemInstance root, final SystemOperationMode som) {
    try {
        monitor.beginTask("Binding threads to processors in " + root.getName(), IProgressMonitor.UNKNOWN);
        logInfo("Binpacker Analysis Report\n");
        /*
			 * Verify that all the busses have a transmission time
			 */
        final ForAllElement addBuses = new ForAllElement(errManager) {

            @Override
            public void process(Element obj) {
                checkBuses((ComponentInstance) obj);
            }
        };
        addBuses.processPreOrderComponentInstance(root, ComponentCategory.BUS);
        /*
			 * Find and report all thread and device instances that don't have a
			 * period specified.
			 */
        EList<Element> incompletethreads = new ForAllElement() {

            @Override
            protected boolean suchThat(Element obj) {
                final ComponentCategory cat = ((ComponentInstance) obj).getCategory();
                if (cat == ComponentCategory.THREAD || cat == ComponentCategory.DEVICE) {
                    return org.osate.pluginsupport.properties.PropertyUtils.getScaled(TimingProperties::getPeriod, (ComponentInstance) obj, TimeUnits.MS).orElse(0.0) == 0.0;
                } else {
                    return false;
                }
            }
        }.processPreOrderComponentInstance(root);
        for (final Iterator<Element> i = incompletethreads.iterator(); i.hasNext(); ) {
            final ComponentInstance o = (ComponentInstance) i.next();
            logWarning((InstanceModelUtil.isThread(o) ? "Thread " : "Device ") + o.getComponentInstancePath() + " is missing period property. Using default of 1 ns");
        }
        /*
			 * Find and report all thread instances that don't have a
			 * compute execution time specified.
			 */
        incompletethreads = new ForAllElement() {

            @Override
            protected boolean suchThat(Element obj) {
                return GetProperties.getThreadExecutioninMilliSec((ComponentInstance) obj) == 0.0;
            }
        }.processPreOrderComponentInstance(root, ComponentCategory.THREAD);
        for (final Iterator<Element> i = incompletethreads.iterator(); i.hasNext(); ) {
            final ComponentInstance o = (ComponentInstance) i.next();
            logWarning("Thread " + o.getComponentInstancePath() + " is missing compute_execution_time or InstructionsPerDispatch property. Using default of 0 ns");
        }
        /*
			 * Find if all the port connections have data size
			 */
        final ForAllElement addThreadConnections = new ForAllElement(errManager) {

            @Override
            public void process(Element obj) {
                if (obj instanceof ConnectionInstance) {
                    final ConnectionInstance connInst = (ConnectionInstance) obj;
                    if (connInst.getKind() == ConnectionKind.PORT_CONNECTION) {
                        final FeatureInstance src = (FeatureInstance) connInst.getSource();
                        Feature srcAP = src.getFeature();
                        Classifier cl = srcAP.getClassifier();
                        if (cl instanceof DataClassifier) {
                            DataClassifier srcDC = (DataClassifier) cl;
                            if (AadlContribUtils.getDataSize(srcDC, SizeUnits.BYTES) == 0) {
                                logWarning("Data size of connection source port " + src.getComponentInstancePath() + " not specified");
                            }
                        }
                    }
                }
            }
        };
        addThreadConnections.processPreOrderAll(root);
        /* The partitionChoice is set in initializeANalysis() */
        NoExpansionExpansor expansor = new NoExpansionExpansor();
        LowLevelBinPacker packer = null;
        if (partitionChoice == IMMEDIATE_PARTITION) {
            packer = new BFCPBinPacker(expansor);
        } else if (partitionChoice == DEFER_EXEC_TIME) {
            packer = new DFCPBinPacker(expansor);
        } else if (partitionChoice == DEFER_BANDWIDTH) {
            packer = new DFBPBinPacker(expansor);
        }
        AssignmentResult result = binPackSystem(root, expansor, packer, errManager, som);
        reportResults(som, result);
        if (result.isSuccess()) {
            showResults(som, root, result);
        } else {
            showNoResults(som);
        }
    } catch (InvalidModelException e) {
        error(e.getElement(), e.getMessage());
    }
}
Also used : ConnectionInstance(org.osate.aadl2.instance.ConnectionInstance) NoExpansionExpansor(EAnalysis.BinPacking.NoExpansionExpansor) BFCPBinPacker(EAnalysis.BinPacking.BFCPBinPacker) FeatureInstance(org.osate.aadl2.instance.FeatureInstance) Element(org.osate.aadl2.Element) ForAllElement(org.osate.aadl2.modelsupport.modeltraversal.ForAllElement) NamedElement(org.osate.aadl2.NamedElement) AssignmentResult(EAnalysis.BinPacking.AssignmentResult) Classifier(org.osate.aadl2.Classifier) SystemClassifier(org.osate.aadl2.SystemClassifier) ComponentClassifier(org.osate.aadl2.ComponentClassifier) DataClassifier(org.osate.aadl2.DataClassifier) ProcessorClassifier(org.osate.aadl2.ProcessorClassifier) DataClassifier(org.osate.aadl2.DataClassifier) ComponentCategory(org.osate.aadl2.ComponentCategory) Feature(org.osate.aadl2.Feature) InvalidModelException(org.osate.aadl2.properties.InvalidModelException) ForAllElement(org.osate.aadl2.modelsupport.modeltraversal.ForAllElement) ComponentInstance(org.osate.aadl2.instance.ComponentInstance) LowLevelBinPacker(EAnalysis.BinPacking.LowLevelBinPacker) DFCPBinPacker(EAnalysis.BinPacking.DFCPBinPacker) DFBPBinPacker(EAnalysis.BinPacking.DFBPBinPacker)

Aggregations

AssignmentResult (EAnalysis.BinPacking.AssignmentResult)2 Classifier (org.osate.aadl2.Classifier)2 ComponentClassifier (org.osate.aadl2.ComponentClassifier)2 DataClassifier (org.osate.aadl2.DataClassifier)2 Element (org.osate.aadl2.Element)2 Feature (org.osate.aadl2.Feature)2 NamedElement (org.osate.aadl2.NamedElement)2 ProcessorClassifier (org.osate.aadl2.ProcessorClassifier)2 SystemClassifier (org.osate.aadl2.SystemClassifier)2 ComponentInstance (org.osate.aadl2.instance.ComponentInstance)2 ConnectionInstance (org.osate.aadl2.instance.ConnectionInstance)2 FeatureInstance (org.osate.aadl2.instance.FeatureInstance)2 ForAllElement (org.osate.aadl2.modelsupport.modeltraversal.ForAllElement)2 InvalidModelException (org.osate.aadl2.properties.InvalidModelException)2 BFCPBinPacker (EAnalysis.BinPacking.BFCPBinPacker)1 BandwidthComparator (EAnalysis.BinPacking.BandwidthComparator)1 CapacityComparator (EAnalysis.BinPacking.CapacityComparator)1 DFBPBinPacker (EAnalysis.BinPacking.DFBPBinPacker)1 DFCPBinPacker (EAnalysis.BinPacking.DFCPBinPacker)1 Disjoint (EAnalysis.BinPacking.Disjoint)1