Hello,
I am trying to send a float[5] array, defined on host side, to the GPU-device. I have already done that with float3 and float4 types. But since float5 is not originally given by Cudas “vector_types”, I was trying to send a float[5] array with the context method “setUserData(…)”. However, when I am trying to access that data on the device side, I get an error of memory adress violation: Process finished with exit code 139 (interrupted by signal 11: SIGSEGV).
I am not sure what I have done wrong. Here is an example of how I am trying to send data to the device from the host:
On Host side:
float test[5] = {1.0f,2.0f,3.0f,4.0f,5.0f};
void* void_ptr = static_cast<void*>(test);
context["test_data"]->setUserData(5* sizeof(float), void_ptr);
On Device side in a .cu file:
rtDeclareVariable(void*, test_data, , );
...
RT_PROGRAM void some_function()
{
...
float* test_device = static_cast<float*>(test_data);
rtPrintf("%f\n", test_device[0]);
...
}
Of course I set “setPrintEnabled” to true in order for the output to work.
I would really appreciate some help, since I dont know how to solve that kind of memory access violation.
Thanks a lot.
You cannot simply send a virtual pointer in host memory to the GPU device. You need to have that data inside some GPU-addressable memory and in your case the easiest method is to copy that onto the device by using an OptiX buffer variable.
On the host:
static const float test[5] = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f};
optix::Buffer bufferOfFloats = context->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_FLOAT, 5); // RT_BUFFER_INPUT means this is a write-only buffer on the host and read-only buffer on the device.
// Copy data into OptiX buffer.
void* dst = bufferOfFloats->map(0, RT_BUFFER_MAP_WRITE_DISCARD);
memcpy(dst, test, sizeof(float) * 5);
bufferOfFloats ->unmap(); // This will mark the buffer dirty which triggers an upload to the device on the next launch.
On the device:
rtBuffer<float> bufferOfFloats; // 1D buffer with float data elements. Same as rtBuffer<float, 1>
RT_PROGRAM void func()
{
// Access floats inside the device copy with index in range [0, bufferOfFloats.size() - 1].
// Always use operator[] to access buffer elements!
// There is no pointer arithmetic allowed on device side buffers in OptiX.
float f = bufferOfFloats[index];
}
If you’re new to OptiX, please read through these documents:
http://raytracing-docs.nvidia.com/optix/index.html
and watch the OptiX Introduction presentation and work through its example source code:
https://devtalk.nvidia.com/default/topic/998546/optix/optix-advanced-samples-on-github/
Thanks for your fast reply. That worked for me.
I need to correct myself.
I am still running into the same Issue. I copy-pasted your example to my code and tried to visualize a float of the array with
rtPrintf("%f\n", f);
But I still get the same type of Memory violation.
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
I copied the host code directly to my main function and the device code to the .cu file, where my ray generation takes place (‘Pinhole Camera’).
I found the Error. Seems like there is one line missing on your host code:
context["bufferOfFloats"]->setBuffer(buffer_of_floats);
Correct me, if I’m wrong.
Right, I just typed that into the reply and forgot to set the variable on the host.
A context->validate() in debug mode should have given you some error that a buffer variable was not set instead of a straight crash.
Also maybe try setting a usage report callback function for additional information during debugging. Example code here:
[url]https://github.com/nvpro-samples/optix_advanced_samples/blob/master/src/optixIntroduction/optixIntro_10/src/Application.cpp#L489[/url]