PDA

View Full Version : JOCL - reading CL-Buffer fails



r00t
05-15-2011, 03:51 AM
Hi,
to use the Java Libraries for the GUI, I decided to use JOCL, kind of an OpenCL-binding for Java. The following code shows my work on a Java program using OpenCL for heavy calculation. Now my problem is the following: As I do not let the main program read out the CL-Buffer, the calculation seems to succes very fast. To let the main program show the results, I then told the program to read out the buffer, but (as I found out with console output) the program hangs up at the first command to do so. Here is the code:

main class:


package realv_1;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import javax.swing.*;

import static org.jocl.CL.*;

import org.jocl.*;

public class ROOT implements MouseListener{
private static final long serialVersionUID = 1L;

public BufferedImage image;
public JComponent root;
public Simulator simulator;
public double delta_t = 20;
public double buffer;
public double old_time;
public double new_time;
public boolean run;
public long fps_num;
public int SIZE_Y = 500;
public int SIZE_X = 500;
public double[] it = new double[]{1};
public int[] max_it;
public int[] rwidth;
public int[] rheight;
public int[] new_explosion;
public double[] new_exp_x;
public double[] new_exp_y;
public double[] cr, cg, cb;

//OpenCL

private cl_context context;
private cl_command_queue commandQueue;
private cl_kernel kernel;
private cl_mem[] memObjects;

//

public static void main(String[] args)
{
new ROOT();
}
public ROOT()
{
init();
}

public void init()
{
fps_num = 0;
run = true;
image = new BufferedImage(SIZE_X, SIZE_Y, BufferedImage.TYPE_INT_RGB);
JFrame frame = new JFrame("Explosion - Simulation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOS E);
frame.setLayout(new BorderLayout());
root = new JPanel()
{
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0,0,this);
}
};
root.setPreferredSize(new Dimension(SIZE_X, SIZE_Y));
root.setOpaque(false);
simulator = new Simulator(SIZE_X, SIZE_Y, this);

max_it = new int[]{ simulator.space.max_it };
rwidth = new int[]{ simulator.space.rwidth };
rheight = new int[]{ simulator.space.rheight };
new_explosion = new int[]{ simulator.space.new_explosion };
new_exp_x = new double[]{ simulator.space.new_exp_x };
new_exp_y = new double[]{ simulator.space.new_exp_y };
cr = new double[rwidth[0]*rheight[0]];
cg = new double[rwidth[0]*rheight[0]];
cb = new double[rwidth[0]*rheight[0]];

simulator.setOpaque(false);
root.add(simulator, "Sim");
frame.add(root, BorderLayout.WEST);
frame.setVisible(true);
frame.setBackground(Color.BLACK);
JPanel panel = new JPanel();
final JButton start_stop = new JButton("Pause");
start_stop.setPreferredSize(new Dimension(100, 40));
start_stop.addActionListener(new ActionListener()
{

@Override
public void actionPerformed(ActionEvent e)
{
if (run)
{
run = false;
start_stop.setText("Continue");
}
else
{
run = true;
start_stop.setText("Pause");
}
}
});
panel.add(start_stop);
frame.add(panel, BorderLayout.SOUTH);
frame.pack();
frame.addMouseListener(this);
updateImage();

//OpenCL

System.out.println("Obtaining platform...");
cl_platform_id platforms[] = new cl_platform_id[1];
clGetPlatformIDs(platforms.length, platforms, null);
cl_context_properties contextProperties = new cl_context_properties();
contextProperties.addProperty(CL_CONTEXT_PLATFORM, platforms[0]);

context = clCreateContextFromType(
contextProperties, CL_DEVICE_TYPE_GPU, null, null, null);
if (context == null)
{
context = clCreateContextFromType(
contextProperties, CL_DEVICE_TYPE_CPU, null, null, null);

if (context == null)
{
System.out.println("Unable to create a context");
System.exit(1);
return;
}
}

setExceptionsEnabled(true);

long numBytes[] = new long[1];
clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, null, numBytes);
int numDevices = (int) numBytes[0] / Sizeof.cl_device_id;
cl_device_id devices[] = new cl_device_id[numDevices];
clGetContextInfo(context, CL_CONTEXT_DEVICES, numBytes[0],
Pointer.to(devices), null);
cl_device_id device = devices[0];

