1 /* $Id: SanityCheck.java 1 2010-02-24 13:03:05Z haidw $ */
4 import java.util.Collections;
5 import java.util.Comparator;
6 import java.util.Vector;
8 import dol.datamodel.architecture.ArchiResource;
9 import dol.datamodel.architecture.Architecture;
10 import dol.datamodel.architecture.Configuration;
11 import dol.datamodel.architecture.Processor;
12 import dol.datamodel.mapping.Mapping;
13 import dol.datamodel.pn.Channel;
14 import dol.datamodel.pn.Connection;
15 import dol.datamodel.pn.Process;
16 import dol.datamodel.pn.ProcessNetwork;
17 import dol.datamodel.pn.Resource;
20 * Check semantic correctness of process network.
23 * <ul><li>whether it is a processnetwork</li>
24 * <li>a channel only has two ports</li>
25 * <li>each channel port has only one peer port of process</li>
28 public class SanityCheck {
30 * Return the singleton instance of this class;
32 * @return the instance.
34 public final static SanityCheck getInstance() {
39 * Check if the process network spec is correct
41 * @param pn processnetwork to check
43 public void checkPN(ProcessNetwork pn) {
45 _checkNameConflict(pn);
46 _checkChannelPorts(pn);
47 _checkChannelConnection(pn);
50 System.out.println("err: " + e.getMessage());
51 //e.printStackTrace();
56 _checkProcessConnection(pn);
59 System.out.println("warning: " + e.getMessage());
64 * Check if the architecture spec is correct
66 * @param arch architecture to check
68 public void checkArch(Architecture arch)
72 _checkNameConflict(arch);
78 System.out.println("err: " + e.getMessage());
84 * Check if the mapping spec is correct
86 * @param map mapping to check
88 public void checkMap(Mapping map)
93 _checkProcessesBound(map);
97 System.out.println("err: " + e.getMessage());
104 * Check name exclusiveness, including processes, channels, and
107 * @param pn processnetwork to check
109 private void _checkNameConflict(ProcessNetwork pn) throws Exception {
110 System.out.println("APPL: Checking resource name ...");
112 Vector<Resource> n = new Vector<Resource>(pn.getChannelList());
113 n.addAll(pn.getProcessList());
114 n.addAll(pn.getConnectionList());
116 //sort resources in n by name
118 new Comparator<Resource>()
120 public int compare(Resource resource1, Resource resource2) {
121 return resource1.getName().compareTo(resource2.getName());
125 //test adjacent resources in n for equal name
126 for (int k = 0; k < n.size() - 1; k++)
128 if (((Resource) n.elementAt(k)).getName().equals(
129 ((Resource) n.elementAt(k + 1)).getName())) {
130 throw new Exception("Name conflict: " +
131 ((Resource)n.elementAt(k + 1)).getName() +
132 " appears (at least) twice.");
138 * Check number of ports for every channel.
140 * @param pn processnetwork to check
142 private void _checkChannelPorts(ProcessNetwork pn) throws Exception {
143 System.out.println("APPL: Checking channel ports ...");
145 for (Channel c : pn.getChannelList()) {
146 if (c.getPortList().size() < 2) {
147 throw new Exception("channel ports less than 2: " +
154 * Check whether all processes are connected.
156 * @param pn processnetwork to check
158 private void _checkProcessConnection(ProcessNetwork pn)
160 System.out.println("APPL: Checking Process connection ...");
163 boolean hasUnused = false;
164 for (Process r : pn.getProcessList()) {
165 boolean flag = false;
166 for (Connection c : pn.getConnectionList()) {
167 Resource origin = c.getOrigin();
168 Resource target = c.getTarget();
169 if (r.getName().equals(origin.getName())) {
171 } else if (r.getName().equals(target.getName())) {
177 result += " " + r.getName();
181 if (hasUnused == true)
182 throw new Exception("process(es) without connection to channels:" + result);
186 * Check whether there are unused channels in the processnetwork.
188 * @param pn processnetwork to check
190 private void _checkChannelConnection(ProcessNetwork pn)
192 System.out.println("APPL: Checking channel connection ...");
195 boolean hasUnused = false;
196 for (Channel r : pn.getChannelList()) {
197 boolean flag = false;
198 for (Connection c: pn.getConnectionList()) {
199 Resource origin = c.getOrigin();
200 Resource target = c.getTarget();
201 if (r.getName().equals(origin.getName())) {
203 } else if (r.getName().equals(target.getName())) {
209 result += " " + r.getName();
213 if (hasUnused == true)
214 throw new Exception("unused channel: " + result);
219 * Check name exclusiveness, including both processors and memories.
221 * @param arch architecture to check
223 private void _checkNameConflict(Architecture arch) throws Exception {
224 System.out.println("ARCH: Checking resource name ...");
225 Vector<ArchiResource> n = new Vector<ArchiResource>(arch.getProcessorList());
226 n.addAll(arch.getMemoryList());
228 //sort resources in n by name
230 new Comparator<ArchiResource>()
232 public int compare(ArchiResource resource1, ArchiResource resource2) {
233 return resource1.getName().compareTo(resource2.getName());
237 //test adjacent resources in n for equal name
238 for (int k = 0; k < n.size() - 1; k++)
240 if (((ArchiResource) n.elementAt(k)).getName().equals(
241 ((ArchiResource) n.elementAt(k + 1)).getName())) {
242 throw new Exception("Name conflict: " +
243 ((ArchiResource)n.elementAt(k + 1)).getName() +
244 " appears (at least) twice.");
250 * every processor of type NETSIM must have a configuration tag with
251 * name "address" and one with name "port". these address-port pairs
256 private void _checkNETSIM(Architecture arch) throws Exception
258 System.out.println("ARCH: Checking network simulators ...");
260 Vector<Processor> sockets = new Vector<Processor>();
262 for (Processor proc : arch.getProcessorList()) {
263 if ( proc.getType().equals("NETSIM") )
265 if ( proc.getCfg("address") == null
266 || proc.getCfg("port") == null )
268 throw new Exception("Processor " + proc.getName() +
269 " is of type NETSIM but address or port is missing");
271 if ( proc.getCfg("address").equals("")
272 || proc.getCfg("port").equals("") )
274 throw new Exception("Processor " + proc.getName() +
275 " has empty address or port");
277 sockets.add(proc); // add processor to socket list
281 /* socket comperator */
282 Comparator<Processor> sockComp = new Comparator<Processor>()
284 public int compare(Processor proc1, Processor proc2)
287 ad1 = proc1.getCfg("address").getValue();
288 ad2 = proc2.getCfg("address").getValue();
290 int comp = ad1.compareToIgnoreCase(ad2);
299 p1 = proc1.getCfg("port").getValue();
300 p2 = proc2.getCfg("port").getValue();
302 return p1.compareToIgnoreCase(p2);
309 Collections.sort(sockets, sockComp);
311 /* check for uniqueness */
312 Processor proc1 = null;
313 Processor proc2 = null;
314 if (!sockets.isEmpty())
315 proc1 = sockets.get(0);
316 for (int i=1; i<sockets.size(); i++)
318 proc2 = sockets.get(i);
319 if (sockComp.compare(proc1, proc2) == 0)
321 throw new Exception("multiple processors with hostname \"" +
322 proc1.getCfg("address").getValue() +
323 "\" and port " + proc1.getCfg("port").getValue() +
332 * Checks that exactly one master simulator is defined if
333 * processors of type "NETSIM" exist.
334 * @param arch the architecture to check
337 private void _checkMaster(Architecture arch) throws Exception
339 boolean hasMaster = false;
340 boolean hasHosts = false;
342 for (Processor p : arch.getProcessorList()) {
343 if (p.getType().equals("NETSIM"))
346 Configuration opt = p.getCfg("master");
347 if (opt != null && opt.getValue().equals("true"))
350 throw new Exception("multiple master simulators"
359 if (hasHosts && !hasMaster)
360 throw new Exception("no master simulator defined");
365 * Check that software resources bind only to one hardware resource.
367 * @param map mapping to check
369 private void _checkMultibind(Mapping map) throws Exception {
370 System.out.println("MAP: Checking multiple bindings ...");
371 Vector<Process> processes = map.getProcessList();
373 //sort processes in n by name
374 Collections.sort(processes,
375 new Comparator<Process>()
377 public int compare(Process p1, Process p2) {
378 return p1.getName().compareTo(p2.getName());
382 //test adjacent origins for equal name
385 if (!processes.isEmpty())
386 o1 = processes.get(0).getName();
387 for (int k = 1; k < processes.size(); k++)
389 o2 = processes.get(k).getName();
392 throw new Exception("sw resource \"" + o1 +
393 "\" has multiple bindings");
399 * Checks that every process is bound to a processor.
400 * @param map the map to check
401 * @throws Exception if not all processes are bound to a processor
403 private void _checkProcessesBound(Mapping map) throws Exception
405 System.out.println("MAP: Checking that all processes have a binding ...");
406 Vector<Process> boundList = map.getProcessList();
407 Vector<Process> totalList = map.getPN().getProcessList();
409 if (boundList.size() != totalList.size())
411 throw new Exception("some processes are not bound to a processor");
418 private final static SanityCheck _instance = new SanityCheck();