package example.localplugin; import gridsim.dcworms.DCWormsTags; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import schedframe.events.scheduling.SchedulingEvent; import schedframe.resources.ResourceStatus; import schedframe.resources.StandardResourceType; import schedframe.resources.computing.ComputingResource; import schedframe.resources.computing.Node; import schedframe.resources.computing.Processor; import schedframe.resources.computing.profiles.energy.airthroughput.AirflowState; import schedframe.resources.computing.profiles.energy.airthroughput.AirflowStateName; import schedframe.resources.computing.profiles.energy.airthroughput.CustomAirflowStateName; import schedframe.resources.computing.profiles.energy.power.PState; import schedframe.resources.computing.profiles.energy.power.StandardPowerStateName; import schedframe.resources.devices.Device; import schedframe.resources.devices.Fan; import schedframe.resources.units.ProcessingElements; import schedframe.resources.units.ResourceUnit; import schedframe.resources.units.ResourceUnitName; import schedframe.resources.units.StandardResourceUnitName; import schedframe.scheduling.manager.resources.ClusterResourceManager; import schedframe.scheduling.manager.resources.ResourceManager; import schedframe.scheduling.manager.tasks.JobRegistry; import schedframe.scheduling.plan.SchedulingPlanInterface; import schedframe.scheduling.plan.impl.SchedulingPlan; import schedframe.scheduling.plugin.ModuleList; import schedframe.scheduling.queue.TaskQueue; import schedframe.scheduling.queue.TaskQueueList; import schedframe.scheduling.tasks.TaskInterface; public class Cluster_FCFSBF_ConsolidationHighPerf_NodePowMan_Plugin extends BaseLocalSchedulingPlugin { public Cluster_FCFSBF_ConsolidationHighPerf_NodePowMan_Plugin () { } public SchedulingPlanInterface schedule(SchedulingEvent event, TaskQueueList queues, JobRegistry jobRegistry, ResourceManager resManager, ModuleList modules) { ClusterResourceManager resourceManager = (ClusterResourceManager) resManager; SchedulingPlan plan = new SchedulingPlan(); // choose the events types to serve. // Different actions for different events are possible. switch (event.getType()) { case START_TASK_EXECUTION: case TASK_FINISHED: // our tasks are placed only in first queue (see // BaseLocalSchedulingPlugin.placeJobsInQueues() method) TaskQueue q = queues.get(0); // check all tasks in queue Set selectedNodes = new HashSet(); for (int i = 0; i < q.size(); i++) { TaskInterface task = q.get(i); // if status of the tasks in READY if (task.getStatus() == DCWormsTags.READY) { Map choosenResources = chooseResourcesForExecution(resourceManager, task); if (choosenResources != null) { addToSchedulingPlan(plan, task, choosenResources); ProcessingElements pe = (ProcessingElements) choosenResources.get(StandardResourceUnitName.PE); Node node = (Node) pe.get(0).getParent(); selectedNodes.add(node); } } } List nodes = resourceManager.getNodes(); nodes.removeAll(selectedNodes); turnOffIdleNodes(nodes); for(Node node: resourceManager.getNodes()){ for(Device device: node.getParent().getResourceCharacteristic().getDevices()){ if(device.getType().equals(StandardResourceType.Fan)){ Fan fan = (Fan) device; adjustFanSpeed(fan, selectedNodes); break; } } } break; } return plan; } @SuppressWarnings("unchecked") private Map chooseResourcesForExecution(ClusterResourceManager resourceManager, TaskInterface task){ List nodes = resourceManager.getNodes(); List availableNodes = findSuitableNodes(task, nodes); Node node; if(availableNodes.size() == 0){ nodes = (List) resourceManager.getResourcesByTypeWithStatus(StandardResourceType.Node, ResourceStatus.UNAVAILABLE); Collections.sort(nodes, new PerformanceComparator()); node = turnOnFirstNode(nodes, task); if(node == null) return null; }else{ Collections.sort(availableNodes, new PerformanceComparator()); node = availableNodes.get(0); } Map map = new HashMap(); List choosenResources = new ArrayList(); int cpuRequest; try { cpuRequest = Double.valueOf(task.getCpuCntRequest()).intValue(); } catch (NoSuchFieldException e) { cpuRequest = 0; } for (int i = 0; i < node.getProcessors().size() && cpuRequest > 0; i++) { if (node.getProcessors().get(i).getStatus() == ResourceStatus.FREE) { choosenResources.add(node.getProcessors().get(i)); cpuRequest--; } } ProcessingElements result = new ProcessingElements(node.getFullName()); result.addAll(choosenResources); map.put(StandardResourceUnitName.PE, result); return map; } private List findSuitableNodes(TaskInterface task, List nodes) { int cpuRequest; try { cpuRequest = Double.valueOf(task.getCpuCntRequest()).intValue(); } catch (NoSuchFieldException e) { cpuRequest = 1; } List suitableNodes = new ArrayList(); for(Node node: nodes){ if(node.getFreeProcessorsNumber() >= cpuRequest){ suitableNodes.add(node); } } return suitableNodes; } private Node turnOnFirstNode(List nodes, TaskInterface task){ Node startedNode = null; int cpuRequest; try { cpuRequest = Double.valueOf(task.getCpuCntRequest()).intValue(); } catch (NoSuchFieldException e) { cpuRequest = 0; } for(Node node: nodes){ if (cpuRequest != 0) { List processors = node.getProcessors(); if (processors.size() < cpuRequest) { if(processors.size() == 0){ if(node.getProcessors().size() < cpuRequest) continue; } } int freeProcessor = 0; for(Processor processor: processors){ if(processor.getStatus() == ResourceStatus.FREE || processor.getStatus() == ResourceStatus.UNAVAILABLE) freeProcessor++; } if(freeProcessor < cpuRequest) continue; else { node.getPowerInterface().setPowerState(StandardPowerStateName.ON); startedNode = node; break; } } } return startedNode; } private void turnOffIdleNodes(List nodes){ for(Node node : nodes){ int freeProcessors = 0; for(Processor proc: node.getProcessors()){ if(proc.getStatus() == ResourceStatus.FREE) freeProcessors++; } if(freeProcessors == node.getProcessors().size()) { node.getPowerInterface().setPowerState(StandardPowerStateName.OFF); } } } class PerformanceComparator implements Comparator{ public int compare(Node node1, Node node2){ double node1Rank = Double.MIN_VALUE; double node2Rank = Double.MIN_VALUE; double node1Speed = 0; for(Processor proc: node1.getProcessors()){ node1Speed = proc.getMIPS(); } node1Rank = node1Speed / node1.getProcessors().size(); double node2Speed = 0; for(Processor proc: node2.getProcessors()){ node2Speed = proc.getMIPS(); } node2Rank = node2Speed / node2.getProcessors().size(); if(node1Rank == node2Rank){ node1Rank = Double.MIN_VALUE; node2Rank = Double.MIN_VALUE; PState pState; for(Processor proc: node1.getProcessors()){ if(proc.getPowerInterface() != null) { pState = proc.getPowerInterface().getLowestPState(); if(pState != null && pState.getFrequency() > node1Rank){ node1Rank = proc.getPowerInterface().getLowestPState().getFrequency(); } } } for(Processor proc: node2.getProcessors()){ if(proc.getPowerInterface() != null) { pState = proc.getPowerInterface().getLowestPState(); if(pState != null && pState.getFrequency() > node2Rank){ node2Rank = proc.getPowerInterface().getLowestPState().getFrequency(); } } } } if(node1Rank < node2Rank) return 1; else if (node1Rank > node2Rank) return -1; else return 0; } } private void adjustFanSpeed(Fan fan, Set selectedNodes){ AirflowStateName newState; double totalLoad = 0; double loadLevel; ComputingResource compRes = fan.getComputingResource(); for(ComputingResource n: compRes.getChildren()){ if(fan.getChilledResources().contains(n.getFullName())){ if(selectedNodes.contains(n)){ totalLoad = totalLoad + 100; } else { totalLoad = totalLoad + n.getLoadInterface().getRecentUtilization().getValue(); } } } loadLevel = totalLoad / compRes.getChildren().size(); double highestLoadLevel = 0; if(fan.getAirflowInterface().supportAirflowState(new CustomAirflowStateName("ON_" + new Double(loadLevel).intValue()))){ newState = new CustomAirflowStateName("ON_" + new Double(loadLevel).intValue()); } else { for(AirflowState airflowState: fan.getAirflowInterface().getSupportedAirflowStates()){ Double load; try{ load = Double.valueOf(airflowState.getName().getLabel().substring(3)); }catch (Exception e){ continue; } if(highestLoadLevel < load){ highestLoadLevel = load; } } if(loadLevel == 0){ newState = new CustomAirflowStateName("OFF"); } else { double higherLoadLevel = highestLoadLevel; for(AirflowState airflowState: fan.getAirflowInterface().getSupportedAirflowStates()){ Double load; try{ load = Double.valueOf(airflowState.getName().getLabel().substring(3)); }catch (Exception e){ continue; } if(loadLevel < load){ higherLoadLevel = load; } } newState = new CustomAirflowStateName("ON_" + Double.valueOf(higherLoadLevel).intValue()); } } fan.getAirflowInterface().setAirflowState(newState); } }