Sending float array from host to device

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:
https://github.com/nvpro-samples/optix_advanced_samples/blob/master/src/optixIntroduction/optixIntro_10/src/Application.cpp#L489