JOCL - Auslesen des CL-Buffers funktioniert nicht

r00t

Mitglied
Guten Morgen!

Der nachfoldende Code bleibt beim Auslesen des CL-Buffers ohne Rückmeldung stehen, zur Anbindung an OpenCL kommt JOCL zum Einsatz. Um die betroffene Zeile erfolgen zwei Test-Konsolenausgaben, von denen nur die erste erscheint, während das Programm beim Auslesen der ersten Variabel aus dem CL-Buffer scheinbar endlos verharrt. Die Ausführung des Kernels scheint allerdings erfolgreich, die GPU-Last steigt auf 98% und die nachfolgende Ausgabe erfolgt. Lösungsvorschläge jeder Art willkommen! Anbei der Code:

Steuerklasse
Java:
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];
        //Input-Variabeln
        memObjects[0] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY,
        	    Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_x), null);
        memObjects[1] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY,
        	    Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.cor_y), null);
        memObjects[2] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_x), null);
        memObjects[3] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.vs_cor_y), null);
        memObjects[4] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.direction), null);
        memObjects[5] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_double * simulator.space.max_it, Pointer.to(simulator.space.speed), null);
        memObjects[6] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.alive), null);
        memObjects[7] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.wave), null);
        memObjects[8] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.new_wave), null);
        memObjects[9] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int * simulator.space.max_it, Pointer.to(simulator.space.cloud), null);
        memObjects[10] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_double, Pointer.to(it), null);
        memObjects[11] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int, Pointer.to(max_it), null);
        memObjects[12] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int, Pointer.to(rwidth), null);
        memObjects[13] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int, Pointer.to(rheight), null);
        memObjects[14] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_int, Pointer.to(new_explosion), null);
        memObjects[15] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_double, Pointer.to(new_exp_x), null);
        memObjects[16] = clCreateBuffer(context, 
        		CL_MEM_READ_ONLY, 
        	    Sizeof.cl_double, Pointer.to(new_exp_y), null);
        //Output-Variablen
        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");
					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
		
	}
}

Klasse "Space"
Java:
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 explode(double px, double py)
	{
		new_explosion = 1;
		new_exp_x = px;
		new_exp_y = py;
	}
        }
}

Und schlussendlich der OpenCL-File:
Java:
#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;
}

Vielen Dank fürs lesen soweit, jede Hilfe ist willkommen! Falls Bedarf besteht, das Programm zu kompilieren, muss ggf beim Import der cl-Datei der gesamte Dateipfad angegeben werden.
 
Zuletzt bearbeitet:

Marco13

Top Contributor
Woh-ho... Wo soll man da anfangen? 30 Kernel-Parameter, 30 cl_mem's, nur 1 Thread ... und insgesamt Fehlerpotential ohne Ende ;)

Vielleicht ein paar Punkte nach dem ersten groben (!) überfliegen: Man kann auch Werte an einen Kernel übergeben, die NICHT als cl_mems vorliegen: Wenn man einen int oder double an einen kernel übergeben will, der vom Kernel nur gelesen werden soll (und ich schätze, das sind hier einige...) dann kann man einfach sowas schreiben wie
clSetKernelArg(kernel, cnt, Sizeof.cl_int, Pointer.to(new int[]{maxIter}));

Vermutlich gibt's auch ein Problem, weil du den Kernel mit
clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, global_work_size, null, 0, null, null).
als 2D spezifizierst, aber nur EINE global work size übergibst. Wundert mich, dass es da nicht gleich kracht...

Außerdem spezifizierst du den global- und local work size als jeweils '1'. Das ganze wird also nur mit einem Thread ausgeführt. OpenCL macht nicht viel Sinn wenn man nur einen Thread verwendet.