commandQueue = clCreateCommandQueue(context, device, 0, null);

memObjects = new cl_mem[30];
memObjects[0] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_x), null);
memObjects[1] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_y), null);
memObjects[2] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_x), null);
memObjects[3] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_y), null);
memObjects[4] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.direction), null);
memObjects[5] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.speed), null);
memObjects[6] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.alive), null);
memObjects[7] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.wave), null);
memObjects[8] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.new_wave), null);
memObjects[9] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.cloud), null);
memObjects[10] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double, Pointer.to(it), null);
memObjects[11] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int, Pointer.to(max_it), null);
memObjects[12] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int, Pointer.to(rwidth), null);
memObjects[13] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int, Pointer.to(rheight), null);
memObjects[14] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int, Pointer.to(new_explosion), null);
memObjects[15] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double, Pointer.to(new_exp_x), null);
memObjects[16] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double, Pointer.to(new_exp_y), null);
memObjects[17] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, null, null);
memObjects[18] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, null, null);
memObjects[19] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[20] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[21] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, null, null);
memObjects[22] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * simulator.space.max_it, null, null);
memObjects[23] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[24] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[25] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[26] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_int * simulator.space.max_it, null, null);
memObjects[27] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * (rwidth[0] * rheight[0]), null, null);
memObjects[28] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * (rwidth[0] * rheight[0]), null, null);
memObjects[29] = clCreateBuffer(context,
CL_MEM_READ_WRITE,
Sizeof.cl_double * (rwidth[0] * rheight[0]), null, null);

String source = readFile("Calculation.cl");
cl_program cpProgram = clCreateProgramWithSource(context, 1,
new String[]{ source }, null, null);
clBuildProgram(cpProgram, 0, null, "-cl-mad-enable", null, null);
kernel = clCreateKernel(cpProgram, "calculate", null);
for (int cnt = 0; cnt < memObjects.length; cnt++)
{
clSetKernelArg(kernel, cnt,
Sizeof.cl_mem, Pointer.to(memObjects[cnt]));
}
final long global_work_size[] = new long[]{ 1 };
long local_work_size[] = new long[]{1};
//OpenCL end

new Thread()
{
public void run()
{
simulator.space.explode(250, 380);
while (true)
{
if (run)
{
old_time = (double)Calendar.getInstance().getTimeInMillis();

//calc
//simulator.update();

//OpenCL
clEnqueueNDRangeKernel(commandQueue, kernel, 2, null,
global_work_size, null, 0, null, null);
System.out.println("test");
//Here start problems, program seems to hang up at the following command:
clEnqueueReadBuffer(commandQueue, memObjects[17], CL_TRUE, 0,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_x), 0, null, null);
System.out.println("test2");
clEnqueueReadBuffer(commandQueue, memObjects[18], CL_TRUE, 0,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_y), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[19], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_x), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[20], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_y), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[21], CL_TRUE, 0,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.direction), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[22], CL_TRUE, 0,
Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.speed), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[23], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.alive), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[24], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.wave), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[25], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.new_wave), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[26], CL_TRUE, 0,
Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.cloud), 0, null, null);
//10 & 11 left out
new_explosion[0] = 0;
clEnqueueReadBuffer(commandQueue, memObjects[27], CL_TRUE, 0,
Sizeof.cl_double * (rwidth[0] * rheight[0]), Pointer.to(cr), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[28], CL_TRUE, 0,
Sizeof.cl_double * (rwidth[0] * rheight[0]), Pointer.to(cg), 0, null, null);
clEnqueueReadBuffer(commandQueue, memObjects[29], CL_TRUE, 0,
Sizeof.cl_double * (rwidth[0] * rheight[0]), Pointer.to(cb), 0, null, null);
//OpenCL end

fps_num++;
System.out.println(fps_num);
//simulator.info.update();
//calc end

