C++ Passing Polymorphic Pointer of Pointers to Function - function

In trying to shorted my code for readability, I wound up changing too much and making mistakes. This is still condensed but taken straight from my code.
My problem is that I have a class called "function" and a derived class "pwfunction" which both have the virtual () operator. I'd like to pass an array of pointers to my "function" objects to various actual functions and use the () operator.
Final edit: This is a SSCCE version of what I'm talking about.
#include <iostream>
using namespace std;
class function
{
public:
virtual double operator () (double x) {return 1.5;}
};
class pwfunction : public function
{
public:
virtual double operator() (double x) {return 2.0;}
};
void interface();
void definefuncs (function** funcs, long unsigned numfuncs);
void interpolate(function* infunc);
void solvefuncs(function** funcs, long unsigned numfuncs);
int main()
{
interface();
return 0;
}
void interface()
{
long unsigned numfuncs = 1;
function* funcs[numfuncs];
definefuncs(funcs, numfuncs);
solvefuncs(funcs, numfuncs);
}
void definefuncs (function** funcs, long unsigned numfuncs)
{
interpolate(funcs[0]);
}
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
void solvefuncs(function** funcs, long unsigned numfuncs)
{
cout<< (*funcs[0])(1.5); //Error Message: Segmentation fault
}

The problem comes from the following:
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
is probably not doing what you want. infunc is allocated locally, and this does not affect anything else outside or this function (and is btw a memory leak). Interpolate should either return infunc, or allocate the original variable, such as
void interpolate(function*& infunc) ...

You don't allocate array for the funclist data in somefunction, so anything can happen. Perhaps you mean
func* funclist[1];
to indicate a one-element array of func pointers.

Related

CUDA thrust device pointer with transform copy crash

In CUDA 9.2 I have something like this:
#ifdef __CUDA_ARCH__
struct Context { float n[4]; } context;
#else
typedef __m128 Context;
#endif
struct A { float k[2]; };
struct B { float q[4]; };
struct FTransform : thrust::unary_function<A, B>
{
const Context context;
FTransform(Context context) : context(context){}
__device__ __host__ B operator()(const A& a) const
{
B b{{a.k[0], a.k[1], a.k[0]*context.n[0], a.k[1]*context.n[1]}};
return b;
}
};
void DoThrust(B* _bs, const Context& context, A* _as, uint32_t count)
{
thrust::device_ptr<B> bs = thrust::device_pointer_cast(_bs);
thrust::device_ptr<A> as = thrust::device_pointer_cast(_as);
FTransform fTransform(context);
auto first = thrust::make_transform_iterator(as, fTransform);
auto last = thrust::make_transform_iterator(as + count, fTransform);
thrust::copy(first, last, bs);
}
int main(int c, char **argv)
{
const uint32_t Count = 4;
Context context;
A* as;
B* bs;
cudaMalloc(&as, Count*sizeof(A));
cudaMalloc(&bs, Count*sizeof(B));
A hostAs[Count];
cudaMemcpy(as, hostAs, Count * sizeof(A), cudaMemcpyHostToDevice);
DoThrust(bs, context, as, Count);
B hostBs[Count];
cudaMemcpy(hostBs, bs, Count * sizeof(B), cudaMemcpyDeviceToHost);//crash
return 0;
}
Then when I call a standard cudaMemcpy() call later on the results I get the exception "an illegal memory access was encountered".
If I replace the thrust code with a non-thrust equivalent there is no error and everything works fine. Various combinations of trying to copy to device_vectors etc I get different crashes that seem to be thrust trying to release the device_ptr's for some reason - so maybe it is here for some reason?
== UPDATE ==
Ok that was confusing it appears it's due to the functor FTransform context member variable in my actual more complicated case. This specifically:
struct FTransform : thrust::unary_function<A, B>
{
#ifdef __CUDA_ARCH__
struct Context { float v[4]; } context;
#else
__m128 context;
#endif
...
};
So I guess it's an alignment problem somehow => in fact it is, as this works:
#ifdef __CUDA_ARCH__
struct __align__(16) Context { float v[4]; } context;
#else
__m128 context;
#endif
The solution is to ensure that if you use aligned types in thrust functor members (such as __m128 SSE types) that are copied to the GPU, that they are defined as aligned both during NVCC's CPU and GPU code build passes - and not accidentally assume even if a type may seem to naturally align to it's equivalent in the other pass that it will be ok, as otherwise bad hard to understand things may happen.
So for example the _ align _(16) is necessary in code like this:
struct FTransform : thrust::unary_function<A, B>
{
#ifdef __CUDA_ARCH__
struct __align__(16) Context { float v[4]; } context;
#else
__m128 context;
#endif
FTransform(Context context) : context(context){}
__device__ __host__ B operator()(const A& a) const; // function makes use of context
};