Innerhalb des Kernels wird auch überall davon ausgegangen, dass mit nur einem einzigen Thread gearbeitet wird. Falls du irgendein zeitkritisches Problem hast, und dann gedacht hast: "Super, ich portier' das 1:1 nach OpenCL, dann ist es schneller" : So funktioniert das nicht. Parallele Programmierung auf dieser Ebene ist (wenn man "hohe Ziele" hat) eine Wissenschaft für sich, aber selbst in der einfachsten Form (wo sie auch schon eine Menge bringen kann!) muss man sich überlegen, welche Teile seines Problems wirklich daten-parallel sind. Vereinfacht gesagt: OpenCL (oder CUDA oder ähnliche Techniken) machen dann Sinn, wenn man ein Problem so beschreiben kann, dass ein paar tausend Threads wirklich das gleiche(!) machen - aber einfach auf unterschiedlichen Teilen der Daten. Das klassische Beispiel: Zwei Arrays mit 1000 Elementen addieren geht mit OpenCL super:
Code:
int index = get_global_id(0);
result[index] = input0[index]+input1[index];
(das bringt nicht so viel, weil nicht viel gerechnet wird, ist aber ein Beispiel für Daten-Parallele Aufgaben). Im Vergleich dazu: Die Summe eines Arrays auf "naive" Art zu berechnen
Code:
int sum = 0;
for (int i=0; i<1000; i++) sum += input[i];
(und das ganze gestartet mit einem einzigen Thread) wird mit OpenCL sicher deutlich langsamer sein als mit Java.
(BTW: Auch diese Aufgabe, die Summe eines Arrays zu berechnen, kann man parallelisieren - obwohl man intuitiv meinen könnte, es wäre eine inhärent sequentielle Aufgabe. Mehr dazu steht in dieser PDF-Datei - wie gesagt, es kann eine Wissenschaft für sich sein ;) )

Zu (vorerst) guter Letzt: Am Ende des Kernels steht sowas wie
new_cor_x = cor_x;
Dort wird ein Zeiger einem anderen Zeiger zugewiesen. Was auch immer damit erreicht werden sollte: Es wird nicht funktionieren...

Eine allgemeine Empfehlung: Der Kernel scheint (nochmal, nur nach dem ersten Überfliegen) aus drei Teilen zu bestehen, die alle in einer
for (int x = 0; x < max_it[0]; x++)
Schleife stehen. Du könntest in Erwägung ziehen, das in drei Kernel aufzuteilen - vielleicht würde das schonmal einiges übersichtlicher machen, und den Parameter-Wust etwas reduzieren...

Die eigentliche Herausforderung, innerhalb dieser Kernels dann die daten-parallelen Teile zu identifizieren und richtig zu implementieren besteht aber nach wie vor. Eine Iteration an sich ist schwer (bzw. unmöglich) zu parallelisieren, sofern die Iteration nicht auf einzelnen Datenelementen (jeweils unabhängig von allen anderen Datenelementen, also parallel auf allen Datenelementen) ablaufen kann.

Vielleicht kann ich das ganze bei Gelegenheit mal testen, aber im Moment sind da noch so viele ":exclaim:"'s und ":question:"'s drin, dass ich kaum glaube, dass die Suche nach einer Lösung für das vordergründige Problem (blockierendes Buffer-Lesen) dir wirklich viel weiter helfen würde...
 

r00t

Mitglied
Vielen Dank für die ausführliche und ehrliche Antwort! Nachdem ich aus der 2 ne 1 gemacht habe läuft das Programm schon ma, zwar bleibt das Fenster schwarz aber das ist an dieser Stelle auch egal. Den Code zur Initialisierung des Kernels kann man wohl gut als abschreckendes Beispiel zu Lehrzwecken verwenden^^, sowas kommt dabei raus wenn man sich in die Schlacht stürzt ohne das Handbuch gelesen zu haben :) Wenigstens hab ich dann noch was zu tun für die Sommerferien, und vielen Dank noch mal!
 

Marco13

Top Contributor
Hmja, alle cl_mems so "namenlos" in ein Array zu packen ist nicht so übersichtlich. Ich weiß, dass ich bei dem "Vector Add" Beispiel so was ähnliches mit drei cl_mems gemacht hatte, aber bei den neuern Beispielen versuch(t)e ich schon, den Dingern "sprechendere" Namen zu geben, im Sinne von
Code:
private int [b]input[/b][];
private cl_mem [b]input[/b]Mem;

private float [b]output[/b][];
private cl_mem [b]output[/b]Mem;
oder so...
 

r00t

Mitglied
Wäre es auch möglich ohne outputMem zu arbeiten, bspw.:
zeiger auf original-Werte in inputMem, Kernel übernimmt inputMem, rechent und verändert inputMem, verändertes inputMem wird ausgelesen & original-werte werden mit inputMem überschrieben ?
Das würde schon mal die Zuweisung am Ende (new_cor_x = cor_x etc) überflüssig machen.
 

Marco13