new_time = (double)Calendar.getInstance().getTimeInMillis();
try
{
TimeUnit.MILLISECONDS.sleep(buffer());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
updateImage();
}
else
{
try
{
TimeUnit.MILLISECONDS.sleep(10);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
}.start();
}
public void updateImage()
{
for (int y = 0; y < simulator.rheight - 50; y++)
{
for (int x = 0; x < simulator.rwidth; x++)
{
int r = (int)Math.round(cr[y*simulator.rwidth+x]);
int g = (int)Math.round(cg[y*simulator.rwidth+x]);
int b = (int)Math.round(cb[y*simulator.rwidth+x]);
if (r > 255)
{
if (r < 510)
{
g = r % 255;
b = r % 255;
}
else
{
g = 255;
b = 255;
}
r = 255;
}
if (g > 255)
{
g = 255;
}
if (b > 255)
{
b = 255;
}
int rgb = (r<<16) + (g<<8) + b;
image.setRGB(x, y, rgb);
}
}
for (int y = simulator.rheight - 50; y < simulator.rheight; y++)
{
for (int x = 0; x < simulator.rwidth; x++)
{
image.setRGB(x, y, (200<<16)+(200<<8)+(200));
}
}
root.repaint();
}
public long buffer()
{
buffer = delta_t - (new_time - old_time);
if (buffer < 0)
{
return 0;
}
return (long)buffer;
}
private String readFile(String fileName)
{
try
{
BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(fileName)));
StringBuffer sb = new StringBuffer();
String line = null;
while (true)
{
line = br.readLine();
if (line == null)
{
break;
}
sb.append(line).append("\n");
}
return sb.toString();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
return null;
}
}
@Override
public void mouseClicked(MouseEvent d) {
simulator.space.explode((double)d.getX() - 8, (double)d.getY() - 31);
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub

}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub

}
@Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub

}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub

}
}

class space:


package realv_1;

public class Space {
public Simulator reference;
public double[] cor_x;
public double[] cor_y;
public int[] vs_cor_x;
public int[] vs_cor_y;
public double[] direction;
public double[] speed;
public int[] alive;
public int[] wave;
public int[] new_wave;
public int[] speed_decreased;
public int[] cloud;
public double it = 2;
public int max_it;
public double x_max;
public double y_max;
public int rwidth;
public int rheight;
public int new_explosion;
public double new_exp_x;
public double new_exp_y;

public Space(Simulator preference)
{
new_explosion = 0;
reference = preference;
x_max = reference.width*it;
y_max = (reference.height - 51)*it;
rwidth = (int)reference.width;
rheight = (int)reference.height;
max_it = (int)(x_max*y_max);
speed = new double[max_it];
direction = new double[max_it];
cor_x = new double[max_it];
cor_y = new double[max_it];
vs_cor_x = new int[max_it];
vs_cor_y = new int[max_it];
alive = new int[max_it];
wave = new int[max_it];
new_wave = new int[max_it];
speed_decreased = new int[max_it];
cloud = new int[max_it];
int cnt = 0;
for (int x = 0; x < x_max; x++)
{
for (int y = 0; y < y_max; y++)
{
cor_x[cnt] = x*(1/it);
cor_y[cnt] = y*(1/it);
vs_cor_x[cnt] = (int)Math.round(cor_x[cnt]);
vs_cor_y[cnt] = (int)Math.round(cor_y[cnt]);
alive[cnt] = 1;
wave[cnt] = 0;
new_wave[cnt] = 0;
speed_decreased[cnt] = 0;
cloud[cnt] = 0;
speed[cnt] = 0;
cnt++;
}
}
calc_vs_cor();
}
public void calc_vs_cor()
{
for (int x = 0; x < max_it; x++)
{
if (speed[x] > 0)
{
vs_cor_x[x] = (int)Math.round(cor_x[x]);
vs_cor_y[x] = (int)Math.round(cor_y[x]);
}
}
}
}

and at last the cl-file:


#pragma OPENCL EXTENSION cl_khr_fp64: enable
__kernel void calculate(
__global double cor_x[],
__global double cor_y[],
__global int vs_cor_x[],
__global int vs_cor_y[],
__global double direction[],
__global double speed[],
__global int alive[],
__global int wave[],
__global int new_wave[],
__global int cloud[],
__global double it[],
__global int max_it[],
__global int rwidth[],
__global int rheight[],
__global int new_explosion[],
__global double new_exp_x[],
__global double new_exp_y[],

__global double *new_cor_x,
__global double *new_cor_y,
__global double *new_vs_cor_x,
__global double *new_vs_cor_y,
__global double *new_direction,
__global double *new_speed,
__global int *new_alive,
__global int *new1_wave,
__global int *new1_new_wave,
__global int *new_cloud,
__global double *cr,
__global double *cg,
__global double *cb
)
{
if (new_explosion[0] == 1)
{
double px, py;
px = new_exp_x[0];
py = new_exp_y[0];
for (int x = 0; x < max_it[0]; x++)
{
double d = sqrt((px - cor_x[x]) * (px - cor_x[x]) + (py - cor_y[x]) * (py - cor_y[x]));
if (37 < d && d < 50)
{
wave[x] = 1;
cloud[x] = 0;
double dy = py - cor_y[x];
double dx = px - cor_x[x];
direction[x] = asin(dy / d);
if (dy >= 0 && dx > 0)
{
direction[x] = M_PI - direction[x];
}
if (dy < 0 && dx > 0)
{
direction[x] = M_PI - direction[x];
}
while (direction[x] >= M_PI * 2)
{
direction[x] -= (M_PI * 2);
}
speed[x] = 0.6;
}
else if (d <= 37)
{
cloud[x] = 1;
wave[x] = 0;
direction[x] = M_PI / 2;
speed[x] = 0.0125;
}
}
new_explosion = 0;
}
for (int x = 0; x < max_it[0]; x++)
{
if (new_wave[x] == 1)
{
wave[x] = 1;
new_wave[x] = 0;
}
if (speed[x] > 0 && alive[x] == 1)
{
while (direction[x] < 0)
{
direction[x] += M_PI * 2;
}
while (direction[x] >= M_PI * 2)
{
direction[x] -= (M_PI * 2);
}
if (cor_y[x] >= (rheight[0] - 51) && cor_x[x] <= (rwidth[0] - 1) && cor_x[x] >= 0
&& direction[x] > M_PI && direction[x] < (M_PI * 2) )
{
direction[x] = M_PI - (direction[x] - M_PI);
while (direction[x] < 0)
{
direction[x] += M_PI * 2;
}
while (direction[x] >= M_PI * 2)
{
direction[x] -= (M_PI * 2);
}
speed[x] *= 1.5;
}
double delta_x, delta_y;
delta_y = - sin(direction[x]) * speed[x];
delta_x = cos(direction[x]) * speed[x];
cor_x[x] += delta_x;
cor_y[x] += delta_y;
if (wave[x] == 1)
{
speed[x] *= 0.99999;
}
else if (cloud[x] == 1 && speed[x] < 0.4)
{
speed[x] *= 1.01;
}
if (cor_x[x] < 0 || cor_x[x] >= (rwidth[0] - 1) || cor_y[x] < 0 || cor_y[x] >= (rheight[0] - 45) )
{
speed[x] = 0;
alive[x] = 0;
}
}
if (speed[x] > 0 && alive[x] == 1)
{
vs_cor_x[x] = (int)round(cor_x[x]);
vs_cor_y[x] = (int)round(cor_y[x]);
if (wave[x] == 1)
{
cb[(int)(vs_cor_y[x]*rwidth[0] + vs_cor_x[x])] += speed[x] * 100;
}
else if (cloud[x] == 1)
{
cr[(int)(vs_cor_y[x]*rwidth[0] + vs_cor_x[x])] += speed[x] + 100;
}
}
}
double dx, dy, d;
for (int x = 0; x < max_it[0]; x++)
{
if (wave[x] == 1)
{
for (int y = 0; y < max_it[0]; y++)
{
if (wave[y] == 0 && cloud[y] == 0)
{
dx = cor_x[x] - cor_x[y];
dy = cor_y[x] - cor_y[y];
d = sqrt((dx * dx) + (dy * dy));
if (d < 0.125)
{
speed[x] *= 0.99;
direction[y] = direction[x];
speed[y] = speed[x];
new_wave[y] = 1;
}
}
}
}
}
new_cor_x = cor_x;
new_cor_y = cor_y;
new_vs_cor_x = vs_cor_x;
new_vs_cor_y = vs_cor_y;
new_direction = direction;
new_speed = speed;
new_alive = alive;
new1_wave = wave;
new1_new_wave = new_wave;
new_cloud = cloud;
}

Thanks for reading so far, any help is welcome!

r00t
05-15-2011, 05:53 AM
http://www.java-forum.org/allgemeine-ja ... post761623 (http://www.java-forum.org/allgemeine-java-themen/118147-jocl-auslesen-cl-buffers-funktioniert.html#post761623)