问题描述
通过LWJGL使用opencl时,出现以下错误消息:
When using opencl via LWJGL, I am getting the following error message:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000002201971, pid=8476, tid=8920
#
# JRE version: 7.0_03-b05
# Java VM: Java HotSpot(TM) 64-Bit Server VM (22.1-b02 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [OpenCL.dll+0x1971]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# V:\Documents\NetBeansProjects\LWJGL\hs_err_pid8476.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
我正在使用的源代码:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.vecmath.Point3f;
import org.lwjgl.*;
import static org.lwjgl.opencl.CL10.*;
import org.lwjgl.opencl.*;
public class RayTracer {
public static void main(String[] args) throws Exception {
LoadSource();
RayTracer rayTracer = new RayTracer();
rayTracer.CLRender();
}
JFrame frame;
BufferedImage scene;
Sphere sphere;
static final float SAMPLES = 4f;
Graphics graphics;
BufferStrategy bufferSrategy;
final AtomicBoolean redraw = new AtomicBoolean();
IntBuffer temp;
static String source = "";
RayTracer() throws LWJGLException {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.createBufferStrategy(2);
bufferSrategy = frame.getBufferStrategy();
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
scene = gc.createCompatibleImage((int) (frame.getWidth()), (int) (frame.getHeight()));
sphere = new Sphere();
sphere.location = new Point3f(0, 0, -5);
startDrawThread();
}
void CLRender() throws LWJGLException {
// initialization
CL.create();
CLPlatform platform = CLPlatform.getPlatforms().get(0);
List<CLDevice> devices = platform.getDevices(CL_DEVICE_TYPE_GPU);
CLContext context = CLContext.create(platform, devices, null, null, null);
CLCommandQueue queue = clCreateCommandQueue(context, devices.get(0), CL_QUEUE_PROFILING_ENABLE, null);
// program/kernel creation
CLProgram program = clCreateProgramWithSource(context, source, null);
try {
Util.checkCLError(clBuildProgram(program, devices.get(0), "", null));
//check for problem
} catch (OpenCLException e) {
ByteBuffer buffer = BufferUtils.createByteBuffer(1024 * 40);
buffer.rewind();
PointerBuffer pb = PointerBuffer.allocateDirect(1);
Util.checkCLError(clGetProgramBuildInfo(program, devices.get(0), CL_PROGRAM_BUILD_STATUS, buffer, null));
switch (buffer.get(0)) {
case CL_BUILD_NONE:
System.out.println("build none");
break;
case CL_BUILD_ERROR:
System.out.println("build error");
break;
case CL_BUILD_IN_PROGRESS:
System.out.println("build in progress");
break;
case CL_BUILD_SUCCESS:
System.out.println("build successful");
break;
}
buffer.rewind();
Util.checkCLError(clGetProgramBuildInfo(program, devices.get(0), CL_PROGRAM_BUILD_LOG, buffer, pb));
print(buffer, pb.get());
System.exit(1);
}
// set kernel
CLKernel kernel = clCreateKernel(program, "trace", null);
final int width = scene.getWidth();
final int height = scene.getHeight();
FloatBuffer sphereRadius, sphereLocation, light, imageDim, samples;
IntBuffer color;
Light movingLight = new Light(new Point3f(), Color.ORANGE);
movingLight.activate();
try {
for (float z = 0;; z += .01f) {
//set Ligh Poition
movingLight.position = new Point3f(-.5f, (float) (10 * Math.cos(z)), (float) (10 * Math.sin(z)));
//Put data in Buffers
float[] lights = Light.getLights();
sphereRadius = toFloatBuffer(new float[]{sphere.radius.x, sphere.radius.y, sphere.radius.z});
sphereLocation = toFloatBuffer(new float[]{sphere.location.x, sphere.location.y, sphere.location.z});
light = toFloatBuffer(lights);
imageDim = toFloatBuffer(new float[]{width, height, -1f});
samples = toFloatBuffer(new float[]{SAMPLES});
color = toIntBuffer(new int[width * height]);
// send to open CL
CLMem sphereRadiusMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sphereRadius, null);
clEnqueueWriteBuffer(queue, sphereRadiusMem, 1, 0, sphereRadius, null, null);
CLMem lightMem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, light, null);
clEnqueueWriteBuffer(queue, lightMem, 1, 0, light, null, null);
CLMem imageDimMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, imageDim, null);
clEnqueueWriteBuffer(queue, imageDimMem, 1, 0, imageDim, null, null);
CLMem samplesMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, samples, null);
clEnqueueWriteBuffer(queue, samplesMem, 1, 0, samples, null, null);
CLMem sphereLocationMem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sphereLocation, null);
clEnqueueWriteBuffer(queue, sphereLocationMem, 1, 0, sphereLocation, null, null);
CLMem colorMem = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, color, null);
// execution
PointerBuffer kernel1DGlobalWorkSize = BufferUtils.createPointerBuffer(2);
kernel1DGlobalWorkSize.put(0, width);
kernel1DGlobalWorkSize.put(1, height);
kernel.setArg(0, sphereRadiusMem);
kernel.setArg(1, sphereLocationMem);
kernel.setArg(2, lightMem);
kernel.setArg(3, imageDimMem);
kernel.setArg(4, samplesMem);
kernel.setArg(5, colorMem);
clEnqueueNDRangeKernel(queue, kernel, 2, null, kernel1DGlobalWorkSize, null, null, null);
// read the results back
clEnqueueReadBuffer(queue, colorMem, 1, 0, color, null, null);
//transfer to Image
setScene(color);
//clean up memory
clReleaseMemObject(colorMem);
clReleaseMemObject(imageDimMem);
clReleaseMemObject(lightMem);
clReleaseMemObject(samplesMem);
//clReleaseMemObject(sphereLocationMem); //uncomenting results in nasty error
clReleaseMemObject(sphereLocationMem);
clReleaseMemObject(sphereRadiusMem);
}
} finally {
// teardown
clFinish(queue);
clReleaseKernel(kernel);
clReleaseProgram(program);
clReleaseCommandQueue(queue);
CL.destroy();
}
}
}
在底部附近,您会看到一条注释clReleaseMemObject(sphereLocationMem);
.如果我对此发表评论,它可以正常工作.其他所有对clReleaseMemory()
的调用都可以正常工作,为什么这会引发错误?
Near the bottom you will see a commented clReleaseMemObject(sphereLocationMem);
When ever this is uncommented, I get the error message. If I leave it commented, it works fine. All the other calls to clReleaseMemory()
work fine, why does this one throw an error?
推荐答案
SphereLocationMem
在指示的行未注释时被释放两次,位于:
SphereLocationMem
is being released twice when the indicated line is uncommented, at:
//clReleaseMemObject(sphereLocationMem); //uncomenting results in nasty error
clReleaseMemObject(sphereLocationMem);
领先于所示的访问冲突.对该行进行注释后,很可能可以正常工作.
Leading to the access violation indicated. Having that line commented, it's most likely working correctly.
这篇关于尝试释放内存时为EXCEPTION_ACCESS_VIOLATION(0xc0000005)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!