mtchamengo / aparapi

Automatically exported from code.google.com/p/aparapi
Other
0 stars 0 forks source link

Running kernels multiple times on GPU fails #108

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Create a kernel and a run method. The kernel only increments an array value 
by one.
2. Run the kernel run method multiple times, i.e. 100.

What is the expected output? What do you see instead?

I'd expect the kernel to be run a 100 times with success, directly on the GPU 
without having to use a fallback. Instead, starting from the 24 run, I see 
fallbacks to JTP with the message:

initJNI failed to return a valid handle
!!!!!!! clCreateContextFromType() failed: device not available

What version of the product are you using? On what operating system?

The most recent one for download.

Please provide any additional information below, that is 
Aparapi_2013_01_23_windows_x86_64.zip.
The OpenCL implementation of Nvidia 4.2 is used.

Can you verify that problem?
Thanks,
Matthias Klass

Original issue reported on code.google.com by matthias.klass@gmail.com on 15 Apr 2013 at 7:58

Attachments:

GoogleCodeExporter commented 9 years ago
You are running out of OpenCL resources.  

The real issue is that you are forcing the bytcode of your kernel to be created 
each time you call ArrayIncrement.run(size) where you have this 

  ArrayIncrementKernel kernel = new ArrayIncrementKernel(inData, outData);
  kernel.execute(size);

Remember the first call to execute(int) on a new kernel instance (each of your 
are new) will cause bytecode to be converted to OpenCL.  Much better to 'reuse' 
the same kernel. 

BTW if you called kernel.dispose() after kernel.execute(size) above you would 
still be inefficient (slow!) but you would not run out of OpenCL resources.

My suggestion is to move the kernel creation out of this method, and just 
assign new arrays to the kernel each time. 

Something like this (hacked from your code) 

public class ArrayIncrement {
    public static class ArrayIncrementKernel extends Kernel {
        private int[] in;
        private int[] out;

        public void setArrays(int[] in, int[] out) {
            this.in = in;
            this.out = out;
        }

        @Override
        public void run() {
            int id = getGlobalId();
            out[id] = in[id] + 1;
        }
    }

    static ArrayIncrementKernel kernel = new ArrayIncrementKernel();

    public static boolean run(int size) {
        int[] inData = new int[size];
        int[] outData = new int[size];
        kernel.setArrays(inData, outData);
        kernel.execute(size);
        return(true);
    }

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(i);
            System.out.println(run(10));
        }
    }
} 

Original comment by frost.g...@gmail.com on 15 Apr 2013 at 3:00

GoogleCodeExporter commented 9 years ago

Original comment by frost.g...@gmail.com on 15 Apr 2013 at 3:01

GoogleCodeExporter commented 9 years ago
Hi,

thanks for your answer, this was exactly what I was looking for!

Matthias

Original comment by matthias.klass@gmail.com on 17 Apr 2013 at 1:45