Package com.jogamp.opencl

Source Code of com.jogamp.opencl.CLProgramTest

/*
* Copyright 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
*    1. Redistributions of source code must retain the above copyright notice, this list of
*       conditions and the following disclaimer.
*
*    2. 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.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``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 JogAmp Community 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.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/

package com.jogamp.opencl;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opencl.CLWork.CLWork1D;
import com.jogamp.opencl.util.CLBuildConfiguration;
import com.jogamp.opencl.util.CLProgramConfiguration;
import com.jogamp.opencl.CLProgram.Status;
import com.jogamp.opencl.util.CLBuildListener;
import com.jogamp.opencl.llb.CL;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import static org.junit.Assert.*;
import static java.lang.System.*;
import static com.jogamp.opencl.CLProgram.CompilerOptions.*;
import static com.jogamp.opencl.util.CLPlatformFilters.*;
import static com.jogamp.opencl.CLVersion.*;

/**
*
* @author Michael Bien
*/
public class CLProgramTest {

    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();


    @Test
    public void enumsTest() {

        // CLProgram enums
        for (Status e : Status.values()) {
            assertEquals(e, Status.valueOf(e.STATUS));
        }
    }

    @Test
    public void rebuildProgramTest() throws IOException {

        out.println(" - - - CLProgramTest; rebuild program test - - - ");

        CLContext context = CLContext.create();
        CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl"));

        try{
            program.createCLKernels();
            fail("expected exception but got none :(");
        }catch(CLException ex) {
            out.println("got expected exception:  "+ex.getCLErrorString());
            assertEquals(ex.errorcode, CL.CL_INVALID_PROGRAM_EXECUTABLE);
        }

        out.println(program.getBuildStatus());
        program.build();
        out.println(program.getBuildStatus());

        assertTrue(program.isExecutable());

        CLKernel kernel = program.createCLKernel("VectorAddGM");
        assertNotNull(kernel);

        // rebuild
        // 1. release kernels (internally)
        // 2. build program
        program.build();
        assertTrue(program.isExecutable());
        out.println(program.getBuildStatus());

        // try again with rebuilt program
        kernel = program.createCLKernel("VectorAddGM");
        assertNotNull(kernel);

        context.release();
    }

    @Test
    public void programBinariesTest() throws IOException {

        out.println(" - - - CLProgramTest; down-/upload binaries test - - - ");

        CLContext context = CLContext.create();
        CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl"))
                                   .build(ENABLE_MAD, WARNINGS_ARE_ERRORS);

        // optain binaries
        Map<CLDevice, byte[]> binaries = program.getBinaries();
        assertFalse(binaries.isEmpty());

        CLDevice[] devices = program.getCLDevices();
        for (CLDevice device : devices) {
            assertTrue(binaries.containsKey(device));
        }

        // 1. release program
        // 2. re-create program with old binaries
        program.release();

        assertFalse(program.isExecutable());

        assertNotNull(program.getBinaries());
        assertEquals(program.getBinaries().size(), 0);

        assertNotNull(program.getBuildLog());
        assertEquals(program.getBuildLog().length(), 0);

        assertNotNull(program.getSource());
        assertEquals(program.getSource().length(), 0);

        assertNotNull(program.getCLDevices());
        assertEquals(program.getCLDevices().length, 0);

        {
            Map<String, CLKernel> kernels = program.createCLKernels();
            assertNotNull(kernels);
            assertEquals(kernels.size(), 0);
        }
        assertNull(program.createCLKernel("foo"));

        program = context.createProgram(binaries);

        assertFalse(program.isExecutable());

        assertNotNull(program.getCLDevices());
        assertTrue(program.getCLDevices().length != 0);

        assertNotNull(program.getBinaries());
        assertEquals(program.getBinaries().size(), 0);

        assertNotNull(program.getBuildLog());
        assertTrue(program.getBuildLog().length() != 0);

        assertNotNull(program.getSource());
        assertEquals(program.getSource().length(), 0);

        try{
            Map<String, CLKernel> kernels = program.createCLKernels();
            fail("expected an exception from createCLKernels but got: "+kernels);
        }catch(CLException ex) {
            // expected, not build yet
        }

        out.println(program.getBuildStatus());
        program.build();
        out.println(program.getBuildStatus());

        assertNotNull(program.createCLKernel("Test"));

        assertTrue(program.isExecutable());

        context.release();

    }

