diff --git a/examples/javaonedemo/mandel.bat b/examples/javaonedemo/mandel.bat new file mode 100644 index 0000000000000000000000000000000000000000..11988e6f013993be6130fcd5c44596fc7f08d65c --- /dev/null +++ b/examples/javaonedemo/mandel.bat @@ -0,0 +1,14 @@ +java ^ + -Djava.library.path=../../com.amd.aparapi.jni/dist ^ + -Dcom.amd.aparapi.executionMode=%1 ^ + -Dcom.amd.aparapi.logLevel=SEVERE^ + -Dcom.amd.aparapi.enableVerboseJNI=false ^ + -Dcom.amd.aparapi.enableProfiling=false ^ + -Dcom.amd.aparapi.enableShowGeneratedOpenCL=false ^ + -Dcom.amd.aparapi.enableVerboseJNIOpenCLResourceTracking=false ^ + -Dcom.amd.aparapi.dumpFlags=true ^ + -Dcom.amd.aparapi.enableInstructionDecodeViewer=false ^ + -classpath ../../com.amd.aparapi/dist/aparapi.jar;javaonedemo.jar ^ + com.amd.aparapi.examples.javaonedemo.Mandel + + diff --git a/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Life.java b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Life.java index 87a027f46cf1020643e1bffb4c0747763e57c609..d439dada8ff0ec362772ab4b8ffcda2bbb4a260f 100644 --- a/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Life.java +++ b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Life.java @@ -121,25 +121,23 @@ public class Life{ height = _height; range = Range.create(width * height, 256); System.out.println("range = " + range); - - setExplicit(_mode.equals(Kernel.EXECUTION_MODE.GPU)); // This gives us a performance boost for GPU mode. - - fromBase = height * width; - toBase = 0; - Arrays.fill(imageData, LifeKernel.DEAD); - /** draw a line across the image **/ - for (int i = width * (height / 2) + width / 10; i < width * (height / 2 + 1) - width / 10; i++) { - imageData[toBase+i] = LifeKernel.ALIVE; - imageData[fromBase+i] = LifeKernel.ALIVE; - } - if (isExplicit()) { - put(imageData); // Because we are using explicit buffer management we must put the imageData array - } - - + + setExplicit(_mode.equals(Kernel.EXECUTION_MODE.GPU)); // This gives us a performance boost for GPU mode. + + fromBase = height * width; + toBase = 0; + Arrays.fill(imageData, LifeKernel.DEAD); + /** draw a line across the image **/ + for (int i = width * (height / 2) + width / 10; i < width * (height / 2 + 1) - width / 10; i++) { + imageData[toBase + i] = LifeKernel.ALIVE; + imageData[fromBase + i] = LifeKernel.ALIVE; + } + if (isExplicit()) { + put(imageData); // Because we are using explicit buffer management we must put the imageData array + } + } - - + @Override public void run() { int gid = getGlobalId(); int to = gid + toBase; @@ -187,7 +185,8 @@ public class Life{ static boolean running = false; static LifeKernel lifeKernel = null; - static double generationsPerSecondField =0; + + static double generationsPerSecondField = 0; public static void main(String[] _args) { @@ -204,8 +203,8 @@ public class Life{ final LifeKernel lifeKernelGPU = new LifeKernel(width, height, image, Kernel.EXECUTION_MODE.GPU); lifeKernel = lifeKernelJTP; - - final Font font = new Font ("Garamond", Font.BOLD , 100); + + final Font font = new Font("Garamond", Font.BOLD, 100); // Create a component for viewing the offsecreen image @SuppressWarnings("serial") JComponent viewer = new JComponent(){ @Override public void paintComponent(Graphics g) { @@ -229,7 +228,7 @@ public class Life{ g.drawImage(image, 0, 0, width, height, 0, height, width, 2 * height, this); } g.drawString(String.format("%5.2f", generationsPerSecondField), 20, 100); - + } } }; @@ -264,7 +263,7 @@ public class Life{ // } else if (item.equals(choices[0])) { lifeKernel = lifeKernelJTP; - + // modeButton = javaMandelBrot; } else if (item.equals(choices[1])) { lifeKernel = lifeKernelGPU; @@ -277,9 +276,9 @@ public class Life{ // controlPanel.add(new JLabel(lifeKernel.getExecutionMode().toString())); - // controlPanel.add(new JLabel(" Generations/Second=")); - // JLabel generationsPerSecond = new JLabel("0.00"); - // controlPanel.add(generationsPerSecond); + // controlPanel.add(new JLabel(" Generations/Second=")); + // JLabel generationsPerSecond = new JLabel("0.00"); + // controlPanel.add(generationsPerSecond); // Set the default size and add to the frames content pane viewer.setPreferredSize(new Dimension(width, height)); @@ -308,8 +307,8 @@ public class Life{ generations++; long now = System.currentTimeMillis(); if (now - start > 1000) { - generationsPerSecondField =(generations * 1000.0) / (now - start); - // generationsPerSecond.setText(String.format("%5.2f", generationsPerSecondField)); + generationsPerSecondField = (generations * 1000.0) / (now - start); + // generationsPerSecond.setText(String.format("%5.2f", generationsPerSecondField)); start = now; generations = 0; } diff --git a/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Mandel.java b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Mandel.java new file mode 100644 index 0000000000000000000000000000000000000000..a9143f443d3a208d57372292a6873c6f6c77367d --- /dev/null +++ b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/Mandel.java @@ -0,0 +1,293 @@ +/* +Copyright (c) 2010-2011, Advanced Micro Devices, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following +disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following +disclaimer in the documentation and/or other materials provided with the distribution. + +Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products +derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export +laws, including but not limited to the U.S. Export Administration Regulations ("EAR"), (15 C.F.R. Sections 730 through +774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, +you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of +Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration +Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1, +E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups +D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject +to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 +of EAR). For the most current Country Group listings, or for additional information about the EAR or your obligations +under those regulations, please refer to the U.S. Bureau of Industry and Security's website at http://www.bis.doc.gov/. + +*/ + +package com.amd.aparapi.examples.javaonedemo; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; +import java.awt.image.DataBufferInt; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JFrame; + +import com.amd.aparapi.Kernel; +import com.amd.aparapi.ProfileInfo; +import com.amd.aparapi.Range; + +/** + * An example Aparapi application which displays a view of the Mandelbrot set and lets the user zoom in to a particular point. + * + * When the user clicks on the view, this example application will zoom in to the clicked point and zoom out there after. + * On GPU, additional computing units will offer a better viewing experience. On the other hand on CPU, this example + * application might suffer with sub-optimal frame refresh rate as compared to GPU. + * + * @author gfrost + * + */ + +public class Mandel{ + + /** + * An Aparapi Kernel implementation for creating a scaled view of the mandelbrot set. + * + * @author gfrost + * + */ + + public static class MandelKernel extends Kernel{ + + /** RGB buffer used to store the Mandelbrot image. This buffer holds (width * height) RGB values. */ + final private int rgb[]; + + /** Mandelbrot image width. */ + final private int width; + + /** Mandelbrot image height. */ + final private int height; + + /** Maximum iterations for Mandelbrot. */ + final private int maxIterations = 64; + + /** Palette which maps iteration values to RGB values. */ + @Constant final private int pallette[] = new int[maxIterations + 1]; + + /** Mutable values of scale, offsetx and offsety so that we can modify the zoom level and position of a view. */ + private float scale = .0f; + + private float offsetx = .0f; + + private float offsety = .0f; + + /** + * Initialize the Kernel. + * + * @param _width Mandelbrot image width + * @param _height Mandelbrot image height + * @param _rgb Mandelbrot image RGB buffer + * @param _pallette Mandelbrot image palette + */ + public MandelKernel(int _width, int _height, int[] _rgb) { + //Initialize palette values + for (int i = 0; i < maxIterations; i++) { + float h = i / (float) maxIterations; + float b = 1.0f - h * h; + pallette[i] = Color.HSBtoRGB(h, 1f, b); + } + + width = _width; + height = _height; + rgb = _rgb; + + } + + @Override public void run() { + + /** Determine which RGB value we are going to process (0..RGB.length). */ + int gid = getGlobalId(); + + /** Translate the gid into an x an y value. */ + float x = (((gid % width * scale) - ((scale / 2) * width)) / width) + offsetx; + + float y = (((gid / height * scale) - ((scale / 2) * height)) / height) + offsety; + + int count = 0; + + float zx = x; + float zy = y; + float new_zx = 0f; + + // Iterate until the algorithm converges or until maxIterations are reached. + while (count < maxIterations && zx * zx + zy * zy < 8) { + new_zx = zx * zx - zy * zy + x; + zy = 2 * zx * zy + y; + zx = new_zx; + count++; + } + + // Pull the value out of the palette for this iteration count. + rgb[gid] = pallette[count]; + } + + public void setScaleAndOffset(float _scale, float _offsetx, float _offsety) { + offsetx = _offsetx; + offsety = _offsety; + scale = _scale; + } + + } + + /** User selected zoom-in point on the Mandelbrot view. */ + public static volatile Point to = null; + + @SuppressWarnings("serial") public static void main(String[] _args) { + + JFrame frame = new JFrame("MandelBrot"); + + /** Width of Mandelbrot view. */ + final int width = 768; + + /** Height of Mandelbrot view. */ + final int height = 768; + + /** Mandelbrot image height. */ + final Range range = Range.create(width * height); + + /** Image for Mandelbrot view. */ + final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + final BufferedImage offscreen = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + // Draw Mandelbrot image + JComponent viewer = new JComponent(){ + @Override public void paintComponent(Graphics g) { + + g.drawImage(image, 0, 0, width, height, this); + } + }; + + // Set the size of JComponent which displays Mandelbrot image + viewer.setPreferredSize(new Dimension(width, height)); + + final Object doorBell = new Object(); + + // Mouse listener which reads the user clicked zoom-in point on the Mandelbrot view + viewer.addMouseListener(new MouseAdapter(){ + @Override public void mouseClicked(MouseEvent e) { + to = e.getPoint(); + synchronized (doorBell) { + doorBell.notify(); + } + } + }); + + // Swing housework to create the frame + frame.getContentPane().add(viewer); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + // Extract the underlying RGB buffer from the image. + // Pass this to the kernel so it operates directly on the RGB buffer of the image + final int[] rgb = ((DataBufferInt) offscreen.getRaster().getDataBuffer()).getData(); + final int[] imageRgb = ((DataBufferInt) image.getRaster().getDataBuffer()).getData(); + // Create a Kernel passing the size, RGB buffer and the palette. + final MandelKernel kernel = new MandelKernel(width, height, rgb); + + float defaultScale = 3f; + + // Set the default scale and offset, execute the kernel and force a repaint of the viewer. + kernel.setScaleAndOffset(defaultScale, -1f, 0f); + kernel.execute(range); + + System.arraycopy(rgb, 0, imageRgb, 0, rgb.length); + viewer.repaint(); + + // Report target execution mode: GPU or JTP (Java Thread Pool). + System.out.println("Execution mode=" + kernel.getExecutionMode()); + + // Window listener to dispose Kernel resources on user exit. + frame.addWindowListener(new WindowAdapter(){ + public void windowClosing(WindowEvent _windowEvent) { + kernel.dispose(); + System.exit(0); + } + }); + + // Wait until the user selects a zoom-in point on the Mandelbrot view. + while (true) { + + // Wait for the user to click somewhere + while (to == null) { + synchronized (doorBell) { + try { + doorBell.wait(); + } catch (InterruptedException ie) { + ie.getStackTrace(); + } + } + } + + float x = -1f; + float y = 0f; + float scale = defaultScale; + float tox = (float) (to.x - width / 2) / width * scale; + float toy = (float) (to.y - height / 2) / height * scale; + + // This is how many frames we will display as we zoom in and out. + int frames = 128; + long startMillis = System.currentTimeMillis(); + for (int sign = -1; sign < 2; sign += 2) { + for (int i = 0; i < frames - 4; i++) { + scale = scale + sign * defaultScale / frames; + x = x - sign * (tox / frames); + y = y - sign * (toy / frames); + + // Set the scale and offset, execute the kernel and force a repaint of the viewer. + kernel.setScaleAndOffset(scale, x, y); + kernel.execute(range); + List<ProfileInfo> profileInfo = kernel.getProfileInfo(); + if (profileInfo != null && profileInfo.size() > 0) { + for (ProfileInfo p : profileInfo) { + System.out.print(" " + p.getType() + " " + p.getLabel() + " " + (p.getStart() / 1000) + " .. " + + (p.getEnd() / 1000) + " " + (p.getEnd() - p.getStart()) / 1000 + "us"); + } + System.out.println(); + } + + System.arraycopy(rgb, 0, imageRgb, 0, rgb.length); + viewer.repaint(); + } + } + + long elapsedMillis = System.currentTimeMillis() - startMillis; + System.out.println("FPS = " + frames * 1000 / elapsedMillis); + + // Reset zoom-in point. + to = null; + + } + + } + +} diff --git a/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/NBody.java b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/NBody.java index c903078e8f68c9df050196197fa17ec9674cf066..57777f21c5a02f2af96c6d0864b93437f62cf784 100644 --- a/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/NBody.java +++ b/examples/javaonedemo/src/com/amd/aparapi/examples/javaonedemo/NBody.java @@ -240,7 +240,7 @@ public class NBody{ caps.setHardwareAccelerated(true); final GLCanvas canvas = new GLCanvas(caps); - Dimension dimension = new Dimension(Integer.getInteger("width", 742-64), Integer.getInteger("height", 742-64)); + Dimension dimension = new Dimension(Integer.getInteger("width", 742 - 64), Integer.getInteger("height", 742 - 64)); canvas.setPreferredSize(dimension); canvas.addGLEventListener(new GLEventListener(){ @@ -348,7 +348,7 @@ public class NBody{ panel.add(canvas, BorderLayout.CENTER); frame.getContentPane().add(panel, BorderLayout.CENTER); final FPSAnimator animator = new FPSAnimator(canvas, 100); - + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true);