Hi,
to use the Java Libraries for the GUI, I decided to use JOCL. 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 (// without comment means that code is absent due to limited space for posts):
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_CLOSE);
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();
//
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]);
//
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()
{
//
}
private String readFile(String fileName)
{
//
}
@Override
public void mouseClicked(MouseEvent d) {
simulator.space.explode((double)d.getX() - 8, (double)d.getY() - 31);
}
//
}
}
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
)
{
//calculation, left out due to limited space in post
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!