    @Test
    public void builderTest() throws IOException, ClassNotFoundException, InterruptedException {
        out.println(" - - - CLProgramTest; program builder test - - - ");

        CLContext context = CLContext.create();
        CLProgram program = context.createProgram(getClass().getResourceAsStream("testkernels.cl"));

        // same as program.build()
        program.prepare().build();

        assertTrue(program.isExecutable());


        // complex build
        program.prepare().withOption(ENABLE_MAD)
                         .forDevice(context.getMaxFlopsDevice())
                         .withDefine("RADIUS", 5)
                         .withDefine("ENABLE_FOOBAR")
                         .build();

        assertTrue(program.isExecutable());

        // reusable builder
        CLBuildConfiguration builder = CLProgramBuilder.createConfiguration()
                                     .withOption(ENABLE_MAD)
                                     .forDevices(context.getDevices())
                                     .withDefine("RADIUS", 5)
                                     .withDefine("ENABLE_FOOBAR");

        out.println(builder);

        // async build test
        {
            final CountDownLatch countdown = new CountDownLatch(1);
            final CLProgram outerProgram = program;

            CLBuildListener buildCallback = new CLBuildListener() {
                @Override
                public void buildFinished(CLProgram program) {
                    assertEquals(outerProgram, program);
                    countdown.countDown();
                }
            };

            builder.setProgram(program).build(buildCallback);
            countdown.await();
        }

        assertTrue(program.isExecutable());

        // serialization test
        File file = tmpFolder.newFile("foobar.builder");
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
        builder.save(oos);
        oos.close();

        // build configuration
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        CLBuildConfiguration buildConfig = CLProgramBuilder.loadConfiguration(ois);
        ois.close();

        assertEquals(builder, buildConfig);

        buildConfig.build(program);
        assertTrue(program.isExecutable());

        // program configuration
        ois = new ObjectInputStream(new FileInputStream(file));
        CLProgramConfiguration programConfig = CLProgramBuilder.loadConfiguration(ois, context);
        assertNotNull(programConfig.getProgram());
        ois.close();
        program = programConfig.build();
        assertTrue(program.isExecutable());


        // cloneing
        assertEquals(builder, builder.clone());

        context.release();
    }


    @Test
    public void kernelTest() {

        String source = "__attribute__((reqd_work_group_size(1, 1, 1))) kernel void foo(float a, int b, short c) { }\n";

        CLContext context = CLContext.create();

        try{
            CLProgram program = context.createProgram(source).build();
            assertTrue(program.isExecutable());

            CLKernel kernel = program.createCLKernel("foo");
            assertNotNull(kernel);

            long[] wgs = kernel.getCompileWorkGroupSize(context.getDevices()[0]);

            out.println("compile workgroup size: " + wgs[0]+" "+wgs[1]+" "+wgs[2]);

            assertEquals(1, wgs[0]);
            assertEquals(1, wgs[1]);
            assertEquals(1, wgs[2]);

            // put args test
            assertEquals(0, kernel.position());

            kernel.putArg(1.0f);
            assertEquals(1, kernel.position());

            kernel.putArg(2);
            assertEquals(2, kernel.position());

            kernel.putArg((short)3);
            assertEquals(3, kernel.position());
           
            try{
                kernel.putArg(3);
                fail("exception not thrown");
            }catch (IndexOutOfBoundsException expected){ }

            assertEquals(3, kernel.position());
            assertEquals(0, kernel.rewind().position());

        }finally{
            context.release();
        }

    }