Passing class function using function pointer to external library

I have a class that uses a preexisting library. There is a function call that needs a function pointer, and I am trying to pass in the function that is in my class. It doesn't compile though. What can I do to fix this? (Also, I'm sure this was asked before in a much clearer way. I'm out of my element with this, so my apologies).
Note: This is for an arduino.
In my main program I have the following code...
#include "CM.h"
CM cm;
void setup() {
cm.setup();
}
CM.h
class CM {
private:
LibClass *lib;
void onInit();
public:
void setup();
};
CM.cpp
#include "CM.h"
void CM::setup() {
lib->attach(onInit); // <-- this isn't working.
}
void CM::onInit() {
Serial.println("HERE I AM");
}
To pass a member function, you need to make it "static" and then pass it with a full scope qualifier:
#include <iostream>
void attach( void (*func)(void) );
class CM {
private:
static void onInit();
public:
void setup();
};
void CM::setup()
{
attach(CM::onInit);
}
void CM::onInit(void)
{
std::cout << "HERE I AM";
}
// a global function pointer for this example
void (*p_func)(void);
// a "library" attach function
void attach( void (*func)(void) )
{
p_func = func;
}
int main(int argc, const char * argv[]) {
CM my;
my.setup();
p_func(); // like the library call
return 0;
}

How to implement device side CUDA virtual functions?

I see that CUDA doesn't allow for classes with virtual functions to be passed into kernel functions. Are there any work-arounds to this limitation?
I would really like to be able to use polymorphism within a kernel function.
Thanks!
The most important part of Robert Crovella's comment is:
The objects simply need to be created on the device.
So keeping that in mind, I was dealing with situation where I had an abstract class Function and then some implementations of it encapsulating different function and its evaluation. This is the simplified version of my code how I achieved polymorphism in my situation, but I am not saying it cannot be done better... It will hopefully help you to get the idea:
class Function
{
public:
__device__ Function() {}
__device__ virtual ~Function() {}
__device__ virtual void Evaluate(const real* __restrict__ positions, real* fitnesses, const SIZE_TYPE particlesCount) const = 0;
};
class FunctionRsj : public Function
{
private:
SIZE_TYPE m_DimensionsCount;
SIZE_TYPE m_PointsCount;
real* m_Y;
real* m_X;
public:
__device__ FunctionRsj(const SIZE_TYPE dimensionsCount, const SIZE_TYPE pointsCount, real* configFileData)
: m_DimensionsCount(dimensionsCount),
m_PointsCount(pointsCount),
m_Y(configFileData),
m_X(configFileData + pointsCount) {}
__device__ ~FunctionRsj()
{
// m_Y points to the beginning of the config
// file data, use it for destruction as this
// object took ownership of configFilDeata.
delete[] m_Y;
}
__device__ void Evaluate(const real* __restrict__ positions, real* fitnesses, const SIZE_TYPE particlesCount) const
{
// Implement evaluation of FunctionRsj here.
}
};
__global__ void evaluate_fitnesses(
const real* __restrict__ positions,
real* fitnesses,
Function const* const* __restrict__ function,
const SIZE_TYPE particlesCount)
{
// This whole kernel is just a proxy as kernels
// cannot be member functions.
(*function)->Evaluate(positions, fitnesses, particlesCount);
}
__global__ void create_function(
Function** function,
SIZE_TYPE dimensionsCount,
SIZE_TYPE pointsCount,
real* configFileData)
{
// It is necessary to create object representing a function
// directly in global memory of the GPU device for virtual
// functions to work correctly, i.e. virtual function table
// HAS to be on GPU as well.
if (threadIdx.x == 0 && blockIdx.x == 0)
{
(*function) = new FunctionRsj(dimensionsCount, pointsCount, configFileData);
}
}
__global__ void delete_function(Function** function)
{
delete *function;
}
int main()
{
// Lets just assume d_FunctionConfigData, d_Positions,
// d_Fitnesses are arrays allocated on GPU already ...
// Create function.
Function** d_Function;
cudaMalloc(&d_Function, sizeof(Function**));
create_function<<<1, 1>>>(d_Function, 10, 10, d_FunctionConfigData);
// Evaluate using proxy kernel.
evaluate_fitnesses<<<
m_Configuration.GetEvaluationGridSize(),
m_Configuration.GetEvaluationBlockSize(),
m_Configuration.GetEvaluationSharedMemorySize()>>>(
d_Positions,
d_Fitnesses,
d_Function,
m_Configuration.GetParticlesCount());
// Delete function object on GPU.
delete_function<<<1, 1>>>(d_Function);
}

