/* * Copyright (C) 2014 - Andreas Maier, Magdalena Herbst, Michael Dorner, Salah Saleh, Anja Pohan, Stefan Nottrott, Frank Schebesch * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.conrad.data.numeric.opencl; import com.jogamp.opencl.CLContext; import com.jogamp.opencl.CLDevice; import edu.stanford.rsl.conrad.data.numeric.Grid2D; import edu.stanford.rsl.conrad.opencl.OpenCLUtil; /** * OpenCLBenchmark is a tiny benchmark for testing local and global memory kernels and demo how an extension of new kernels works. */ public class OpenCLBenchmark { public static void main(String[] args) { CLContext context = OpenCLUtil.createContext(); CLDevice[] devices = context.getDevices(); CLDevice device = devices[0]; String leftAlignFormat = "| %-20s | %-5d | %-6d |%n"; System.out.format("+----------------------+-------+--------+%n"); System.out.printf("| size | local | global |%n"); System.out.format("+----------------------+-------+--------+%n"); int iterations = 10; for (int p = 2; p<12; p++) { int x = (int)Math.pow(2, p); int y = (int)Math.pow(2, p); Grid2D grid2D = new Grid2D(x, y); // fill the grid with 1.0f for(int i = 0; i<x; i++) { for(int j = 0; j<y; j++) { float val = 1.0f; grid2D.setAtIndex(i, j, val); } } // local version, using the standard OpenClGridOperators class OpenCLGrid2D openCLGrid2DLocal = new OpenCLGrid2D(grid2D, context, device); OpenCLGridOperators openCLGridOperatos = (OpenCLGridOperators) openCLGrid2DLocal.getGridOperator(); openCLGridOperatos.sum(openCLGrid2DLocal); // initialize double sum = 0.0; long startLocal = System.currentTimeMillis(); for (int i = 0; i<iterations; i++) { sum = openCLGridOperatos.sum(openCLGrid2DLocal); } long endLocal = (System.currentTimeMillis() - startLocal); if ((int)sum != x*y) { System.out.println("\tWrong result in local sum: " + sum + " != " + x); } openCLGrid2DLocal.release(); openCLGrid2DLocal = null; /* * In this example we extend the standard OpenCL grid operators by a new method 'sumGlobalMemory(...)'. * Therefore we have to instantiate the new class ExtendedOpenCLGridOperators by its singleton. * Then we can set this new, extended grid operator class to the grid. */ OpenCLGrid2D openCLGrid2DGlobal = new OpenCLGrid2D(grid2D, context, device); openCLGrid2DGlobal.setNumericGridOperator(ExtendedOpenCLGridOperators.getInstance()); // set a new numeric grid operator class ExtendedOpenCLGridOperators gg = (ExtendedOpenCLGridOperators) openCLGrid2DGlobal.getGridOperator(); // continue as usual, but with a cast gg.sumGlobalMemory(openCLGrid2DGlobal); sum = 0.0; long startGlobal = System.currentTimeMillis(); for (int i = 0; i<iterations; i++) { sum = gg.sumGlobalMemory(openCLGrid2DGlobal); } long endGlobal = (System.currentTimeMillis() - startGlobal); if ( (int)sum != x*y ) { System.out.println("\tWrong result in global sum: " + sum + " != " + x*y); } openCLGrid2DGlobal.release(); openCLGrid2DGlobal = null; System.out.format(leftAlignFormat, (x + " x " + y)+ " pixels ", endLocal/iterations, endGlobal/iterations); } System.out.format("+----------------------+-------+--------+%n"); // last, but not lead: // dot product Grid2D grid2D = new Grid2D(512, 512); for(int i = 0; i<512; i++) { for(int j = 0; j<512; j++) { float val = 1.0f; grid2D.setAtIndex(i, j, val); } } OpenCLGrid2D openCLGrid2D = new OpenCLGrid2D(grid2D, context, device); double dotProduct = openCLGrid2D.getGridOperator().dotProduct(openCLGrid2D, openCLGrid2D); System.out.println("dot product: " + dotProduct); //min openCLGrid2D.setAtIndex(1, 2, -0.12345f); float min = openCLGrid2D.getGridOperator().min(openCLGrid2D); System.out.println("min: " + min); } }