    @Test
    public void kernelVectorArgsTest() {

        String source =
                "kernel void vector(global float * out,\n"
              + "                   const float v1,\n"
              + "                   const float2 v2,\n"
              + "//                   const float3 v3,\n" // nv does not support float3
              + "                   const float4 v4,\n"
              + "                   const float8 v8) {\n"
              + "    out[0] = v1;\n"

              + "    out[1] = v2.x;\n"
              + "    out[2] = v2.y;\n"

              + "    out[3] = v4.x;\n"
              + "    out[4] = v4.y;\n"
              + "    out[5] = v4.z;\n"
              + "    out[6] = v4.w;\n"

              + "    out[ 7] = v8.s0;\n"
              + "    out[ 8] = v8.s1;\n"
              + "    out[ 9] = v8.s2;\n"
              + "    out[10] = v8.s3;\n"
              + "    out[11] = v8.s4;\n"
              + "    out[12] = v8.s5;\n"
              + "    out[13] = v8.s6;\n"
              + "    out[14] = v8.s7;\n"
              + "}\n";

        CLContext context = CLContext.create();

        try{
            CLProgram program = context.createProgram(source).build();
            CLKernel kernel = program.createCLKernel("vector");

            CLBuffer<FloatBuffer> buffer = context.createFloatBuffer(15, CLBuffer.Mem.WRITE_ONLY);
           
            final int seed = 7;
            Random rnd = new Random(seed);
           
            kernel.putArg(buffer);
            kernel.putArg(rnd.nextFloat());
            kernel.putArg(rnd.nextFloat(), rnd.nextFloat());
//            kernel.putArg(rnd.nextFloat(), rnd.nextFloat(), rnd.nextFloat()); // nv does not support float3
            kernel.putArg(rnd.nextFloat(), rnd.nextFloat(), rnd.nextFloat(), rnd.nextFloat());
            kernel.putArg(TestUtils.fillBuffer(Buffers.newDirectFloatBuffer(8), seed));

            CLCommandQueue queue = context.getMaxFlopsDevice().createCommandQueue();
            queue.putTask(kernel).putReadBuffer(buffer, true);

            FloatBuffer out = buffer.getBuffer();

            rnd = new Random(seed);
            for(int i = 0; i < 7; i++) {
                assertEquals(rnd.nextFloat(), out.get(), 0.01f);
            }

            rnd = new Random(seed);
            for(int i = 0; i < 8; i++) {
                assertEquals(rnd.nextFloat(), out.get(), 0.01f);
            }

        }finally{
            context.release();
        }

    }

    @Test
    public void createAllKernelsTest() {
       
        String source = "kernel void foo(int a) { }\n"+
                        "kernel void bar(float b) { }\n";

        CLContext context = CLContext.create();
        try{
            CLProgram program = context.createProgram(source).build();
            assertTrue(program.isExecutable());

            Map<String, CLKernel> kernels = program.createCLKernels();
            for (CLKernel kernel : kernels.values()) {
                out.println("kernel: "+kernel.toString());
            }

            assertNotNull(kernels.get("foo"));
            assertNotNull(kernels.get("bar"));

            kernels.get("foo").setArg(0, 42);
            kernels.get("bar").setArg(0, 3.14f);


        }finally{
            context.release();
        }

    }

    @Test
    public void workTest() throws IOException {

        CLContext context = CLContext.create(CLPlatform.getDefault(version(CL_1_1)));

        try{
            CLProgram program = context.createProgram(CLProgramTest.class.getResourceAsStream("testkernels.cl")).build();

            CLDevice device = context.getMaxFlopsDevice();
            out.println(device);
            CLCommandQueue queue = device.createCommandQueue();

            CLBuffer<IntBuffer> buffer = context.createIntBuffer(20);

            CLWork1D work = CLWork.create1D(program.createCLKernel("add"));
            work.getKernel().setArgs(buffer, 5, buffer.getNIOCapacity());

            //optimal values
            work.setWorkSize(20, 1).optimizeFor(device);
            assertEquals(work.workSize.get(0), 20);
            assertNotSame(work.groupSize.get(0), 0);

            queue.putWriteBuffer(buffer, false)
                 .putWork(work)
                 .putReadBuffer(buffer, true);

            while(buffer.getBuffer().hasRemaining()) {
                assertEquals(5, buffer.getBuffer().get());
            }
            buffer.getBuffer().rewind();

            // driver choice
            work.setWorkSize(20);
            assertEquals(work.workSize.get(0), 20);
            assertEquals(work.groupSize.get(0), 0);

            queue.putWriteBuffer(buffer, false)
                 .putWork(work)
                 .putReadBuffer(buffer, true);

            while(buffer.getBuffer().hasRemaining()) {
                assertEquals(10, buffer.getBuffer().get());
            }
            buffer.getBuffer().rewind();

        }finally{
            context.release();
        }

    }

//    @Test
    public void loadTest() throws IOException, ClassNotFoundException, InterruptedException {
        for(int i = 0; i < 100; i++) {
            rebuildProgramTest();
            builderTest();
            programBinariesTest();
        }
    }

}
TOP

Related Classes of com.jogamp.opencl.CLProgramTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.