/** Print a table of metrics for the given data. */ private static void printData(Data data) { System.out.println("n\tK\tT\tSpdup\tEffic\tEDSF"); System.out.println( data.n + "\t" + FMT_0.format(data.K_series.x(0)) + "\t" + FMT_0.format(data.T_series.x(0)) + "\t" + FMT_3.format(data.Speedup_series.x(0)) + "\t" + FMT_3.format(data.Eff_series.x(0))); for (int i = 1; i < data.K_series.length(); ++i) { System.out.println( data.n + "\t" + FMT_0.format(data.K_series.x(i)) + "\t" + FMT_0.format(data.T_series.x(i)) + "\t" + FMT_3.format(data.Speedup_series.x(i)) + "\t" + FMT_3.format(data.Eff_series.x(i)) + "\t" + FMT_3.format(data.EDSF_series_2.x(i - 1))); } }
/** 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 the given line of input. */ private static void parseLine(String line, int linenum) { Scanner scanner = new Scanner(line); if (scanner.hasNextInt()) { // A running time data line. Parse contents. int n = scanner.nextInt(); if (!scanner.hasNextInt()) error("K invalid", linenum); int K = scanner.nextInt(); if (K < 0) error("K < 0", linenum); if (K == 0) return; // Ignore T_seq K_max = Math.max(K_max, K); double T_min = Double.POSITIVE_INFINITY; double T_max = Double.NEGATIVE_INFINITY; while (scanner.hasNextLong()) { double T = (double) scanner.nextLong(); if (T <= 0.0) error("T invalid", linenum); T_min = Math.min(T_min, T); T_max = Math.max(T_max, T); } if (T_min == Double.POSITIVE_INFINITY) { error("T values missing", linenum); } // Record data. Data data = getData(n); if (K == 0) { data.T_seq = T_min; data.T_max_seq = T_max; data.Dev_seq = (T_max - T_min) / T_min; } else if (K == 1) { double Speedup = data.T_seq == 0.0 ? 1.0 : data.T_seq / T_min; double Eff = Speedup; double Dev = (T_max - T_min) / T_min; data.T_par_1 = T_min; data.K_series.add(K); data.T_series.add(T_min); data.T_max_series.add(T_max); data.Speedup_series.add(Speedup); data.Eff_series.add(Eff); data.Dev_series.add(Dev); } else { double Speedup = data.T_seq == 0.0 ? data.T_par_1 / T_min : data.T_seq / T_min; double Eff = Speedup / K; double Dev = (T_max - T_min) / T_min; double EDSF = (K * T_min - data.T_par_1) / data.T_par_1 / (K - 1); data.K_series.add(K); data.T_series.add(T_min); data.T_max_series.add(T_max); data.Speedup_series.add(Speedup); data.Eff_series.add(Eff); data.Dev_series.add(Dev); data.K_series_2.add(K); data.EDSF_series_2.add(EDSF); } } else { // A problem size specification line or plot specification line. String keyword = scanner.next(); if (keyword.equals("n")) { // A problem size specification line. Parse contents. if (!scanner.hasNextInt()) error("Missing n value", linenum); int n = scanner.nextInt(); if (!scanner.hasNextDouble()) error("Missing N value", linenum); double N = scanner.nextDouble(); String labelText = scanner.findInLine(QUOTED_STRING_PATTERN); if (labelText == null) error("Missing quoted label text", linenum); labelText = labelText.substring(1, labelText.length() - 1); // Record contents. Data data = getData(n); data.N = N; data.labelText = labelText; } else if (keyword.equals("time")) { parsePlotSpecification(T_plot, scanner, linenum); } else if (keyword.equals("speedup")) { parsePlotSpecification(Speedup_plot, scanner, linenum); } else if (keyword.equals("eff")) { parsePlotSpecification(Eff_plot, scanner, linenum); } else if (keyword.equals("edsf")) { parsePlotSpecification(EDSF_plot, scanner, linenum); } else { error("Unknown command", 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); }