/** * Clean the checked flag of a taskset * * @return $none */ public void cleanTaskSetChecked() { Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); set.hasChecked = false; } }
/** Print out all the balancing metrics */ public void printMetrics() { Map<Integer, ArrayList<TaskSet>> map = getCurrentTaskSetAtLevels(); for (TaskSet set : mTask2TaskSet.values()) { set.setImpactFafctor(0.0); } int maxDepth = 0; for (Entry entry : map.entrySet()) { int depth = (Integer) entry.getKey(); if (depth > maxDepth) { maxDepth = depth; } } ArrayList<TaskSet> exits = map.get(maxDepth); double avg = 1.0 / exits.size(); for (TaskSet set : exits) { // set.setImpactFafctor(avg); addImpact(set, avg); } for (Entry entry : map.entrySet()) { int depth = (Integer) entry.getKey(); ArrayList<TaskSet> list = (ArrayList) entry.getValue(); /** Horizontal Runtime Variance. */ double hrv = new HorizontalRuntimeVariance().getMetric(list); /** Impact Factor Variance. */ double ifv = new ImpactFactorVariance().getMetric(list); /** Pipeline Runtime Variance. */ double prv = new PipelineRuntimeVariance().getMetric(list); /** Distance Variance. */ double dv = new DistanceVariance().getMetric(list); Log.printLine( "HRV " + depth + " " + list.size() + " " + hrv + "\nIFV " + depth + " " + list.size() + " " + ifv + "\nPRV " + depth + " " + list.size() + " " + prv + "\nDV " + depth + " " + list.size() + " " + dv); } }
/** Update task set dependencies */ private void updateTaskSetDependencies() { Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; set.getChildList().clear(); set.getParentList().clear(); for (Task task : set.getTaskList()) { for (Iterator tIt = task.getParentList().iterator(); tIt.hasNext(); ) { Task parent = (Task) tIt.next(); TaskSet parentSet = (TaskSet) mTask2TaskSet.get(parent); if (!set.getParentList().contains(parentSet) && set != parentSet) { set.getParentList().add(parentSet); } } for (Iterator tIt = task.getChildList().iterator(); tIt.hasNext(); ) { Task child = (Task) tIt.next(); TaskSet childSet = (TaskSet) mTask2TaskSet.get(child); if (!set.getChildList().contains(childSet) && set != childSet) { set.getChildList().add(childSet); } } } } } // within each method cleanTaskSetChecked(); }
/** * Add impact factor to a TaskSet * * @param set TaskSet * @param impact Impact Factor */ private void addImpact(TaskSet set, double impact) { /* * follow the path from set */ set.setImpactFafctor(set.getImpactFactor() + impact); int size = set.getParentList().size(); if (size > 0) { double avg = impact / size; for (TaskSet parent : set.getParentList()) { addImpact(parent, avg); } } }
/** * Sort taskSet based on their impact factors and then merge similar taskSet together * * @param taskList */ @Override public void process(ArrayList<TaskSet> taskList) { if (taskList.size() > getClusterNum()) { ArrayList<TaskSet> jobList = new ArrayList<TaskSet>(); for (int i = 0; i < getClusterNum(); i++) { jobList.add(new TaskSet()); } int clusters_size = taskList.size() / getClusterNum(); if (clusters_size * getClusterNum() < taskList.size()) { clusters_size++; } // sortListDecreasing(taskList); preprocessing(taskList, jobList); for (TaskSet set : taskList) { // sortListIncreasing(jobList); TaskSet job = getCandidateTastSet(jobList, set, clusters_size); addTaskSet2TaskSet(set, job); job.addTask(set.getTaskList()); job.setImpactFafctor(set.getImpactFactor()); // update dependency for (Task task : set.getTaskList()) { getTaskMap().put(task, job); // this is enough // impact factor is not updated } } taskList.clear(); // you sure? } else { // do nothing since } }
/** * Gets the potential candidate taskSets to merge * * @param taskList * @param checkSet * @return */ @Override protected TaskSet getCandidateTastSet( ArrayList<TaskSet> taskList, TaskSet checkSet, int clusters_size) { ArrayList<TaskSet> potential = getNextPotentialTaskSets(taskList, checkSet, clusters_size); TaskSet task = null; long min = Long.MAX_VALUE; for (TaskSet set : potential) { if (set.getJobRuntime() < min) { min = set.getJobRuntime(); task = set; } } if (task != null) { return task; } else { return taskList.get(0); } }
private ArrayList<TaskSet> getNextPotentialTaskSets( ArrayList<TaskSet> taskList, TaskSet checkSet, int clusters_size) { int dis = Integer.MAX_VALUE; HashMap map = new HashMap<Integer, ArrayList>(); for (TaskSet set : taskList) { int distance = calDistance(checkSet, set); if (distance < dis) { dis = distance; } if (!map.containsKey(distance)) { map.put(distance, new ArrayList<TaskSet>()); } ArrayList<TaskSet> list = (ArrayList) map.get(distance); if (!list.contains(set)) { list.add(set); } } ArrayList returnList = new ArrayList<TaskSet>(); for (TaskSet set : (ArrayList<TaskSet>) map.get(dis)) { if (set.getTaskList().size() < clusters_size) { returnList.add(set); } } if (returnList.isEmpty()) { returnList.clear(); for (TaskSet set : taskList) { if (set.getTaskList().isEmpty()) { returnList.add(set); return returnList; } } // no empty available while (returnList.isEmpty()) { map.remove(dis); ArrayList<Integer> keys = new ArrayList(map.keySet()); int min = Integer.MAX_VALUE; for (int i : keys) { if (min > i) { min = i; } } dis = min; for (TaskSet set : (ArrayList<TaskSet>) map.get(dis)) { if (set.getTaskList().size() < clusters_size) { returnList.add(set); } } } return returnList; } else { return returnList; } }
/** Print out the clustering information. */ private void printOut() { Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; Log.printLine("Job"); for (Task task : set.getTaskList()) { Log.printLine( "Task " + task.getCloudletId() + " " + task.getImpact() + " " + task.getCloudletLength()); } } } // within each method cleanTaskSetChecked(); }
/** * Gets the current tasks per level * * @return tasks list per level */ public Map<Integer, ArrayList<TaskSet>> getCurrentTaskSetAtLevels() { // makesure it is updated // makesure Taskset.hasChecked is false Map map = new HashMap<Integer, ArrayList<TaskSet>>(); Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; int depth = getDepth(set); if (!map.containsKey(depth)) { map.put(depth, new ArrayList<TaskSet>()); } ArrayList list = (ArrayList) map.get(depth); list.add(set); } } mTaskSet2Depth.clear(); // must do cleanTaskSetChecked(); return map; }
private ArrayList preprocessing(ArrayList<TaskSet> taskList, ArrayList<TaskSet> jobList) { int size = taskList.size(); int[] record = new int[size]; for (int i = 0; i < size; i++) { record[i] = -1; } int index_record = 0; int[][] distances = new int[size][size]; for (int i = 0; i < size; i++) { for (int j = 0; j < i; j++) { TaskSet setA = taskList.get(i); TaskSet setB = taskList.get(j); int distance = calDistance(setA, setB); distances[i][j] = distance; } } int job_index = 0; // boolean [] popped = new boolean[size]; ArrayList idList = sortDistanceIncreasing(distances, size, jobList.size()); for (int i = 0; i < idList.size(); i++) { int max_i = (Integer) idList.get(i); record[index_record] = max_i; index_record++; TaskSet set = taskList.get(max_i); TaskSet job = jobList.get(job_index); addTaskSet2TaskSet(set, job); job.addTask(set.getTaskList()); job.setImpactFafctor(set.getImpactFactor()); // update dependency for (Task task : set.getTaskList()) { getTaskMap().put(task, job); // this is enough // impact factor is not updated } job_index++; if (job_index == jobList.size()) { break; } } /** Actually not really necessary because record[i] is already empty */ Arrays.sort(record); for (int i = size - 1; i >= 0 && record[i] >= 0; i--) { taskList.remove(record[i]); } return taskList; }
/** * Gets the depth of a TaskSet * * @param set TaskSet * @return depth */ private int getDepth(TaskSet set) { if (mTaskSet2Depth.containsKey(set)) { return (Integer) mTaskSet2Depth.get(set); } else { int depth = 0; for (Iterator it = set.getParentList().iterator(); it.hasNext(); ) { TaskSet parent = (TaskSet) it.next(); int curDepth = getDepth(parent); if (curDepth > depth) { depth = curDepth; } } depth++; mTaskSet2Depth.put(set, depth); return depth; } }
/** * Calculate the distance between two taskSet one assumption here taskA and taskB are at the same * level because it is horizontal clustering does not work with arbitary workflows * * @param taskA * @param taskB * @return */ private int calDistance(TaskSet taskA, TaskSet taskB) { if (taskA == null || taskB == null || taskA == taskB) { return 0; } LinkedList<TaskSet> listA = new LinkedList<TaskSet>(); LinkedList<TaskSet> listB = new LinkedList<TaskSet>(); int distance = 0; listA.add(taskA); listB.add(taskB); if (taskA.getTaskList().isEmpty() || taskB.getTaskList().isEmpty()) { return Integer.MAX_VALUE; } do { LinkedList<TaskSet> copyA = (LinkedList) listA.clone(); listA.clear(); for (TaskSet set : copyA) { for (TaskSet child : set.getChildList()) { if (!listA.contains(child)) { listA.add(child); } } } LinkedList<TaskSet> copyB = (LinkedList) listB.clone(); listB.clear(); for (TaskSet set : copyB) { for (TaskSet child : set.getChildList()) { if (!listB.contains(child)) { listB.add(child); } } } for (TaskSet set : listA) { if (listB.contains(set)) { return distance * 2; } } distance++; } while (!listA.isEmpty() && !listB.isEmpty()); return distance * 2; }
@Override public void run() { if (clusterNum > 0) { for (Iterator it = getTaskList().iterator(); it.hasNext(); ) { Task task = (Task) it.next(); TaskSet set = new TaskSet(); set.addTask(task); mTask2TaskSet.put(task, set); } } remove(); updateTaskSetDependencies(); printMetrics(); String code = Parameters.getClusteringParameters().getCode(); Map<Integer, ArrayList<TaskSet>> map = getCurrentTaskSetAtLevels(); if (code != null) { for (char c : code.toCharArray()) { switch (c) { case 'v': // verticalClustering(); VerticalBalancing v = new VerticalBalancing(map, this.mTask2TaskSet, this.clusterNum); v.run(); break; case 'c': // childAwareHorizontalClustering(); ChildAwareHorizontalClustering ch = new ChildAwareHorizontalClustering(map, this.mTask2TaskSet, this.clusterNum); ch.run(); updateTaskSetDependencies(); break; case 'r': // horizontalRuntimeBalancing(); HorizontalRuntimeBalancing r = new HorizontalRuntimeBalancing(map, this.mTask2TaskSet, this.clusterNum); r.run(); updateTaskSetDependencies(); break; case 'i': HorizontalImpactBalancing i = new HorizontalImpactBalancing(map, this.mTask2TaskSet, this.clusterNum); i.run(); break; case 'd': HorizontalDistanceBalancing d = new HorizontalDistanceBalancing(map, this.mTask2TaskSet, this.clusterNum); d.run(); break; case 'h': HorizontalRandomClustering h = new HorizontalRandomClustering(map, this.mTask2TaskSet, this.clusterNum); h.run(); break; default: break; } } printMetrics(); } printOut(); Collection sets = mTask2TaskSet.values(); for (Iterator it = sets.iterator(); it.hasNext(); ) { TaskSet set = (TaskSet) it.next(); if (!set.hasChecked) { set.hasChecked = true; addTasks2Job(set.getTaskList()); } } // a good habit cleanTaskSetChecked(); updateDependencies(); addClustDelay(); recover(); }