OptiX and CUDA interoperability

Hello,

I want to use OptiX and CUDA together. I’ve installed both OptiX and CUDA, and now I want to adapt the optixTutorial sample to include some CUDA code.
I followed the OptiX programming guide for interoperability and used the function cudaSetDevice( cuda_device_ordinal ) in the optixTutorial.cpp but always end up with the following:

[100%] Linking CXX executable ../bin/optixTutorial
...
undefined reference to `cudaSetDevice'
...

Using other CUDA specific methods (e.g. cudaMalloc) produces the same error.

I also added

using namespace optix;
#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_runtime_api.h>

to the optixTutorial.cpp.

I’m using CUDA 8.0, Optix 5.0.0, Ubuntu 16.04, cmake 3.5.1 and a GeForce GTX 750 Ti.

Thanks in advance for your help.

This might just be a problem with the order of includes.
Put the CUDA includes before the OptiX includes and move the “using namespace optix” after all includes.
[url]https://devtalk.nvidia.com/default/topic/1027866/?comment=5228492[/url]

The forum has a search functionality. I found that post via this search (second hit):
[url]https://devtalk.nvidia.com/search/more/sitecommentsearch/cuda_runtime.h/?boards=254&order=date-desc[/url]

I would recommend to update to OptiX 5.1.0 as well.

Hi Detlef,

thanks for your quick reply.

I updated to OptiX 5.1.0 and put the CUDA includes before the OptiX includes and put the namespace at the end of the includes.

Unfortunately, I get the same error and additionally:

undefined reference to `sutil::calculateCameraVariables(float3, float3, float3, float, float, float3&, float3&, float3&, bool)'
undefined reference to `sutil::Arcball::rotate(float2 const&, float2 const&) const'

The additional error should be due to the sutil library missing in you project’s linker settings.

That said, the initial error is a linker error as well, so you might just be missing the CUDA runtime library in your list of modules.

I would start with an absolute minimal example which works before adding the CUDA includes and then start to include the cuda_runtime.h and then add a runtime call and see where this goes and adjust the CMake linker libraries until you have everything together.

I have the same issue.
Optix SDK 4.1.1
CUDA 8.0

Windows 7, Visual Studio 14.0.25431.01 update 3

In main.cpp I use both of CUDA and Optix. CUDA includes first.

At some point I get same error messages

undefined reference to `sutil::calculateCameraVariables(float3, float3, float3, float, float, float3&, float3&, float3&, bool)'
undefined reference to `sutil::Arcball::rotate(float2 const&, float2 const&) const'

If I compare sutil.dll and full verbose linker output, I get a difference in namespace qualificator of argument

// sutil.dll
?calculateCameraVariables@sutil@@YAXUfloat3@optix@@00MMAEAU23@11_N@Z

// linker.log
?calculateCameraVariables@sutil@@YAXUfloat3@@00MMAEAU23@11_N@Z

So, because of collision of namespaces and equality of types optix::float3 and float3 compiler somehow decides to shortcut argument signature. Linker can’t handle this.

Maybe it’s problem of the compiler.
Or with CUDA 8.0 I should use another version of Optix.

You should definitely update to OptiX 5.1.0.

The function declarations are using fully qualified names. If you’d remove the “using namespace optix” in the calling code and declare the variables with optix::float3, that should find the match.

Personally I’m not using any of the sutil libraries in my own OptiX application framework and also avoid using namespace statements to make clear what declarations are meant.

I had a double check about using namespace optix; and I found nothing.

Also I just now reproduce the problem with user-defined function.

So, I have function

// primeComon.cpp
optix::float3 transformPoint(const SimpleMatrix4x3& M, const optix::float3& p)
{
    return optix::make_float3(
        M.f0*p.x + M.f1*p.y + M.f2*p.z + M.f3,
    M.f4*p.x + M.f5*p.y + M.f6*p.z + M.f7,
    M.f8*p.x + M.f9*p.y + M.f10*p.z + M.f11);
}

After compilation, I have primeCommon.obj.

Using
DUMPBIN /SYMBOLS primeCommon.obj
I recive it’s contents

019 00000000 SECT6  notype ()    External     | ?transformPoint@@YA?AUfloat3@optix@@AEBUSimpleMatrix4x3@@AEBU12@@Z (struct optix::float3 __cdecl transformPoint(struct SimpleMatrix4x3 const &,struct optix::float3 const &))

So this function properly compiled to .obj file.

In main.cpp I have this situation (simplified):

#include <cuda.h>
#include <cuda_runtime.h>
#include <optix_prime/optix_primepp.h>
#include "primeCommon.h"

int main()
{
    SimpleMatrix4x3 *transforms;
    optix::float3 *vertices;

    /* some code */

    optix::float3 A = transformPoint(transforms[indexMesh], vertices[tri.x]);

    /* some code */
}

Linking fails with message

adding resource. type:MANIFEST, name:1, language:0x0409, flags:0x30, size:381
primeInstancing.obj : error LNK2019: unresolved external symbol "struct float3 __cdecl transformPoint(struct SimpleMatrix4x3 const &,struct float3 const &)" (?transformPoint@@YA?AUfloat3@@AEBUSimpleMatrix4x3@@AEBU1@@Z) referenced in function "main()"

Linker symbol and obj symbol are identical, except “optix::”

I repeat, there is no using namespace optix; directive.
Every type defined with optix::.

If I remove #include <cuda.h> #include <cuda_runtime.h> and dependent code, all works fine.

I’m using the same compiler version. Let me check.

You could try to switch to OptiX 5.1.0 and CUDA 9.0 (not newer).

I’ve hit this as well in my own code when trying to #include <cuda_runtime_api.h> now in an OptiX based application.
The solution was to put that include before every #include <optix.h> inside my sources.
All my function signatures use fully qualified namespaces.