/** Plot the given data. */ private static void plotData(Data data, String label) { int len = data.K_series.length(); T_plot.xySeries(new AggregateXYSeries(data.K_series, data.T_series)) .label(label, data.K_series.x(len - 1), data.T_series.x(len - 1)); Speedup_plot.xySeries(new AggregateXYSeries(data.K_series, data.Speedup_series)) .label(label, data.K_series.x(len - 1), data.Speedup_series.x(len - 1)); Eff_plot.xySeries(new AggregateXYSeries(data.K_series, data.Eff_series)) .label(label, data.K_series.x(len - 1), data.Eff_series.x(len - 1)); EDSF_plot.xySeries(new AggregateXYSeries(data.K_series_2, data.EDSF_series_2)) .label(label, data.K_series_2.x(len - 2), data.EDSF_series_2.x(len - 2)); }
/** Parse a plot specification line. */ private static void parsePlotSpecification(Plot plot, Scanner scanner, int linenum) { if (!scanner.hasNext()) error("Missing plot attribute", linenum); String attribute = scanner.next(); if (attribute.equals("frameTitle")) { String theTitle = scanner.findInLine(QUOTED_STRING_PATTERN); if (theTitle == null) error("Missing quoted frame title", linenum); theTitle = theTitle.substring(1, theTitle.length() - 1); plot.frameTitle(theTitle + " (n = " + nplot + ")"); } else if (attribute.equals("plotTitle")) { String theTitle = scanner.findInLine(QUOTED_STRING_PATTERN); if (theTitle == null) error("Missing quoted plot title", linenum); theTitle = theTitle.substring(1, theTitle.length() - 1); plot.plotTitle(theTitle + " (n = " + nplot + ")"); } else if (attribute.equals("margins")) { if (!scanner.hasNextDouble()) error("Missing margins value", linenum); double theMargin = scanner.nextDouble(); plot.margins(theMargin); } else if (attribute.equals("leftMargin")) { if (!scanner.hasNextDouble()) error("Missing left margin value", linenum); double theMargin = scanner.nextDouble(); plot.leftMargin(theMargin); } else if (attribute.equals("topMargin")) { if (!scanner.hasNextDouble()) error("Missing top margin value", linenum); double theMargin = scanner.nextDouble(); plot.topMargin(theMargin); } else if (attribute.equals("rightMargin")) { if (!scanner.hasNextDouble()) error("Missing right margin value", linenum); double theMargin = scanner.nextDouble(); plot.rightMargin(theMargin); } else if (attribute.equals("bottomMargin")) { if (!scanner.hasNextDouble()) error("Missing bottom margin value", linenum); double theMargin = scanner.nextDouble(); plot.bottomMargin(theMargin); } else if (attribute.equals("xAxisStart")) { if (!scanner.hasNextDouble()) error("Missing X axis start value", linenum); double theStart = scanner.nextDouble(); plot.xAxisStart(theStart); } else if (attribute.equals("xAxisEnd")) { if (!scanner.hasNextDouble()) error("Missing X axis end value", linenum); double theStart = scanner.nextDouble(); plot.xAxisEnd(theStart); } else if (attribute.equals("xAxisMajorDivisions")) { if (!scanner.hasNextInt()) error("Missing X axis major divisions value", linenum); int theMajorDivisions = scanner.nextInt(); plot.xAxisMajorDivisions(theMajorDivisions); } else if (attribute.equals("xAxisMinorDivisions")) { if (!scanner.hasNextInt()) error("Missing X axis minor divisions value", linenum); int theMinorDivisions = scanner.nextInt(); plot.xAxisMinorDivisions(theMinorDivisions); } else if (attribute.equals("xAxisLength")) { if (!scanner.hasNextDouble()) error("Missing X axis length value", linenum); double theLength = scanner.nextDouble(); plot.xAxisLength(theLength); } else if (attribute.equals("xAxisTitle")) { String theTitle = scanner.findInLine(QUOTED_STRING_PATTERN); if (theTitle == null) error("Missing quoted X axis title", linenum); theTitle = theTitle.substring(1, theTitle.length() - 1); plot.xAxisTitle(theTitle); } else if (attribute.equals("yAxisStart")) { if (!scanner.hasNextDouble()) error("Missing Y axis start value", linenum); double theStart = scanner.nextDouble(); plot.yAxisStart(theStart); } else if (attribute.equals("yAxisEnd")) { if (!scanner.hasNextDouble()) error("Missing Y axis end value", linenum); double theStart = scanner.nextDouble(); plot.yAxisEnd(theStart); } else if (attribute.equals("yAxisMajorDivisions")) { if (!scanner.hasNextInt()) error("Missing Y axis major divisions value", linenum); int theMajorDivisions = scanner.nextInt(); plot.yAxisMajorDivisions(theMajorDivisions); } else if (attribute.equals("yAxisMinorDivisions")) { if (!scanner.hasNextInt()) error("Missing Y axis minor divisions value", linenum); int theMinorDivisions = scanner.nextInt(); plot.yAxisMinorDivisions(theMinorDivisions); } else if (attribute.equals("yAxisTickFormat")) { String theFormat = scanner.findInLine(QUOTED_STRING_PATTERN); if (theFormat == null) error("Missing quoted Y axis tick format", linenum); theFormat = theFormat.substring(1, theFormat.length() - 1); plot.yAxisTickFormat(new DecimalFormat(theFormat)); } else if (attribute.equals("yAxisLength")) { if (!scanner.hasNextDouble()) error("Missing Y axis length value", linenum); double theLength = scanner.nextDouble(); plot.yAxisLength(theLength); } else if (attribute.equals("yAxisTitle")) { String theTitle = scanner.findInLine(QUOTED_STRING_PATTERN); if (theTitle == null) error("Missing quoted Y axis title", linenum); theTitle = theTitle.substring(1, theTitle.length() - 1); plot.yAxisTitle(theTitle); } else if (attribute.equals("yAxisTitleOffset")) { if (!scanner.hasNextDouble()) error("Missing Y axis title offset value", linenum); double theTitleOffset = scanner.nextDouble(); plot.yAxisTitleOffset(theTitleOffset); } else { error("Unknown plot attribute", linenum); } }
/** Main program. */ public static void main(String[] args) throws Exception { // Parse command line arguments. if (args.length < 3) usage(); inputfile = new File(args[0]); nplot = Integer.parseInt(args[1]); for (int i = 2; i < args.length; ++i) { basis.add(parseBasisFunction(args[i])); } // Set up plots with default attributes. T_plot.plotTitle("n = " + nplot) .rightMargin(72) .minorGridLines(true) .xAxisKind(Plot.LOGARITHMIC) .xAxisMinorDivisions(10) .xAxisTitle("Processors, K") .yAxisKind(Plot.LOGARITHMIC) .yAxisMinorDivisions(10) .yAxisTickFormat(FMT_0E) .yAxisTickScale(1000) .yAxisTitle("Running Time, T (sec)") .labelPosition(Plot.RIGHT) .labelOffset(6); Speedup_plot.plotTitle("n = " + nplot) .rightMargin(72) .xAxisStart(0) .xAxisTitle("Processors, K") .yAxisStart(0) .yAxisTitle("Speedup") .labelPosition(Plot.RIGHT) .labelOffset(6); Eff_plot.plotTitle("n = " + nplot) .rightMargin(72) .xAxisStart(0) .xAxisTitle("Processors, K") .yAxisStart(0) .yAxisTickFormat(FMT_1) .yAxisTitle("Efficiency") .labelPosition(Plot.RIGHT) .labelOffset(6); EDSF_plot.plotTitle("n = " + nplot) .rightMargin(72) .xAxisStart(0) .xAxisTitle("Processors, K") .yAxisStart(0) .yAxisTickFormat(FMT_0) .yAxisTickScale(0.001) .yAxisTitle("Sequential Fraction, F (/1000)") .labelPosition(Plot.RIGHT) .labelOffset(6); // Parse the input file. Scanner scanner = new Scanner(inputfile); int linenum = 1; while (scanner.hasNextLine()) { String line = scanner.nextLine(); int i = line.indexOf('#'); if (i >= 0) line = line.substring(0, i); line = line.trim(); if (line.length() > 0) parseLine(line, linenum); ++linenum; } // Validate data. for (Data data : dataMap.values()) { validateData(data); } // Set up and solve nonnegative least squares problem. ListSeries n_series = new ListSeries(); ListSeries K_series = new ListSeries(); ListSeries T_series = new ListSeries(); for (Data data : dataMap.values()) { double n = data.n; for (int i = 0; i < data.K_series.length(); ++i) { double K = data.K_series.x(i); double T = data.T_series.x(i); if (K >= 1) { n_series.add(n); K_series.add(K); T_series.add(T); } } } int M = n_series.length(); int P = basis.size(); NonNegativeLeastSquares nnls = new NonNegativeLeastSquares(M, P); for (int i = 0; i < M; ++i) { double n = n_series.x(i); double K = K_series.x(i); double T = T_series.x(i); for (int j = 0; j < P; ++j) { nnls.a[i][j] = basis.get(j).f(n, K); } nnls.b[i] = T; } nnls.solve(); // Get actual data for n = nplot. Data actualData = dataMap.get(nplot); if (actualData == null) { System.err.println("No data for n = " + nplot); System.exit(1); } // Set up model data for n = nplot. Data modelData = new Data(nplot); for (int i = 0; i < actualData.K_series.length(); ++i) { double K = actualData.K_series.x(i); double T = modelFunction(nplot, K, nnls.x); if (K == 1) modelData.T_par_1 = T; double Speedup = modelData.T_par_1 / T; double Eff = Speedup / K; modelData.K_series.add(K); modelData.T_series.add(T); modelData.Speedup_series.add(Speedup); modelData.Eff_series.add(Eff); if (K >= 2) { double EDSF = (K * T - modelData.T_par_1) / modelData.T_par_1 / (K - 1); modelData.K_series_2.add(K); modelData.EDSF_series_2.add(EDSF); } } // Print data. System.out.println("Actual"); printData(actualData); System.out.println("Model"); printData(modelData); // Print model function and chi^2. System.out.print("T(n,K)"); for (int i = 0; i < P; ++i) { System.out.print(i == 0 ? " = " : " + "); System.out.print(basis.get(i).toString(nnls.x[i])); } System.out.println(); System.out.println("chi^2 = " + nnls.normsqr); // Add ideal performance lines to plots. Speedup_plot.seriesDots(null) .seriesColor(new Color(0.7f, 0.7f, 0.7f)) .xySeries(new double[] {0, K_max}, new double[] {0, K_max}); Eff_plot.seriesDots(null) .seriesColor(new Color(0.7f, 0.7f, 0.7f)) .xySeries(new double[] {0, K_max}, new double[] {1, 1}); // Add model data to plots. T_plot.seriesDots(null).seriesColor(Color.RED).labelColor(Color.RED); Speedup_plot.seriesDots(null).seriesColor(Color.RED).labelColor(Color.RED); Eff_plot.seriesDots(null).seriesColor(Color.RED).labelColor(Color.RED); EDSF_plot.seriesDots(null).seriesColor(Color.RED).labelColor(Color.RED); plotData(modelData, "Model"); // Add actual data to plots. T_plot.seriesDots(Dots.circle(5)).seriesColor(Color.BLACK).labelColor(Color.BLACK); Speedup_plot.seriesDots(Dots.circle(5)).seriesColor(Color.BLACK).labelColor(Color.BLACK); Eff_plot.seriesDots(Dots.circle(5)).seriesColor(Color.BLACK).labelColor(Color.BLACK); EDSF_plot.seriesDots(Dots.circle(5)).seriesColor(Color.BLACK).labelColor(Color.BLACK); plotData(actualData, "Actual"); // Display plots. T_plot.getFrame().setVisible(true); Speedup_plot.getFrame().setVisible(true); Eff_plot.getFrame().setVisible(true); EDSF_plot.getFrame().setVisible(true); }