X-Git-Url: http://sraa.de/git/?a=blobdiff_plain;f=dol%2Fsrc%2Fdol%2Fcheck%2FSanityCheck.java;fp=dol%2Fsrc%2Fdol%2Fcheck%2FSanityCheck.java;h=88f82db1cde7d6800822ffe6ffb2bfdb616328b4;hb=8c411cf24ed0eb889191aaeafd8fa1e69081df42;hp=0000000000000000000000000000000000000000;hpb=dea7a4fb1ed110d3ce6e6d9255103d724bd66c0e;p=jump.git diff --git a/dol/src/dol/check/SanityCheck.java b/dol/src/dol/check/SanityCheck.java new file mode 100644 index 0000000..88f82db --- /dev/null +++ b/dol/src/dol/check/SanityCheck.java @@ -0,0 +1,419 @@ +/* $Id: SanityCheck.java 1 2010-02-24 13:03:05Z haidw $ */ +package dol.check; + +import java.util.Collections; +import java.util.Comparator; +import java.util.Vector; + +import dol.datamodel.architecture.ArchiResource; +import dol.datamodel.architecture.Architecture; +import dol.datamodel.architecture.Configuration; +import dol.datamodel.architecture.Processor; +import dol.datamodel.mapping.Mapping; +import dol.datamodel.pn.Channel; +import dol.datamodel.pn.Connection; +import dol.datamodel.pn.Process; +import dol.datamodel.pn.ProcessNetwork; +import dol.datamodel.pn.Resource; + +/** + * Check semantic correctness of process network. + * + * This class checks + * + */ +public class SanityCheck { + /** + * Return the singleton instance of this class; + * + * @return the instance. + */ + public final static SanityCheck getInstance() { + return _instance; + } + + /** + * Check if the process network spec is correct + * + * @param pn processnetwork to check + */ + public void checkPN(ProcessNetwork pn) { + try { + _checkNameConflict(pn); + _checkChannelPorts(pn); + _checkChannelConnection(pn); + } + catch (Exception e) { + System.out.println("err: " + e.getMessage()); + //e.printStackTrace(); + System.exit(-1); + } + + try { + _checkProcessConnection(pn); + } + catch (Exception e) { + System.out.println("warning: " + e.getMessage()); + } + } + + /** + * Check if the architecture spec is correct + * + * @param arch architecture to check + */ + public void checkArch(Architecture arch) + { + try + { + _checkNameConflict(arch); + _checkNETSIM(arch); + _checkMaster(arch); + } + catch (Exception e) + { + System.out.println("err: " + e.getMessage()); + System.exit(-1); + } + } + + /** + * Check if the mapping spec is correct + * + * @param map mapping to check + */ + public void checkMap(Mapping map) + { + try + { + _checkMultibind(map); + _checkProcessesBound(map); + } + catch (Exception e) + { + System.out.println("err: " + e.getMessage()); + System.exit(-1); + } + } + + + /** + * Check name exclusiveness, including processes, channels, and + * connections. + * + * @param pn processnetwork to check + */ + private void _checkNameConflict(ProcessNetwork pn) throws Exception { + System.out.println("APPL: Checking resource name ..."); + + Vector n = new Vector(pn.getChannelList()); + n.addAll(pn.getProcessList()); + n.addAll(pn.getConnectionList()); + + //sort resources in n by name + Collections.sort(n, + new Comparator() + { + public int compare(Resource resource1, Resource resource2) { + return resource1.getName().compareTo(resource2.getName()); + } + } ); + + //test adjacent resources in n for equal name + for (int k = 0; k < n.size() - 1; k++) + { + if (((Resource) n.elementAt(k)).getName().equals( + ((Resource) n.elementAt(k + 1)).getName())) { + throw new Exception("Name conflict: " + + ((Resource)n.elementAt(k + 1)).getName() + + " appears (at least) twice."); + } + } + } + + /** + * Check number of ports for every channel. + * + * @param pn processnetwork to check + */ + private void _checkChannelPorts(ProcessNetwork pn) throws Exception { + System.out.println("APPL: Checking channel ports ..."); + + for (Channel c : pn.getChannelList()) { + if (c.getPortList().size() < 2) { + throw new Exception("channel ports less than 2: " + + c.getName()); + } + } + } + + /** + * Check whether all processes are connected. + * + * @param pn processnetwork to check + */ + private void _checkProcessConnection(ProcessNetwork pn) + throws Exception { + System.out.println("APPL: Checking Process connection ..."); + + String result = ""; + boolean hasUnused = false; + for (Process r : pn.getProcessList()) { + boolean flag = false; + for (Connection c : pn.getConnectionList()) { + Resource origin = c.getOrigin(); + Resource target = c.getTarget(); + if (r.getName().equals(origin.getName())) { + flag = true; break; + } else if (r.getName().equals(target.getName())) { + flag = true; break; + } + } + if (flag == false) { + hasUnused = true; + result += " " + r.getName(); + } + } + + if (hasUnused == true) + throw new Exception("process(es) without connection to channels:" + result); + } + + /** + * Check whether there are unused channels in the processnetwork. + * + * @param pn processnetwork to check + */ + private void _checkChannelConnection(ProcessNetwork pn) + throws Exception { + System.out.println("APPL: Checking channel connection ..."); + + String result = ""; + boolean hasUnused = false; + for (Channel r : pn.getChannelList()) { + boolean flag = false; + for (Connection c: pn.getConnectionList()) { + Resource origin = c.getOrigin(); + Resource target = c.getTarget(); + if (r.getName().equals(origin.getName())) { + flag = true; break; + } else if (r.getName().equals(target.getName())) { + flag = true; break; + } + } + if (flag == false) { + hasUnused = true; + result += " " + r.getName(); + } + } + + if (hasUnused == true) + throw new Exception("unused channel: " + result); + } + + + /** + * Check name exclusiveness, including both processors and memories. + * + * @param arch architecture to check + */ + private void _checkNameConflict(Architecture arch) throws Exception { + System.out.println("ARCH: Checking resource name ..."); + Vector n = new Vector(arch.getProcessorList()); + n.addAll(arch.getMemoryList()); + + //sort resources in n by name + Collections.sort(n, + new Comparator() + { + public int compare(ArchiResource resource1, ArchiResource resource2) { + return resource1.getName().compareTo(resource2.getName()); + } + } ); + + //test adjacent resources in n for equal name + for (int k = 0; k < n.size() - 1; k++) + { + if (((ArchiResource) n.elementAt(k)).getName().equals( + ((ArchiResource) n.elementAt(k + 1)).getName())) { + throw new Exception("Name conflict: " + + ((ArchiResource)n.elementAt(k + 1)).getName() + + " appears (at least) twice."); + } + } + } + + /** + * every processor of type NETSIM must have a configuration tag with + * name "address" and one with name "port". these address-port pairs + * have to be unique + * @param arch + * @throws Exception + */ + private void _checkNETSIM(Architecture arch) throws Exception + { + System.out.println("ARCH: Checking network simulators ..."); + + Vector sockets = new Vector(); + + for (Processor proc : arch.getProcessorList()) { + if ( proc.getType().equals("NETSIM") ) + { + if ( proc.getCfg("address") == null + || proc.getCfg("port") == null ) + { + throw new Exception("Processor " + proc.getName() + + " is of type NETSIM but address or port is missing"); + } + if ( proc.getCfg("address").equals("") + || proc.getCfg("port").equals("") ) + { + throw new Exception("Processor " + proc.getName() + + " has empty address or port"); + } + sockets.add(proc); // add processor to socket list + } + } + + /* socket comperator */ + Comparator sockComp = new Comparator() + { + public int compare(Processor proc1, Processor proc2) + { + String ad1, ad2; + ad1 = proc1.getCfg("address").getValue(); + ad2 = proc2.getCfg("address").getValue(); + + int comp = ad1.compareToIgnoreCase(ad2); + + if (comp != 0) + { + return comp; + } + else + { + String p1, p2; + p1 = proc1.getCfg("port").getValue(); + p2 = proc2.getCfg("port").getValue(); + + return p1.compareToIgnoreCase(p2); + } + } + }; + + + /* sort sockets */ + Collections.sort(sockets, sockComp); + + /* check for uniqueness */ + Processor proc1 = null; + Processor proc2 = null; + if (!sockets.isEmpty()) + proc1 = sockets.get(0); + for (int i=1; i processes = map.getProcessList(); + + //sort processes in n by name + Collections.sort(processes, + new Comparator() + { + public int compare(Process p1, Process p2) { + return p1.getName().compareTo(p2.getName()); + } + } ); + + //test adjacent origins for equal name + String o1 = null; + String o2 = null; + if (!processes.isEmpty()) + o1 = processes.get(0).getName(); + for (int k = 1; k < processes.size(); k++) + { + o2 = processes.get(k).getName(); + if (o1.equals(o2)) + { + throw new Exception("sw resource \"" + o1 + + "\" has multiple bindings"); + } + } + } + + /** + * Checks that every process is bound to a processor. + * @param map the map to check + * @throws Exception if not all processes are bound to a processor + */ + private void _checkProcessesBound(Mapping map) throws Exception + { + System.out.println("MAP: Checking that all processes have a binding ..."); + Vector boundList = map.getProcessList(); + Vector totalList = map.getPN().getProcessList(); + + if (boundList.size() != totalList.size()) + { + throw new Exception("some processes are not bound to a processor"); + } + } + + /** + * singleton instance + */ + private final static SanityCheck _instance = new SanityCheck(); +}