error with function pointers usage in C

#include <stdio.h>
#include <string.h>
void func1 (void) { printf( "1\n" ); }
void func0 (void) { printf( "0\n" ); }
typedef struct {
void (*func0)(void);
void (*func1)(void);
}mainJT;
static const mainJT coreJT = {
core_func0,
core_func1
};
mainJT currJT;
int main()
{
currJT=coreJT;
coreJT.core_func0();
getchar();
return 0;
}
Please help me fix the errors, I am sure I am making some obvious mistakes. Thanks.
Your question isn't quite clear but I see what I can find.
typedef struct {
void (*func0)(void);
void (*func1)(void);
} mainJT;
Here you are declaring a struct with function pointer members func0 and func1. Then you are trying to define a coreJT variable via an initializer list:
static const mainJT coreJT = {
core_func0,
core_func1
};
But this doesn't work, because there are no functions called core_func0 or core_func1!
Also you try to call
coreJT.core_func0();
which is also incorrect since your struct doesn't have a member of name core_func0.
For a possible solution try renaming your functions like so:
void core_func1 (void) { printf( "1\n" ); }
void core_func0 (void) { printf( "0\n" ); }
and call your function pointer by
coreJT.func0();
i see lot of errors:
for eg: the correct way of initializing a structure is :
/* Define a type point to be a struct with integer members x, y */
typedef struct {
int x;
int y;
} point;
/* Define a variable p of type point, and initialize all its members inline! */
point p = {1,2};
so your part of the code is :
mainJT coreJT = {
core_func0;
core_func1;
};
completely wrong.
also where are the functions core_func1 core_func0 are declared and defined .i cannot see them.
i guess you first need to go through structures in c

Functions in struct in c only

I am having a hard time compiling this C code.
Basically what happens is:
it does compile but when I run it (on Terminal) it prints me:Illegal instruction
I tried to debug it and on Xcode and when it attempts to execute (*fraction).print() it says: EXC_BAD_ACCESS
if I delete the (*fraction).print() line everything works fine (same happens if I only delete the next line)
GNU99 and -fnested-functions flag is enabled
I do not want to change the main function just the other stuff
This code drove me crazy for a whole afternoon so a little help would be really appreciated.
Thankyou
#include <stdlib.h>
#include "string.h"
#include "stdio.h"
typedef struct
{
int numerator;
int denominator;
void (*print)(); // prints on screen "numerator/denominator"
float (*convertToNum)(); //returns value of numerator/denominator
void (*setNumerator)(int n);
void (*setDenominator)(int d);
} Fraction;
Fraction* allocFraction(Fraction* fraction); //creates an uninitialized fraction
void deleteFraction(Fraction *fraction);
Fraction* allocFraction(Fraction* fraction)
{
void print()
{
int a= 10;
printf("%i/%i", (*fraction).numerator, (*fraction).denominator);
a--;
}
float convertToNum()
{
return (float)(*fraction).numerator/(float)(*fraction).denominator;
}
void setNumerator (int n)
{
(*fraction).numerator= n;
}
void setDenominator (int d)
{
(*fraction).denominator= d;
}
if(fraction== NULL)
fraction= (Fraction*) malloc(sizeof(Fraction));
if(fraction)
{
(*fraction).convertToNum= convertToNum;
(*fraction).print= print;
(*fraction).setNumerator= setNumerator;
(*fraction).setDenominator= setDenominator;
}
return fraction;
}
void deleteFraction(Fraction *fraction)
{
free(fraction);
}
int main (int argc, const char * argv[])
{
Fraction *fraction= allocFraction(fraction);
(*fraction).setNumerator(4);
(*fraction).setDenominator(7);
(*fraction).print(); //EXC_BAD_ACCESS on debug. Illegal instruction in Terminal
printf("%f", (*fraction).convertToNum());
(*fraction).print();
deleteFraction(fraction);
return 0;
}
You can't write C in the same way you write Javascript.
Specifically, it appears that print() is a nested function inside allocFraction() (which is itself not standard C but a gcc extension). You can't call a nested function through a function pointer from outside the scope of where it's defined. This is true even if you don't access anything in the outer scope from the nested scope.
Your code appears to be attempting to do object-oriented programming in C. Have you considered C++?