Top Contributor
Dazu müßte ich den Kernel jetzt mehr im Detail nachvollziehen. Es KANN gehen: Wenn man z.B. in einem Array einfach jeden Wert verdoppeln will, kann man durchaus sowas machen wie
Code:
__kernel void calculate( __global double *inputAndOutput){
    int i = get_global_id(0);
    inputAndOutput[i] *= 2;
}
Aber bedenke, dass das u.U. für alle Array-Indizes gleichzeitig ausgeführt wird - also sowas wie
Code:
__kernel void calculate( __global double *inputAndOutput){
    int i = get_global_id(0);
    inputAndOutput[i+1] = inputAndOutput[i];
}
würde komplettes Datenchaos liefern, weil array und array[i+1] u.U. gleichzeitig gelesen und geschrieben werden.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
E Erste Schritte JOCL in Eclipse Allgemeine Java-Themen 5
L Input/Output Email mit großer Pdf Anhang auslesen? Allgemeine Java-Themen 6
Ernesto95 HTTP Mit JavaScript erzeugte dynamische Webseite auslesen und nach einem Schlüsselwort durchsuchen Allgemeine Java-Themen 6
K Bildschirm auslesen/ Text erkennen Allgemeine Java-Themen 5
torresbig Url nach Webseiten-Login auslesen & Daten an Webseite senden Allgemeine Java-Themen 9
S .exe Datei/Programm auslesen? Allgemeine Java-Themen 2
T INI - Einträge auslesen Allgemeine Java-Themen 6
H Auslesen eines (LDAP-)Attributs in Active Directory Allgemeine Java-Themen 2
O PDF auslesen und verändern, was ist besser iText oder PDFBox ? Allgemeine Java-Themen 9
Robertop Status von Caps- und NumLock auslesen Allgemeine Java-Themen 1
Master3000 Java Konsole über Buffered Reader Zeilenweise auslesen ? Allgemeine Java-Themen 26
G Mac Package auslesen Allgemeine Java-Themen 17
W Versionsnummer auslesen - Regex ist zickig Allgemeine Java-Themen 2
F Junit Test + Cucumber - JSON auslesen und in einem weiteren Schritt nutzen Allgemeine Java-Themen 0
M verschiedene Dokumente auslesen Allgemeine Java-Themen 1
Gaudimagspam CSV-Datei auslesen in Java Allgemeine Java-Themen 7
L Dateien richtig auslesen Allgemeine Java-Themen 6
F WireGuard Status auslesen Allgemeine Java-Themen 3
B .txt Datei erstellen und auslesen bzw. schreiben Allgemeine Java-Themen 6
I DOM-Parser - Element im Element an bestimmten Stellen auslesen Allgemeine Java-Themen 1
N Txt Datei auslesen. Allgemeine Java-Themen 5
O xlsx Datei auslesen mit POI Apache liest keine LEERZELLEN Allgemeine Java-Themen 6
O xlsx Datei auslesen mit POI von Apache wirft seltsamen Fehler. Allgemeine Java-Themen 11
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
V EMail, Attachments auslesen von einer Email Allgemeine Java-Themen 0
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
E CSV mit Text und Binärdaten auslesen Allgemeine Java-Themen 7
x46 Webseite in Java auslesen Allgemeine Java-Themen 2
M Html Seite auslesen Allgemeine Java-Themen 16
S Hilfe bei dem Auslesen einer YAML Datei Allgemeine Java-Themen 8
J Fenstergröße eines anderen Programmes auslesen Allgemeine Java-Themen 9
B Cookie auslesen Allgemeine Java-Themen 3
B Input/Output Programm zum Auslesen/Beschreiben von Textdateien, wie Geschwindigkeit erhöhen? Allgemeine Java-Themen 18
J Variablen Mehrere int-variablen in txt abspeichern und danach wieder auslesen Allgemeine Java-Themen 1
J Daten aus Website-Quelltext auslesen Allgemeine Java-Themen 62
J Teil einer URL auslesen Allgemeine Java-Themen 13
denny86 NetBeans Ordnernamen rekursiv auslesen und in Variable verarbeiten Allgemeine Java-Themen 38
C Atfx mit Hilfe von OpenAtfx auslesen Allgemeine Java-Themen 1
C Position von Pixeln in Bilder auslesen Allgemeine Java-Themen 2
M aktive WLAN Teilnehmer auslesen? Allgemeine Java-Themen 6
X JSONObject auslesen und in HashMap hinterlegen Allgemeine Java-Themen 16
S Kann man mit Java auf einem lokalen PC/Mac Benutzergruppen auslesen und Rechte ändern? Allgemeine Java-Themen 11
C Webseite auslesen Allgemeine Java-Themen 3
D Best Practice Gesamten Bildschirminhalt auslesen und Email schicken sobald kein Pixel sich ändert Allgemeine Java-Themen 11
A Erste Schritte Daten aus einer Website auslesen Allgemeine Java-Themen 7
J Bestimmte Zeile aus Textdatei auslesen Allgemeine Java-Themen 18
G Aus JTextField Zahlen auslesen und random generieren Allgemeine Java-Themen 10
M Tastatureingabe von Sondertasten auslesen Allgemeine Java-Themen 6
C Auslesen auslösen über Button-Click Allgemeine Java-Themen 8
M xlsx File auslesen Exception occured Allgemeine Java-Themen 13
U OOP Warum kann ich aus meiner Methode keinen String auslesen Allgemeine Java-Themen 4
J Auslesen Daten Java/HTML Allgemeine Java-Themen 15
4a61766120617274697374 PDF iText Wort Koordinaten auslesen Allgemeine Java-Themen 1
KeVoZ_ Bestimmte Zeile aus Console finden & auslesen Allgemeine Java-Themen 2
T Url aus txt Datei auslesen und öffnen? Allgemeine Java-Themen 4
N Werte aus Hashmap auslesen und übertragen Allgemeine Java-Themen 8
KeVoZ_ Properties mit String auslesen Allgemeine Java-Themen 11
I HTML einer Website auslesen liefert nur head Allgemeine Java-Themen 6
D Aktuell installierte Java Version auslesen unter Windows Allgemeine Java-Themen 5
M Parameter auslesen im Servlet Allgemeine Java-Themen 0
M Input/Output USB Geräteinstanzkennung auslesen Allgemeine Java-Themen 3
W 2D-Grafik Erstellungsdatum JPG direkt aus Header (EXIF) auslesen. Allgemeine Java-Themen 5
M Daten aus anderen Programmen auslesen Allgemeine Java-Themen 2
T Datei Byteweise auslesen Allgemeine Java-Themen 1
T Datentypen MNIST Datenbank auslesen (.gz) Allgemeine Java-Themen 0
T Ini Datei auslesen Allgemeine Java-Themen 3
J Temperatur aus bytes auslesen. Allgemeine Java-Themen 13
I JSoup Class auslesen Allgemeine Java-Themen 1
Bluedaishi Textdateien auslesen Allgemeine Java-Themen 12
T ELM327 OBD2 auslesen Allgemeine Java-Themen 0
D Double aus String auslesen Allgemeine Java-Themen 8
Z Zahlen aus Bild auslesen Allgemeine Java-Themen 1
A interaktives PDF auslesen/auswerten? Allgemeine Java-Themen 0
G Daten aus Website auslesen Allgemeine Java-Themen 7
S CSV Eintrag der nächsten Zeile auslesen funktioniert nicht Allgemeine Java-Themen 8
I Java FX JsonObjekt Children auslesen Allgemeine Java-Themen 23
M RXTX Details auslesen Allgemeine Java-Themen 6
N Input/Output Website Text auslesen und bestimmte Zeilen wiedergeben Allgemeine Java-Themen 4
X HTTP Auslesen der Ergebnisse von einer Webseite und in eine Liste packen Allgemeine Java-Themen 1
J Wav-Datei aus .jar auslesen Allgemeine Java-Themen 7
J Daten aus GUI auslesen und in Objekte umwandeln Allgemeine Java-Themen 6
D CSV Datei auslesen Allgemeine Java-Themen 23
N Werte aus Arrays auslesen funktioniert nicht Allgemeine Java-Themen 5
J Java JSON-Datei aus .Zip auslesen und Download mit Progress Bar Allgemeine Java-Themen 20
V Tooltips mit Java auslesen Allgemeine Java-Themen 1
I Inhalt einer Website auslesen Allgemeine Java-Themen 6
A JTable - CellRange auslesen Allgemeine Java-Themen 2
V 2d-Barcodes mit zxing auslesen Allgemeine Java-Themen 2
A Auslesen einer Datei sowie ausgeben als Liste in App Allgemeine Java-Themen 5
K Website in Programm einbinden und auslesen Allgemeine Java-Themen 2
M Image auslesen Allgemeine Java-Themen 2
S Zahlen aus (String mit zahlen) immer wieder neu auslesen Allgemeine Java-Themen 5
T datei auslesen ind der richtigen reihenfolge Allgemeine Java-Themen 2
A Probleme beim auslesen von Quelltext (HTML) Allgemeine Java-Themen 5
I Methoden Quellcode auslesen (Refelction o.ä.) Allgemeine Java-Themen 5
B Compiler-Fehler NullPointerException beim Auslesen von .lang-Datei Allgemeine Java-Themen 3
A Metadaten von Bildern auslesen und verändern Allgemeine Java-Themen 5
M InputStream auslesen Allgemeine Java-Themen 1
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
I Best Practice Properties auslesen und splitten (RegExp?) Allgemeine Java-Themen 0

Ähnliche Java Themen

Neue Themen


Oben