/** Parse a DAX file with jdom */ private void parseXmlFile(String path) { try { SAXBuilder builder = new SAXBuilder(); // parse using builder to get DOM representation of the XML file Document dom = builder.build(new File(path)); Element root = dom.getRootElement(); List list = root.getChildren(); for (Iterator it = list.iterator(); it.hasNext(); ) { Element node = (Element) it.next(); if (node.getName().toLowerCase().equals("job")) { long length = 0; String nodeName = node.getAttributeValue("id"); String nodeType = node.getAttributeValue("name"); /** * capture runtime. If not exist, by default the runtime is 0.1. Otherwise CloudSim would * ignore this task. BUG/#11 */ double runtime = 0.1; if (node.getAttributeValue("runtime") != null) { String nodeTime = node.getAttributeValue("runtime"); runtime = 1000 * Double.parseDouble(nodeTime); if (runtime < 100) { runtime = 100; } length = (long) runtime; } else { Log.printLine("Cannot find runtime for " + nodeName + ",set it to be 0"); } // multiple the scale, by default it is 1.0 length *= Parameters.getRuntimeScale(); List fileList = node.getChildren(); List mFileList = new ArrayList<org.cloudbus.cloudsim.File>(); for (Iterator itf = fileList.iterator(); itf.hasNext(); ) { Element file = (Element) itf.next(); if (file.getName().toLowerCase().equals("uses")) { String fileName = file.getAttributeValue("name"); // DAX version 3.3 if (fileName == null) { fileName = file.getAttributeValue("file"); // DAX version 3.0 } if (fileName == null) { Log.print("Error in parsing xml"); } String inout = file.getAttributeValue("link"); double size = 0.0; String fileSize = file.getAttributeValue("size"); if (fileSize != null) { size = Double.parseDouble(fileSize) /*/ 1024*/; } else { Log.printLine("File Size not found for " + fileName); } /** a bug of cloudsim, size 0 causes a problem. 1 is ok. */ if (size == 0) { size++; } /** Sets the file type 1 is input 2 is output */ int type = 0; if (inout.equals("input")) { type = Parameters.FileType.INPUT.value; } else if (inout.equals("output")) { type = Parameters.FileType.OUTPUT.value; } else { Log.printLine("Parsing Error"); } org.cloudbus.cloudsim.File tFile; /* * Already exists an input file (forget output file) */ if (size < 0) { /* * Assuming it is a parsing error */ size = 0 - size; Log.printLine("Size is negative, I assume it is a parser error"); } if (type == Parameters.FileType.OUTPUT.value) { /** It is good that CloudSim does tell whether a size is zero */ tFile = new org.cloudbus.cloudsim.File(fileName, (int) size); } else if (ReplicaCatalog.containsFile(fileName)) { tFile = ReplicaCatalog.getFile(fileName); } else { tFile = new org.cloudbus.cloudsim.File(fileName, (int) size); ReplicaCatalog.setFile(fileName, tFile); } tFile.setType(type); mFileList.add(tFile); } } Task task; // In case of multiple workflow submission. Make sure the jobIdStartsFrom is consistent. synchronized (this) { task = new Task(this.jobIdStartsFrom, length); this.jobIdStartsFrom++; } task.setType(nodeType); task.setUserId(userId); mName2Task.put(nodeName, task); for (Iterator itm = mFileList.iterator(); itm.hasNext(); ) { org.cloudbus.cloudsim.File file = (org.cloudbus.cloudsim.File) itm.next(); task.addRequiredFile(file.getName()); } task.setFileList(mFileList); this.getTaskList().add(task); /** Add dependencies info. */ } else if (node.getName().toLowerCase().equals("child")) { List pList = node.getChildren(); String childName = node.getAttributeValue("ref"); if (mName2Task.containsKey(childName)) { Task childTask = (Task) mName2Task.get(childName); for (Iterator itc = pList.iterator(); itc.hasNext(); ) { Element parent = (Element) itc.next(); String parentName = parent.getAttributeValue("ref"); if (mName2Task.containsKey(parentName)) { Task parentTask = (Task) mName2Task.get(parentName); parentTask.addChild(childTask); childTask.addParent(parentTask); } } } } } /** If a task has no parent, then it is root task. */ ArrayList roots = new ArrayList<Task>(); for (Iterator it = mName2Task.values().iterator(); it.hasNext(); ) { Task task = (Task) it.next(); task.setDepth(0); if (task.getParentList().isEmpty()) { roots.add(task); } } /** Add depth from top to bottom. */ for (Iterator it = roots.iterator(); it.hasNext(); ) { Task task = (Task) it.next(); setDepth(task, 1); } /** Clean them so as to save memory. Parsing workflow may take much memory */ this.mName2Task.clear(); } catch (JDOMException jde) { Log.printLine("JDOM Exception;Please make sure your dax file is valid"); } catch (IOException ioe) { Log.printLine("IO Exception;Please make sure dax.path is correctly set in your config file"); } catch (Exception e) { e.printStackTrace(); Log.printLine("Parsing Exception"); } }
/** The main function */ @Override public void run() { double[][] bandwidths = Parameters.getBandwidths(); int vmNum = getVmList().size(); int taskNum = getTaskList().size(); double[] availableTime = new double[vmNum]; // cloudlet id starts from 1 double[][] earliestStartTime = new double[taskNum + 1][vmNum]; double[][] earliestFinishTime = new double[taskNum + 1][vmNum]; int[] allocation = new int[taskNum + 1]; List<Task> taskList = new ArrayList<Task>(getTaskList()); List<Task> readyList = new ArrayList<Task>(); while (!taskList.isEmpty()) { readyList.clear(); for (Task task : taskList) { boolean ready = true; for (Task parent : task.getParentList()) { if (taskList.contains(parent)) { ready = false; break; } } if (ready) { readyList.add(task); } } taskList.removeAll(readyList); // schedule readylist for (Task task : readyList) { long[] fileSizes = new long[task.getParentList().size()]; int parentIndex = 0; for (Task parent : task.getParentList()) { long fileSize = 0; for (Iterator fileIter = task.getFileList().iterator(); fileIter.hasNext(); ) { File file = (File) fileIter.next(); if (file.getType() == 1) { for (Iterator fileIter2 = parent.getFileList().iterator(); fileIter2.hasNext(); ) { File file2 = (File) fileIter2.next(); if (file2.getType() == 2 && file2.getName().equals(file.getName())) { fileSize += file.getSize(); } } } } fileSizes[parentIndex] = fileSize; parentIndex++; } double minTime = Double.MAX_VALUE; int minTimeIndex = 0; for (int vmIndex = 0; vmIndex < getVmList().size(); vmIndex++) { Vm vm = (Vm) getVmList().get(vmIndex); double startTime = availableTime[vm.getId()]; parentIndex = 0; for (Task parent : task.getParentList()) { int allocatedVmId = allocation[parent.getCloudletId()]; double actualFinishTime = earliestFinishTime[parent.getCloudletId()][allocatedVmId]; double communicationTime = fileSizes[parentIndex] / bandwidths[allocatedVmId][vm.getId()]; if (actualFinishTime + communicationTime > startTime) { startTime = actualFinishTime + communicationTime; } parentIndex++; } earliestStartTime[task.getCloudletId()][vm.getId()] = startTime; double runtime = task.getCloudletLength() / vm.getMips(); earliestFinishTime[task.getCloudletId()][vm.getId()] = runtime + startTime; if (runtime + startTime < minTime) { minTime = runtime + startTime; minTimeIndex = vmIndex; } } allocation[task.getCloudletId()] = minTimeIndex; // we do not really need it use task.getVmId task.setVmId(minTimeIndex); availableTime[minTimeIndex] = minTime; } } }