Link to home
Start Free TrialLog in
Avatar of InteractiveMind
InteractiveMindFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Casting between two structs in C (CUDA)

The CUDA library effectively defines its own complex number data type, cuComplex, as follows:

  struct __builtin_align__(8) float2
  {
    float x, y;
  };
  typedef float2 cuFloatComplex;
  typedef cuFloatComplex cuComplex;

I am already using my own complex data type:

  typedef struct  { float re; float im; } complex;

and I wish to be able to cast between the two. Here's an example of what I'm currently trying:

  cuComplex cu_data;
  ...
  complex c_data;
  c_data = (complex)cu_data;

but I'm getting the (nvcc) error:

  'no suitable user-defined conversion from "cuComplex" to "complex" exists'.

So how do I do this? Equivalently: is there a way to do a typedef, but to simply rename the members of that struct? (ie rename 'x' to 're', 'y' to 'im')?

Thanks!
Avatar of jkr
jkr
Flag of Germany image

You could provide your own operator, e.g.
  struct /*__builtin_align__(8)*/ float2
  {
    float x, y;
  };
  typedef float2 cuFloatComplex;
  typedef cuFloatComplex cuComplex;

 typedef struct  { float re; float im; operator cuComplex();} complex;

 complex::operator cuComplex() {

   cuComplex out;

   out.x = re;
   out.y = im;

   return out;
 }

  int main () {

  cuComplex out;
  complex in;

  out = (cuComplex) in;

  return 0;
  }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of sridhard
sridhard


Hi,

Try using pointers . This will assign/point the correponding values. Note sure whether this helps

  cuComplex cu_data = (cuComplex  *) malloc(sizeof(cuComplex ));
  ...
  complex *c_data;
  c_data = (complex*)cu_data;

You can delete any one pointer later .
Avatar of InteractiveMind

ASKER

Thank you, both. I think I should mention that I am in fact casting pointers/arrays of such types in my code (but I get the same problem).

@jkr, would your method work for casting pointers? (I can't test it at the moment). If so, my code needs to be as fast as possible, so given that I'm going to need to do [probably] millions of such casts per second, would it be quicker to just do a typedef:

   typedef cuComplex complex;

and then a global search and replace of '.re' with '.x' etc? (I'm reluctant to do so)

Also, can you think of any reason why what I'm already doing wouldn't work? Is it the __builtin_align__(8) that's causing problems?
>>@jkr, would your method work for casting pointers?

If you use the indirecton appropriately - yes.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
The safest strategy is to use only cuda's struct in the first place, also in your code, so there is no cast needed anymore.
>> so given that I'm going to need to do [probably] millions of such casts per second, would it be quicker to just do a typedef:

My vote -> YES
@ambience, did you consider the different alignments as previous posts said?
@ambience, sorry I misunderstood your post, I thought you were suggesting just cast anyway, nevermind :)
Hi

Your answer is a function ponter. There (in the function) you read/write cuComplex/complex structs anyway you like.

Rafael
Thanks