001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is JTransforms.
015 *
016 * The Initial Developer of the Original Code is
017 * Piotr Wendykier, Emory University.
018 * Portions created by the Initial Developer are Copyright (C) 2007-2009
019 * the Initial Developer. All Rights Reserved.
020 *
021 * Alternatively, the contents of this file may be used under the terms of
022 * either the GNU General Public License Version 2 or later (the "GPL"), or
023 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
024 * in which case the provisions of the GPL or the LGPL are applicable instead
025 * of those above. If you wish to allow use of your version of this file only
026 * under the terms of either the GPL or the LGPL, and not to allow others to
027 * use your version of this file under the terms of the MPL, indicate your
028 * decision by deleting the provisions above and replace them with the notice
029 * and other provisions required by the GPL or the LGPL. If you do not delete
030 * the provisions above, a recipient may use your version of this file under
031 * the terms of any one of the MPL, the GPL or the LGPL.
032 *
033 * ***** END LICENSE BLOCK ***** */
034
035package edu.emory.mathcs.jtransforms.dht;
036
037import java.util.Arrays;
038
039import edu.emory.mathcs.utils.ConcurrencyUtils;
040import edu.emory.mathcs.utils.IOUtils;
041
042/**
043 * Benchmark of double precision DHT's
044 *
045 * @author Piotr Wendykier (piotr.wendykier@gmail.com)
046 *
047 */
048@SuppressWarnings("javadoc")
049public class BenchmarkDoubleDHT {
050
051        private static int nthread = 8;
052
053        private static int niter = 200;
054
055        private static int nsize = 16;
056
057        private static int threadsBegin2D = 65636;
058
059        private static int threadsBegin3D = 65636;
060
061        private static boolean doWarmup = true;
062
063        private static int[] sizes1D = new int[] { 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 10368,
064                        27000, 75600, 165375, 362880, 1562500, 3211264, 6250000 };
065
066        private static int[] sizes2D = new int[] { 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 260, 520, 1050, 1458, 1960,
067                        2916, 4116, 5832 };
068
069        private static int[] sizes3D = new int[] { 8, 16, 32, 64, 128, 256, 512, 1024, 5, 17, 30, 95, 180, 270, 324, 420 };
070
071        private static boolean doScaling = false;
072
073        private BenchmarkDoubleDHT() {
074
075        }
076
077        public static void parseArguments(String[] args) {
078                if (args.length > 0) {
079                        nthread = Integer.parseInt(args[0]);
080                        threadsBegin2D = Integer.parseInt(args[1]);
081                        threadsBegin3D = Integer.parseInt(args[2]);
082                        niter = Integer.parseInt(args[3]);
083                        doWarmup = Boolean.parseBoolean(args[4]);
084                        doScaling = Boolean.parseBoolean(args[5]);
085                        nsize = Integer.parseInt(args[6]);
086                        sizes1D = new int[nsize];
087                        sizes2D = new int[nsize];
088                        sizes3D = new int[nsize];
089                        for (int i = 0; i < nsize; i++) {
090                                sizes1D[i] = Integer.parseInt(args[7 + i]);
091                        }
092                        for (int i = 0; i < nsize; i++) {
093                                sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
094                        }
095                        for (int i = 0; i < nsize; i++) {
096                                sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
097                        }
098                } else {
099                        System.out.println("Default settings are used.");
100                }
101                ConcurrencyUtils.setNumberOfThreads(nthread);
102                ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
103                ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
104                System.out.println("nthred = " + nthread);
105                System.out.println("threadsBegin2D = " + threadsBegin2D);
106                System.out.println("threadsBegin3D = " + threadsBegin3D);
107                System.out.println("niter = " + niter);
108                System.out.println("doWarmup = " + doWarmup);
109                System.out.println("doScaling = " + doScaling);
110                System.out.println("nsize = " + nsize);
111                System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
112                System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
113                System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
114        }
115
116        public static void benchmarkForward_1D() {
117                final double[] times = new double[nsize];
118                double[] x;
119                for (int i = 0; i < nsize; i++) {
120                        System.out.println("Forward DHT 1D of size " + sizes1D[i]);
121                        DoubleDHT_1D dht = new DoubleDHT_1D(sizes1D[i]);
122                        x = new double[sizes1D[i]];
123                        if (doWarmup) { // call the transform twice to warm up
124                                IOUtils.fillMatrix_1D(sizes1D[i], x);
125                                dht.forward(x);
126                                IOUtils.fillMatrix_1D(sizes1D[i], x);
127                                dht.forward(x);
128                        }
129                        double av_time = 0;
130                        long elapsedTime = 0;
131                        for (int j = 0; j < niter; j++) {
132                                IOUtils.fillMatrix_1D(sizes1D[i], x);
133                                elapsedTime = System.nanoTime();
134                                dht.forward(x);
135                                elapsedTime = System.nanoTime() - elapsedTime;
136                                av_time = av_time + elapsedTime;
137                        }
138                        times[i] = av_time / 1000000.0 / niter;
139                        System.out.println("Average execution time: " + String.format("%.2f", av_time / 1000000.0 / niter) + " msec");
140                        x = null;
141                        dht = null;
142                        System.gc();
143                        ConcurrencyUtils.sleep(5000);
144                }
145                IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_1D.txt", nthread, niter, doWarmup, doScaling,
146                                sizes1D, times);
147        }
148
149        public static void benchmarkForward_2D_input_1D() {
150                final double[] times = new double[nsize];
151                double[] x;
152                for (int i = 0; i < nsize; i++) {
153                        System.out.println("Forward DHT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
154                        DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
155                        x = new double[sizes2D[i] * sizes2D[i]];
156                        if (doWarmup) { // call the transform twice to warm up
157                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
158                                dht2.forward(x);
159                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
160                                dht2.forward(x);
161                        }
162                        double av_time = 0;
163                        long elapsedTime = 0;
164                        for (int j = 0; j < niter; j++) {
165                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
166                                elapsedTime = System.nanoTime();
167                                dht2.forward(x);
168                                elapsedTime = System.nanoTime() - elapsedTime;
169                                av_time = av_time + elapsedTime;
170                        }
171                        times[i] = av_time / 1000000.0 / niter;
172                        System.out.println("Average execution time: " + String.format("%.2f", av_time / 1000000.0 / niter) + " msec");
173                        x = null;
174                        dht2 = null;
175                        System.gc();
176                        ConcurrencyUtils.sleep(5000);
177                }
178                IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_2D_input_1D.txt", nthread, niter, doWarmup,
179                                doScaling, sizes2D, times);
180
181        }
182
183        public static void benchmarkForward_2D_input_2D() {
184                final double[] times = new double[nsize];
185                double[][] x;
186                for (int i = 0; i < nsize; i++) {
187                        System.out.println("Forward DHT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
188                        DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
189                        x = new double[sizes2D[i]][sizes2D[i]];
190                        if (doWarmup) { // call the transform twice to warm up
191                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
192                                dht2.forward(x);
193                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
194                                dht2.forward(x);
195                        }
196                        double av_time = 0;
197                        long elapsedTime = 0;
198                        for (int j = 0; j < niter; j++) {
199                                IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
200                                elapsedTime = System.nanoTime();
201                                dht2.forward(x);
202                                elapsedTime = System.nanoTime() - elapsedTime;
203                                av_time = av_time + elapsedTime;
204                        }
205                        times[i] = av_time / 1000000.0 / niter;
206                        System.out.println("Average execution time: " + String.format("%.2f", av_time / 1000000.0 / niter) + " msec");
207                        x = null;
208                        dht2 = null;
209                        System.gc();
210                        ConcurrencyUtils.sleep(5000);
211                }
212                IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_2D_input_2D.txt", nthread, niter, doWarmup,
213                                doScaling, sizes2D, times);
214
215        }
216
217        public static void benchmarkForward_3D_input_1D() {
218                final double[] times = new double[nsize];
219                double[] x;
220                for (int i = 0; i < nsize; i++) {
221                        System.out.println("Forward DHT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x "
222                                        + sizes3D[i]);
223                        DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
224                        x = new double[sizes3D[i] * sizes3D[i] * sizes3D[i]];
225                        if (doWarmup) { // call the transform twice to warm up
226                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
227                                dht3.forward(x);
228                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
229                                dht3.forward(x);
230                        }
231                        double av_time = 0;
232                        long elapsedTime = 0;
233                        for (int j = 0; j < niter; j++) {
234                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
235                                elapsedTime = System.nanoTime();
236                                dht3.forward(x);
237                                elapsedTime = System.nanoTime() - elapsedTime;
238                                av_time = av_time + elapsedTime;
239                        }
240                        times[i] = av_time / 1000000.0 / niter;
241                        System.out.println("Average execution time: " + String.format("%.2f", av_time / 1000000.0 / niter) + " msec");
242                        x = null;
243                        dht3 = null;
244                        System.gc();
245                        ConcurrencyUtils.sleep(5000);
246                }
247                IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_3D_input_1D.txt", nthread, niter, doWarmup,
248                                doScaling, sizes3D, times);
249
250        }
251
252        public static void benchmarkForward_3D_input_3D() {
253                final double[] times = new double[nsize];
254                double[][][] x;
255                for (int i = 0; i < nsize; i++) {
256                        System.out.println("Forward DHT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x "
257                                        + sizes3D[i]);
258                        DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
259                        x = new double[sizes3D[i]][sizes3D[i]][sizes3D[i]];
260                        if (doWarmup) { // call the transform twice to warm up
261                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
262                                dht3.forward(x);
263                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
264                                dht3.forward(x);
265                        }
266                        double av_time = 0;
267                        long elapsedTime = 0;
268                        for (int j = 0; j < niter; j++) {
269                                IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
270                                elapsedTime = System.nanoTime();
271                                dht3.forward(x);
272                                elapsedTime = System.nanoTime() - elapsedTime;
273                                av_time = av_time + elapsedTime;
274                        }
275                        times[i] = av_time / 1000000.0 / niter;
276                        System.out.println("Average execution time: " + String.format("%.2f", av_time / 1000000.0 / niter) + " msec");
277                        x = null;
278                        dht3 = null;
279                        System.gc();
280                        ConcurrencyUtils.sleep(5000);
281                }
282                IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_3D_input_3D.txt", nthread, niter, doWarmup,
283                                doScaling, sizes3D, times);
284        }
285
286        public static void main(String[] args) {
287                parseArguments(args);
288                benchmarkForward_1D();
289                benchmarkForward_2D_input_1D();
290                benchmarkForward_2D_input_2D();
291                benchmarkForward_3D_input_1D();
292                benchmarkForward_3D_input_3D();
293                System.exit(0);
294
295        }
296}