package simulator.stats.implementation; import gridsim.gssim.GssimConstants; import gridsim.gssim.ResourceHistoryItem; import gssim.schedframe.scheduling.AbstractExecutable; import gssim.schedframe.scheduling.ExecTaskInterface; import java.awt.Color; import java.awt.Paint; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartRenderingInfo; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.AxisLocation; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.encoders.ImageFormat; import org.jfree.chart.labels.CategoryItemLabelGenerator; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.CombinedDomainXYPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.category.CategoryItemRenderer; import org.jfree.chart.renderer.category.GanttRenderer; import org.jfree.chart.renderer.xy.XYStepAreaRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.chart.title.Title; import org.jfree.data.gantt.TaskSeries; import org.jfree.data.gantt.TaskSeriesCollection; import org.jfree.data.time.FixedMillisecond; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.TextAnchor; import org.joda.time.DateTime; import org.joda.time.DateTimeUtilsExt; import schedframe.resources.profile.PowerUsage; import schedframe.resources.units.ResourceUnit; import schedframe.scheduling.Job; import schedframe.scheduling.JobInterface; import schedframe.scheduling.utils.ResourceParameterName; import simulator.ConfigurationOptions; import simulator.GenericUser; import simulator.GridSchedulingSimulator; import simulator.stats.SimulationStatistics; import simulator.stats.implementation.out.AbstractStringSerializer; import simulator.stats.implementation.out.FormatedStringSerializer; import simulator.stats.implementation.out.StringSerializer; import test.rewolucja.energy.extension.EnergyExtension; import test.rewolucja.extensions.Extension; import test.rewolucja.extensions.ExtensionList; import test.rewolucja.extensions.ExtensionType; import test.rewolucja.resources.ProcessingElements; import test.rewolucja.resources.ResourceType; import test.rewolucja.resources.exception.ResourceException; import test.rewolucja.resources.physical.base.ComputingResource; import test.rewolucja.resources.utils.ResourceController; import test.rewolucja.scheduling.JobRegistry; import csiro.mit.utils.jfreechart.timetablechart.TimetableChartFactory; import csiro.mit.utils.jfreechart.timetablechart.data.Timetable; import csiro.mit.utils.jfreechart.timetablechart.data.TimetableEventGroup; import csiro.mit.utils.jfreechart.timetablechart.data.TimetableEventSource; import csiro.mit.utils.jfreechart.timetablechart.renderer.TimetableRenderer; public class GSSimStatistics implements SimulationStatistics { private Log log = LogFactory.getLog(GSSimStatistics.class); protected static float ALPHA = 0.5f; protected static int GANTT_WIDTH = 1200; //protected static final int BITS = 8; //protected static final int MILLI_SEC = 1000; protected static final String RAW_TASKS_STATISTICS_OUTPUT_FILE_NAME = "Tasks.txt"; protected static final String JOBS_STATISTICS_OUTPUT_FILE_NAME = "Jobs.txt"; protected static final String SIMULATION_STATISTICS_OUTPUT_FILE_NAME = "Simulation.txt"; protected static final String ENERGYUSAGE_STATISTICS_OUTPUT_FILE_NAME = "Energy.txt"; protected static final String RESOURCEUSAGE_STATISTICS_OUTPUT_FILE_NAME = "ResourceUtilization.txt"; protected static final String DIAGRAMS_FILE_NAME_PREFIX = "Chart_"; protected static final String STATS_FILE_NAME_PREFIX = "Stats_"; protected static final String TASK_SEPARATOR = ";"; protected static final String JOB_SEPARATOR = ";"; protected String outputFolderName; protected String simulationIdentifier; protected ConfigurationOptions configuration; protected GSSAccumulatorsStats accStats; private GenericUser users; protected ResourceController resourceController; protected boolean generateDiagrams = true; protected AbstractStringSerializer serializer; protected long startSimulationTime; protected long endSimulationTime; //RESOURCES protected Timetable ganttDiagramPeTimetable; protected Map> resourceEnergyDiagrams; protected Map> resourceLoadDiagrams; protected Map> basicResStats; protected HashMap basicResLoad; protected Map peGanttMap; protected Map taskGanttMap; //TASKS protected int numOfdelayedTasks = 0; protected int numOfNotExecutedTasks = 0; protected double maxCj = 0; protected boolean allTasksFinished; protected TaskSeriesCollection ganttDiagramTaskSeriesCollection; protected TaskSeriesCollection ganttDiagramWaitingTimeSeriesCollection; protected HashMap> task_processorsMap; JobRegistry jr; public GSSimStatistics(String simulationIdentifier, ConfigurationOptions co, GenericUser users, String outputFolderName, ResourceController resourceController) { this.simulationIdentifier = simulationIdentifier; this.configuration = co; this.users = users; this.outputFolderName = outputFolderName; if (this.configuration.formatstatisticsoutput) this.serializer = new FormatedStringSerializer(); else this.serializer = new StringSerializer(); this.serializer.setDefaultNumberFormat(GridSchedulingSimulator.DFAULT_NUMBER_FORMAT); this.resourceController = resourceController; jr = new JobRegistry("COMPUTING_GRID_0#BROKER"); init(); } public void generateStatistics() { this.startSimulationTime = DateTimeUtilsExt.getOffsetTime().getTimeInMillis(); this.endSimulationTime = DateTimeUtilsExt.currentTimeMillis(); long s = 0; long e = 0; log.info("gatherResourceStatistics"); s = System.currentTimeMillis(); gatherResourceStatistics(); e = System.currentTimeMillis(); log.info("time in sec: " + ((e - s) / 1000)); log.info("gatherTaskStatistics"); s = System.currentTimeMillis(); gatherTaskStatistics(); e = System.currentTimeMillis(); log.info("time in sec: " + ((e - s) / 1000)); log.info("saveSimulationStatistics"); s = System.currentTimeMillis(); saveSimulationStatistics(); e = System.currentTimeMillis(); log.info("time in sec: " + ((e - s) / 1000)); } public String getOutputFolderName() { return outputFolderName; } private void init() { task_processorsMap = new HashMap>(); accStats = new GSSAccumulatorsStats(); } public void saveSimulationStatistics() { PrintStream simulationStatsFile = null; if (configuration.createsimulationstatistics) { try { File file = new File(outputFolderName + STATS_FILE_NAME_PREFIX + simulationIdentifier + "_" + SIMULATION_STATISTICS_OUTPUT_FILE_NAME); simulationStatsFile = new PrintStream(new FileOutputStream(file)); } catch (IOException e) { e.printStackTrace(); } } if (simulationStatsFile != null) { Object txt = accStats.serialize(this.serializer); simulationStatsFile.println(txt); } if (simulationStatsFile != null) { simulationStatsFile.close(); } } /************* RESOURCE STATISTICS SECTION **************/ private void gatherResourceStatistics() { //TEMPORARY CONFIGURATION SECTION ResourceType [] resForAnalyze = {ResourceType.COMPUTING_RESOURCE, ResourceType.COMPUTING_NODE, ResourceType.CPU}; HashMap> type_stats = new HashMap>(); List crStats = new ArrayList(); crStats.add(Stats.textLoad); crStats.add(Stats.chartLoad); crStats.add(Stats.textEnergy); crStats.add(Stats.chartEnergy); type_stats.put(ResourceType.COMPUTING_RESOURCE, crStats); List cnStats = new ArrayList(); cnStats.add(Stats.textLoad); //cnStats.add(Stats.chartLoad); cnStats.add(Stats.textEnergy); //cnStats.add(Stats.chartEnergy); type_stats.put(ResourceType.COMPUTING_NODE, cnStats); List cpuStats = new ArrayList(); cpuStats.add(Stats.textLoad); //cpuStats.add(Stats.chartLoad); cpuStats.add(Stats.textEnergy); //cpuStats.add(Stats.chartEnergy); type_stats.put(ResourceType.CPU, cpuStats); peGanttMap = new HashMap(); taskGanttMap = new HashMap(); resourceLoadDiagrams = new HashMap>(); resourceEnergyDiagrams = new HashMap>(); ganttDiagramPeTimetable = new Timetable(new FixedMillisecond( startSimulationTime), new FixedMillisecond(endSimulationTime)); PrintStream resourceLoadStatsFile = null; try { File file = new File(outputFolderName + STATS_FILE_NAME_PREFIX + simulationIdentifier + "_" + RESOURCEUSAGE_STATISTICS_OUTPUT_FILE_NAME); resourceLoadStatsFile = new PrintStream(new FileOutputStream(file)); } catch (IOException e) { resourceLoadStatsFile = null; } PrintStream energyStatsFile = null; try { File file = new File(outputFolderName + STATS_FILE_NAME_PREFIX + simulationIdentifier + "_" + ENERGYUSAGE_STATISTICS_OUTPUT_FILE_NAME); energyStatsFile = new PrintStream(new FileOutputStream(file)); } catch (IOException e) { energyStatsFile = null; } basicResStats = gatherPEStats(JobRegistry.getAllocationHistory()); peStatsPostProcessing(basicResStats); basicResLoad = calculatePELoad( basicResStats); if (configuration.creatediagrams_processors) { createPEGanttDiagram(basicResStats); } for(ResourceType resType: resForAnalyze){ List resources = null; try { resources = (List) resourceController.getResources().getDescendantsByType(resType); } catch (Exception e) { continue; } if(type_stats.containsKey(resType)){ for(ComputingResource resource: resources){ ResourceUsageStats resourceUsage = null; ResourceEnergyStats energyUsage = null; if(type_stats.get(resType).contains(Stats.textLoad)){ resourceUsage = gatherResourceLoadStats(resource, basicResStats); resourceUsage.setMeanUsage(calculateResourceLoad(resource, basicResLoad)); if (resourceLoadStatsFile != null) { Object txt = resourceUsage.serialize(serializer); resourceLoadStatsFile.println(txt); } } if(type_stats.get(resType).contains(Stats.chartLoad)){ if (configuration.creatediagrams_resources) { createResourceLoadDiagram(resourceUsage); } } if(type_stats.get(resType).contains(Stats.textEnergy)){ energyUsage = gatherResourceEnergyStats(resource); energyUsage.setMeanUsage(calculateEnergyLoad(energyUsage)); energyUsage.setSumUsage(energyUsage.getMeanUsage() * (endSimulationTime-startSimulationTime)/(3600*1000)); if (energyStatsFile != null) { Object txt = energyUsage.serialize(serializer); energyStatsFile.println(txt); } } if(type_stats.get(resType).contains(Stats.chartEnergy)){ if (configuration.creatediagrams_energyusage) { createResourceEnergyGanttDiagram(energyUsage); } } } } } saveResourceGanttDiagrams(); createAccumulatedResourceSimulationStatistic(); if (energyStatsFile != null) { energyStatsFile.close(); } if (resourceLoadStatsFile != null) { resourceLoadStatsFile.close(); } } private void peStatsPostProcessing(Map> basicResStats){ ResourceType resType = null; for(String key: basicResStats.keySet()){ List resStats = basicResStats.get(key); resType = resStats.get(0).getResType(); break; } List resources = null; try { resources = (List) resourceController.getResources().getDescendantsByType(resType); } catch (Exception e) { return; } for(ComputingResource resource: resources){ if(!basicResStats.containsKey(resource.getName())){ basicResStats.put(resource.getName(), new ArrayList()); } } } private Map> gatherPEStats(Map> history) { Map> basicResStats = new TreeMap>(new MapPEIdComparator()); for (Integer executableID : history.keySet()) { Map historyItem = (Map) history.get(executableID); List resHistItemList = (List) historyItem.get(GssimConstants.RESOURCES); Map res = resHistItemList.get(resHistItemList.size() - 1).getResourceUnits(); ResourceUnit resUnit = res.get(ResourceParameterName.PROCESSINGELEMENTS); ProcessingElements pes = (ProcessingElements) resUnit ; for(ComputingResource pe: pes){ String peName = pe.getName(); long startDate = ((DateTime) historyItem.get(GssimConstants.START_TIME)).getMillis(); long endDate = ((DateTime) historyItem.get(GssimConstants.END_TIME)).getMillis(); JobRegistry jr = new JobRegistry("stats"); ExecTaskInterface execTask = jr.getTaskExecutable(executableID); String uniqueTaskID = execTask.getJobId() + "_" + execTask.getId(); ResStat resStat = new ResStat(peName, pe.getType(), startDate, endDate, uniqueTaskID); List resStats = basicResStats.get(peName); if (resStats == null) { resStats = new ArrayList(); resStats.add(resStat); basicResStats.put(peName, resStats); } else { resStats.add(resStat); } List peNames = task_processorsMap.get(uniqueTaskID); if (peNames == null) { peNames = new ArrayList(); peNames.add(peName); task_processorsMap.put(uniqueTaskID, peNames); } else { peNames.add(peName); } } } return basicResStats; } private ResourceUsageStats gatherResourceLoadStats(ComputingResource resource, Map> basicStats) { ResourceUsageStats usageStats = new ResourceUsageStats(resource.getName(), resource.getType(), "resourceLoadStats"); for(String resName: basicStats.keySet()){ try { if(resource.getDescendantsByName(resName) != null || resource.getName().compareTo(resName) == 0){ createResourceLoadData(usageStats, basicStats.get(resName)); } } catch (ResourceException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return usageStats; } private TreeMap createResourceLoadData(ResourceUsageStats usageStats, List resStats) { TreeMap ganttData = (TreeMap)usageStats.getUsage(); for (ResStat resStat : resStats) { long start_time = resStat.getStartDate(); long end_time = resStat.getEndDate(); if (end_time > start_time) { Integer end = ganttData.get(end_time); if (end == null) { ganttData.put(end_time, 0); Long left = getLeftKey(ganttData, end_time); if (left != null) { Integer leftValue = ganttData.get(left); ganttData.put(end_time, leftValue); } } Integer start = ganttData.get(start_time); if (start == null) { ganttData.put(start_time, 0); Long left = getLeftKey(ganttData, start_time); if (left != null) { Integer leftValue = ganttData.get(left); ganttData.put(start_time, leftValue); } } SortedMap sm = ganttData.subMap(start_time, end_time); for (Long key : sm.keySet()) { Integer keyVal = ganttData.get(key); ganttData.put(key, keyVal + 1); } } } return ganttData; } private Long getLeftKey(TreeMap ganttData, Long toKey) { SortedMap sm = ganttData.headMap(toKey); if (sm.isEmpty()) { return null; } return sm.lastKey(); } private ResourceEnergyStats gatherResourceEnergyStats(ComputingResource resource) { double power = 0; ResourceEnergyStats resEnergyUsage = new ResourceEnergyStats(resource.getName(), resource.getType(), "resourceEnergyStats"); Map usage = resEnergyUsage.getEnergy(); ExtensionList extensionList = resource.getExtensionList(); if(extensionList != null){ for (Extension extension : extensionList) { if (extension.getType() == ExtensionType.ENERGY_EXTENSION) { EnergyExtension ee = (EnergyExtension)extension; List powerUsage = ee.getPowerUsageHistory(); if(powerUsage.size()==0) break; long lastTime = DateTimeUtilsExt.getOffsetTime().getTimeInMillis(); long endSimulationTime = DateTimeUtilsExt.currentTimeMillis(); double lastPower = 0; powerUsage.add(new PowerUsage(endSimulationTime, ee.getPowerUsageHistory().get(ee.getPowerUsageHistory().size()-1).getValue())); for(PowerUsage pu:powerUsage){ usage.put(pu.getTimestamp(), pu.getValue()); /// System.out.println(resource.getName() + ":"+new DateTime(pu.getTimestamp())+";"+pu.getValue()); power = power + (pu.getTimestamp() - lastTime) * lastPower/ (3600 * 1000); lastPower = pu.getValue(); lastTime = pu.getTimestamp(); } } } } //System.out.println(power); return resEnergyUsage; } private void createResourceEnergyGanttDiagram(ResourceEnergyStats energyUsage) { XYDataset dataset = createResourceEnergyGanttDataSet(energyUsage, startSimulationTime, endSimulationTime); List energyDiagram = resourceEnergyDiagrams.get(energyUsage.getResourceType()); if(energyDiagram == null){ energyDiagram = new ArrayList(); energyDiagram.add(dataset); resourceEnergyDiagrams.put(energyUsage.getResourceType(), energyDiagram); } else { energyDiagram.add(dataset); } } private XYDataset createResourceEnergyGanttDataSet( ResourceEnergyStats energyUsage, long start, long end) { TreeMap ganttdata = createResourceEnergyGanttData(energyUsage); XYSeriesCollection dataset = new XYSeriesCollection(); XYSeries data = new XYSeries(energyUsage.getResourceName(), false, true); //data.add(start, 0); for (Long key : ganttdata.keySet()) { Double val = ganttdata.get(key); data.add(key, val); } data.add(end, 0); dataset.addSeries(data); return dataset; } private TreeMap createResourceEnergyGanttData( ResourceEnergyStats energyUsage) { Map energy = energyUsage.getEnergy(); TreeMap ganttData = new TreeMap(); for (Long euKey : energy.keySet()) { ganttData.put(euKey, energy.get(euKey)); } return ganttData; } private boolean saveResourceGanttDiagrams() { JFreeChart resourceDiagram = null; JFreeChart peDiagram = null; JFreeChart resourceEnergyDiagram = null; if (!generateDiagrams) return false; String fileName = new File(outputFolderName, DIAGRAMS_FILE_NAME_PREFIX + simulationIdentifier + "_").getAbsolutePath(); String chartName = "Gantt diagram for " + GridSchedulingSimulator.SIMULATOR_NAME; String simulationTime = "Simulation time"; Title subtitle = new TextTitle("created for \"" + simulationIdentifier + "\" at " + Calendar.getInstance().getTime().toString()); if (configuration.creatediagrams_processors) { peDiagram = getPeGanttDiagram(chartName, subtitle, simulationTime); if (!saveCategoryChart(peDiagram, fileName + "Processing_Elements", "{0}")) return false; } if (configuration.creatediagrams_resources) { for(ResourceType resType: resourceLoadDiagrams.keySet()){ resourceDiagram = getResourcesLoadDiagram(resType, chartName, subtitle, simulationTime); if (!saveXYPlotChart(resourceDiagram, fileName + "Resources Load - "+resType)) return false; } } if (configuration.creatediagrams_energyusage) { for(ResourceType resType: resourceEnergyDiagrams.keySet()){ resourceEnergyDiagram = getResourcesEnergyDiagram(resType, chartName, subtitle, simulationTime); if (!saveXYPlotChart(resourceEnergyDiagram, fileName + "Energy - "+resType)) return false; } } return true; } private JFreeChart getResourcesLoadDiagram(ResourceType resType, String chartName, Title subtitle, String simulationTime) { String cpu = "CPU"; boolean urls = false; boolean tooltip = true; boolean legend = true; CombinedDomainXYPlot cPlot = new CombinedDomainXYPlot(); DateAxis xAxis = new DateAxis(simulationTime); JFreeChart chart = null; List loadDiagram = resourceLoadDiagrams.get(resType); for (XYDataset dataset : loadDiagram) { JFreeChart tChart = ChartFactory.createXYStepAreaChart("", "", null, dataset, PlotOrientation.VERTICAL, legend, tooltip, urls); XYPlot tPlot = tChart.getXYPlot(); NumberAxis yAxis = new NumberAxis(cpu); yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); tPlot.setRangeAxis(yAxis); XYStepAreaRenderer rend = (XYStepAreaRenderer) tPlot.getRenderer(); rend.setShapesVisible(false); cPlot.add(tPlot); } cPlot.setDomainAxis(xAxis); cPlot.setDomainAxisLocation(AxisLocation.TOP_OR_LEFT); chart = new JFreeChart(chartName, cPlot); chart.addSubtitle(subtitle); return chart; } private JFreeChart getResourcesEnergyDiagram(ResourceType resType, String chartName, Title subtitle, String simulationTime) { String energy = "ENERGY [W]"; boolean urls = false; boolean tooltip = true; boolean legend = true; CombinedDomainXYPlot cPlot = new CombinedDomainXYPlot(); DateAxis xAxis = new DateAxis(simulationTime); List energyDiagram = resourceEnergyDiagrams.get(resType); for (XYDataset dataset : energyDiagram) { JFreeChart tChart = ChartFactory.createXYStepAreaChart("", "", null, dataset, PlotOrientation.VERTICAL, legend, tooltip, urls); XYPlot tPlot = tChart.getXYPlot(); NumberAxis yAxis = new NumberAxis(energy); yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); tPlot.setRangeAxis(yAxis); XYStepAreaRenderer rend = (XYStepAreaRenderer) tPlot.getRenderer(); rend.setShapesVisible(false); cPlot.add(tPlot); } cPlot.setDomainAxis(xAxis); cPlot.setDomainAxisLocation(AxisLocation.TOP_OR_LEFT); JFreeChart chart = new JFreeChart(chartName, cPlot); chart.addSubtitle(subtitle); return chart; } private JFreeChart getPeGanttDiagram(String chartName, Title subtitle, String simulationTime) { String processors = "Processing Elements"; boolean tooltip = true; boolean legend = true; JFreeChart chart = TimetableChartFactory.createTimetableChart( chartName, processors, simulationTime, ganttDiagramPeTimetable, legend, tooltip); chart.addSubtitle(subtitle); TimetableRenderer rend = (TimetableRenderer) chart.getCategoryPlot() .getRenderer(); rend.setBackgroundBarPaint(null); return chart; } private boolean saveXYPlotChart(JFreeChart c, String fileName) { c.setNotify(false); c.setAntiAlias(true); c.setTextAntiAlias(true); c.setBorderVisible(false); int height = 900; CombinedDomainXYPlot cPlot = (CombinedDomainXYPlot) c.getPlot(); int nPlots = cPlot.getSubplots().size(); if (nPlots > 3) { height = nPlots * 300; } int width = GANTT_WIDTH; if (configuration.creatediagrams_resources_scale != -1) width = (int) ((endSimulationTime - startSimulationTime) * configuration.creatediagrams_resources_scale); ChartRenderingInfo info = new ChartRenderingInfo(); File f = new File(fileName + "." + ImageFormat.PNG); final String gssimSubtitle = "Created by " + GridSchedulingSimulator.SIMULATOR_NAME + " http://www.gssim.org/"; c.addSubtitle(new TextTitle(gssimSubtitle)); boolean encodeAlpha = false; int compression = 9;// values 0-9 try { ChartUtilities.saveChartAsPNG(f, c, width, height, info, encodeAlpha, compression); } catch (IOException e) { e.printStackTrace(); return false; } return true; } private void createPEGanttDiagram(Map> basicResStats) { for(String peName: basicResStats.keySet()){ TimetableEventSource pe = new TimetableEventSource(peName); ganttDiagramPeTimetable.addEventSource(pe); peGanttMap.put(peName, pe); for(ResStat resStat: basicResStats.get(peName)){ pe = peGanttMap.get(resStat.getPeName()); if(pe == null){ //pe = new TimetableEventSource(resStat.getPeName()); // ganttDiagramPeTimetable.addEventSource(pe); // peGanttMap.put(resStat.getPeName(), pe); } TimetableEventGroup task = taskGanttMap.get(resStat.getTaskID()); long startDate = resStat.getStartDate(); long endDate = resStat.getEndDate(); if (task == null) { task = new TimetableEventGroup(resStat.getTaskID()); taskGanttMap.put(resStat.getTaskID(), task); ganttDiagramPeTimetable.addEventGroup(task); } ganttDiagramPeTimetable.addEvent(pe, task, new FixedMillisecond(startDate), new FixedMillisecond(endDate)); } } } private void createResourceLoadDiagram(ResourceUsageStats resStats) { XYDataset dataset = createResourceLoadDataSet(resStats); List loadDiagram = resourceLoadDiagrams.get(resStats.getResourceType()); if(loadDiagram == null){ loadDiagram = new ArrayList(); loadDiagram.add(dataset); resourceLoadDiagrams.put(resStats.getResourceType(), loadDiagram); } else { loadDiagram.add(dataset); } } private XYDataset createResourceLoadDataSet(ResourceUsageStats resStats) { XYSeriesCollection dataset = new XYSeriesCollection(); XYSeries data = new XYSeries(resStats.resourceName, false, true); Map usage = resStats.getUsage(); for (Long key : usage.keySet()) { Integer val = usage.get(key); data.add(key, val); } dataset.addSeries(data); return dataset; } private void createAccumulatedResourceSimulationStatistic() { ComputingResource resource = resourceController.getResources(); for(ComputingResource child :resource.getChildren()){ double load = calculateResourceLoad(child, basicResLoad); accStats.meanTotalLoad.add(load); // accStats.meanEnergyUsage.add(tempMeanEnergyUsage.getMean()); } } private HashMap calculatePELoad(Map> basicResStats){ HashMap peLoad = new HashMap(); for(String resName: basicResStats.keySet()){ List resStats = basicResStats.get(resName); double sum = 0; for(ResStat resStat:resStats){ sum += (resStat.endDate-resStat.startDate); } double load = sum/(endSimulationTime-startSimulationTime); peLoad.put(resName, load); } return peLoad; } private Double calculateResourceLoad(ComputingResource resource, HashMap peLoad ){ int peCnt = 0; double sum = 0; for(String resName: peLoad.keySet()){ try { if(resource.getDescendantsByName(resName)!= null || resource.getName().compareTo(resName)==0){ Double load = peLoad.get(resName); sum += load; peCnt++; } } catch (ResourceException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return sum/peCnt; } private double calculateEnergyLoad(ResourceEnergyStats resEnergyStats ){ double meanEnergyUsage = 0; long time = 0; double load = 0; Map usage = resEnergyStats.getEnergy(); for (Long key : usage.keySet()) { if (time != 0) { meanEnergyUsage += (load * (key - time)) / (endSimulationTime - startSimulationTime); time = key; } else { time = key; } load = (double) usage.get(key); } return meanEnergyUsage; } /*private void createPEGanttDiagram(String peName, String uniqueTaskID, Map historyItem) { TimetableEventSource pe = peGanttMap.get(peName); if(pe == null){ pe = new TimetableEventSource(peName); ganttDiagramPETimetable.addEventSource(pe); peGanttMap.put(peName, pe); } TimetableEventGroup task = taskGanttMap.get(uniqueTaskID); long startDate = ((DateTime) historyItem.get(GssimConstants.START_TIME)) .getMillis(); long endDate = ((DateTime) historyItem.get(GssimConstants.END_TIME)) .getMillis(); if (task == null) { task = new TimetableEventGroup(uniqueTaskID); taskGanttMap.put(uniqueTaskID, task); ganttDiagramPETimetable.addEventGroup(task); } ganttDiagramPETimetable.addEvent(pe, task, new FixedMillisecond(startDate), new FixedMillisecond(endDate)); }*/ /************* TASK STATISTICS SECTION **************/ public void gatherTaskStatistics() { List> jobs = users.getAllReceivedJobs(); Collections.sort(jobs, new JobIdComparator()); ganttDiagramTaskSeriesCollection = new TaskSeriesCollection(); ganttDiagramWaitingTimeSeriesCollection = new TaskSeriesCollection(); PrintStream taskStatsFile = null; try { File file = new File(outputFolderName + STATS_FILE_NAME_PREFIX + simulationIdentifier + "_" + RAW_TASKS_STATISTICS_OUTPUT_FILE_NAME); taskStatsFile = new PrintStream(new FileOutputStream(file)); } catch (IOException e) { taskStatsFile = null; } PrintStream jobStatsFile = null; if (configuration.createjobsstatistics) { try { File file = new File(outputFolderName + STATS_FILE_NAME_PREFIX + simulationIdentifier + "_" + JOBS_STATISTICS_OUTPUT_FILE_NAME); jobStatsFile = new PrintStream(new FileOutputStream(file)); } catch (IOException e) { jobStatsFile = null; } } for (int i = 0; i < jobs.size(); i++) { Job job = (Job) jobs.get(i); //List execList = JobRegistry.getInstance("COMPUTING_GRID_0#BROKER").getAllSubmittedTasks(); List execList = jr.getJobExecutables(job.getId()); List taskStatsList = new ArrayList(); this.serializer.setFieldSeparator(TASK_SEPARATOR); for (int j = 0; j < execList.size(); j++) { AbstractExecutable task = (AbstractExecutable) execList.get(j); TaskStats taskStats = createTaskStats(task); if (taskStats != null && taskStatsFile != null) { Object txt = taskStats.serialize(serializer); taskStatsFile.println(txt); } if (taskStats != null && taskStats.getExecFinishDate() != -1) { if (configuration.createsimulationstatistics) { createAccumulatedTaskSimulationStatistic(taskStats); } allTasksFinished &= task.isFinished(); if (generateDiagrams) { if (configuration.creatediagrams_tasks) createTaskDiagramData(task); if (configuration.creatediagrams_taskswaitingtime) createTaskWaitingTimeDiagramData(task); } taskStatsList.add(taskStats); } } if (configuration.createjobsstatistics && taskStatsList.size() > 0) { this.serializer.setFieldSeparator(JOB_SEPARATOR); JobStats jobStats = createJobStats(taskStatsList); if (jobStatsFile != null) { Object txt = jobStats.serialize(serializer); jobStatsFile.println(txt); } } } if (configuration.createsimulationstatistics) { accStats.makespan.add(maxCj); accStats.delayedTasks.add(numOfdelayedTasks); accStats.failedRequests.add(users.getAllSentTasks().size() - users.getFinishedTasksCount()); } saveTaskGanttDiagrams(); if (taskStatsFile != null) { taskStatsFile.close(); } if (jobStatsFile != null) { jobStatsFile.close(); } } private TaskStats createTaskStats(AbstractExecutable task) { TaskStats taskStats = new TaskStats(task, startSimulationTime); String uniqueTaskID = taskStats.getJobID() + "_" + taskStats.getTaskID(); taskStats.setProcessorsName(task_processorsMap.get(uniqueTaskID)); return taskStats; } private JobStats createJobStats(List tasksStats) { String jobID = ((TaskStats) tasksStats.get(0)).getJobID(); JobStats jobStats = new JobStats(jobID); double maxCj = 0; for (int i = 0; i < tasksStats.size(); i++) { TaskStats task = (TaskStats) tasksStats.get(i); jobStats.meanTaskStartTime.add(task.getStartTime()); jobStats.meanTaskCompletionTime.add(task.getCompletionTime()); maxCj = Math.max(maxCj, task.getCompletionTime()); jobStats.meanTaskExecutionTime.add(task.getExecutionTime()); jobStats.meanTaskWaitingTime.add(task.getWaitingTime()); jobStats.meanTaskFlowTime.add(task.getFlowTime()); jobStats.meanTaskGQ_WaitingTime.add(task.getGQ_WaitingTime()); jobStats.lateness.add(task.getLateness()); jobStats.tardiness.add(task.getTardiness()); } jobStats.makespan.add(maxCj); return jobStats; } private void createAccumulatedTaskSimulationStatistic(TaskStats taskStats) { accStats.meanTaskFlowTime.add(taskStats.getFlowTime()); accStats.meanTaskExecutionTime.add(taskStats.getExecutionTime()); accStats.meanTaskCompletionTime.add(taskStats.getCompletionTime()); accStats.meanTaskWaitingTime.add(taskStats.getWaitingTime()); accStats.meanTaskStartTime.add(taskStats.getStartTime()); accStats.lateness.add(taskStats.getLateness()); accStats.tardiness.add(taskStats.getTardiness()); if (taskStats.getExecFinishDate() == -1) { numOfNotExecutedTasks++; } if (taskStats.getTardiness() > 0.0) { numOfdelayedTasks++; } maxCj = Math.max(maxCj, taskStats.getCompletionTime()); } private void createTaskDiagramData(AbstractExecutable task) { String uniqueTaskID = task.getJobId() + "_" + task.getId(); String resIDlist[] = task.getAllResourceName(); String resID = resIDlist[resIDlist.length - 1]; long execStartTime = Double.valueOf(task.getExecStartTime()).longValue() * 1000; long execEndTime = Double.valueOf(task.getFinishTime()).longValue() * 1000; TaskSeries taskRes = ganttDiagramTaskSeriesCollection.getSeries(resID); if (taskRes == null) { taskRes = new TaskSeries(resID); ganttDiagramTaskSeriesCollection.add(taskRes); } org.jfree.data.gantt.Task ganttTask = new org.jfree.data.gantt.Task(uniqueTaskID, new Date(execStartTime), new Date(execEndTime)); if (!task.isFinished()) { ganttTask.setPercentComplete(1.0); } taskRes.add(ganttTask); } private void createTaskWaitingTimeDiagramData(AbstractExecutable task) { String uniqueTaskID = task.getJobId() + "_" + task.getId(); String resIDlist[] = task.getAllResourceName(); String resID = resIDlist[resIDlist.length - 1]; long execStartTime = Double.valueOf(task.getExecStartTime()).longValue() * 1000; long execEndTime = Double.valueOf(task.getFinishTime()).longValue() * 1000; TaskSeries waitRes = ganttDiagramWaitingTimeSeriesCollection.getSeries(resID); if (waitRes == null) { waitRes = new TaskSeries(resID); ganttDiagramWaitingTimeSeriesCollection.add(waitRes); } long sub = Double.valueOf(task.getSubmissionTime()).longValue() * 1000; org.jfree.data.gantt.Task wait_exec = new org.jfree.data.gantt.Task(uniqueTaskID, new Date(sub), new Date( execEndTime)); org.jfree.data.gantt.Task exec = new org.jfree.data.gantt.Task(uniqueTaskID, new Date(execStartTime), new Date( execEndTime)); if (!task.isFinished()) { exec.setPercentComplete(1.0); } wait_exec.addSubtask(wait_exec); wait_exec.addSubtask(exec); waitRes.add(wait_exec); } private boolean saveTaskGanttDiagrams() { JFreeChart taskDiagram = null; JFreeChart waitingTimeDiagram = null; if (!generateDiagrams) return false; String fileName = new File(outputFolderName, DIAGRAMS_FILE_NAME_PREFIX + simulationIdentifier + "_") .getAbsolutePath(); String chartName = "Gantt diagram for " + GridSchedulingSimulator.SIMULATOR_NAME; String simulationTime = "Simulation time"; Title subtitle = new TextTitle("created for \"" + simulationIdentifier + "\" at " + Calendar.getInstance().getTime().toString()); if (configuration.creatediagrams_tasks) { taskDiagram = getTaskDiagram(chartName, subtitle, simulationTime); if (!saveCategoryChart(taskDiagram, fileName + "Tasks", null /* "{0}" */)) return false; } if (configuration.creatediagrams_taskswaitingtime) { waitingTimeDiagram = getWaitingTimeDiagram(chartName, subtitle, simulationTime); if (!saveCategoryChart(waitingTimeDiagram, fileName + "Waiting_Time", null /* "Task {1} at {0}" */)) return false; } return true; } private JFreeChart getTaskDiagram(String chartName, Title subtitle, String simulationTime) { String tasks = "Tasks"; boolean urls = false; boolean tooltip = true; boolean legend = true; JFreeChart chart = ChartFactory.createGanttChart(chartName, tasks, simulationTime, ganttDiagramTaskSeriesCollection, legend, tooltip, urls); chart.addSubtitle(subtitle); GanttRenderer re = (GanttRenderer) chart.getCategoryPlot().getRenderer(); re.setCompletePaint(Color.black); return chart; } private JFreeChart getWaitingTimeDiagram(String chartName, Title subtitle, String simulationTime) { String tasks = "Tasks"; boolean urls = false; boolean tooltip = true; boolean legend = true; JFreeChart chart = ChartFactory.createGanttChart(chartName, tasks, simulationTime, ganttDiagramWaitingTimeSeriesCollection, legend, tooltip, urls); chart.addSubtitle(subtitle); chart.getPlot().setForegroundAlpha(ALPHA); GanttRenderer re = (GanttRenderer) chart.getCategoryPlot().getRenderer(); re.setCompletePaint(Color.black); return chart; } private boolean saveCategoryChart(JFreeChart c, String fileName, String labelFormat) { c.setNotify(false); c.setAntiAlias(true); c.setTextAntiAlias(true); c.setBorderVisible(false); CategoryPlot categoryplot = (CategoryPlot) c.getPlot(); categoryplot.setDomainGridlinesVisible(true); if (labelFormat != null) { CategoryItemRenderer rend = categoryplot.getRenderer(); rend.setBaseItemLabelsVisible(true); ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.CENTER, TextAnchor.CENTER); rend.setBasePositiveItemLabelPosition(position); NumberFormat nf = NumberFormat.getInstance(); CategoryItemLabelGenerator gen = new StandardCategoryItemLabelGenerator(labelFormat, nf); rend.setBaseItemLabelGenerator(gen); } int rows = c.getCategoryPlot().getDataset().getColumnKeys().size(); int height = 900; if (rows > 45) { height = rows * 20; } int width = calculateChartWidth(c); CategoryItemRenderer rend = c.getCategoryPlot().getRenderer(); for (int i = 0; i < c.getCategoryPlot().getDataset().getRowKeys().size(); i++) { Paint collor = c.getCategoryPlot().getDrawingSupplier().getNextPaint(); rend.setSeriesOutlinePaint(i, collor); rend.setSeriesPaint(i, collor); } ChartRenderingInfo info = new ChartRenderingInfo(); // info.setEntityCollection(null); File f = new File(fileName + "." + ImageFormat.PNG); final String gssimSubtitle = "Created by " + GridSchedulingSimulator.SIMULATOR_NAME + " http://www.gssim.org/"; c.addSubtitle(new TextTitle(gssimSubtitle)); boolean encodeAlpha = false; int compression = 9; try { ChartUtilities.saveChartAsPNG(f, c, width, height, info, encodeAlpha, compression); } catch (IOException e) { e.printStackTrace(); return false; } catch (Exception e) { if (log.isErrorEnabled()) log.error("The png file (" + fileName + ")\nwill not be generated (It can be too large data size problem)", e); } catch (Throwable t) { log.error("The png file (" + fileName + ")\nwill not be generated (It can be too large data size problem)", t); } return true; } private int calculateChartWidth(JFreeChart c) { int ganttWidth = GANTT_WIDTH; int rows = c.getCategoryPlot().getDataset().getColumnKeys().size(); if (rows > 45) { int height = rows * 20; ganttWidth = Math.max((int) (height * 1.5), GANTT_WIDTH); } return ganttWidth; } private static class JobIdComparator implements Comparator> { public int compare(JobInterface o1, JobInterface o2) { try { Integer o1int; Integer o2int; try{ o1int = Integer.parseInt(o1.getId()); o2int = Integer.parseInt(o2.getId()); return o1int.compareTo(o2int); } catch(NumberFormatException e){ return o1.getId().compareTo(o2.getId()); } } catch (NoSuchFieldException e) { e.printStackTrace(); } return -1; } } private static class MapPEIdComparator implements Comparator { public int compare(String o1, String o2) { Integer o1int; Integer o2int; o1int = Integer.parseInt(o1.substring(o1.indexOf("_")+1)); o2int = Integer.parseInt(o2.substring(o2.indexOf("_")+1)); return o1int.compareTo(o2int); } } } class ResStat{ public long getStartDate() { return startDate; } public void setStartDate(long startDate) { this.startDate = startDate; } public long getEndDate() { return endDate; } public void setEndDate(long endDate) { this.endDate = endDate; } public String getTaskID() { return taskID; } public void setTaskID(String taskID) { this.taskID = taskID; } public ResStat( String peName, long startDate, long endDate, String taskID) { super(); this.startDate = startDate; this.endDate = endDate; this.taskID = taskID; this.peName = peName; } public String getPeName() { return peName; } public void setPeName(String peName) { this.peName = peName; } public ResStat(String peName, ResourceType resType, long startDate, long endDate, String taskID) { super(); this.peName = peName; this.resType = resType; this.startDate = startDate; this.endDate = endDate; this.taskID = taskID; } String peName; ResourceType resType; long startDate; long endDate; String taskID; public ResourceType getResType() { return resType; } public void setResType(ResourceType resType) { this.resType = resType; } } enum Stats{ textLoad, chartLoad, textEnergy, chartEnergy; }