I figured this out.
I needed to define my functions in the correct files. For example, in Foo.h
:
class Foo {
public:
__host__ __device__
Foo();
}
and the function definition in Foo.cu
not Foo.cpp
as I originally thought.
Foo::Foo() {}
For the constant variables, I needed to implement a slightly different strategy.
Here is an example of the C++ class that I started with:
class Foo {
public:
static double const epsilon;
static void functionThatUsesEpsilon();
/**/
}
Had to be converted to use the global namespace as the epsilon def'n
namespace foo {
extern __constant__ double epsilon;
}
class Foo {
public:
// same stuff as before with the addition of this function
__host__ __device__
static inline double getEpsilon() {
#ifdef __CUDACC__
return foo::epsilon;
#else
return epsilon;
#endif
}
static void functionThatUsesEpsilon() {
if (bar < getEpsilon()) { // etc }
}
};
The ifdef
above will return the correct version of the variable for either the host or the device code. Everywhere I had referenced Foo::epsilon
I needed to replace with Foo::getEpsilon()
so the correct epsilon was returned.
Hope this helps someone in the future. Thanks to @RobertCrovella for getting me thinking.