0

Recently I started working with CUDA and Ethereum and I found a little bit of code snipet on a function that when I try to port to a cuda file I get some errors.

Here is the code snippet:

void keccak_f1600_round(uint2* a, uint r, uint out_size)
{

#if !__ENDIAN_LITTLE__
    for (uint i = 0; i != 25; ++i)
        a[i] = make_uint2(a[i].y, a[i].x);
#endif

uint2 b[25];
uint2 t;

// Theta
b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];

#if !__ENDIAN_LITTLE__
    for (uint i = 0; i != 25; ++i)
        a[i] = make_uint2(a[i].y, a[i].x);
#endif

}

The error I am getting concern the b[0] line and is:

error: no operator "^=" matches these operands operand types are: uint2 ^= uint2

TO be honest I don't have a lot of experience with uint2 and cuda and that is why I am asking what should I do to correct this issue.

tudoricc
  • 709
  • 1
  • 12
  • 31
  • 1
    Apparently `uint2` is not a numeric type; I think it's a struct. I'm not familar with CUDA, so I don't have more details than that. – Keith Thompson May 18 '15 at 22:26
  • What do you expect should this operator do? Bitwise xor? you need to implement it yourself. – m.s. May 18 '15 at 22:27
  • @m.s. bitwise xor,by implementing yourself you should add both parameters(`a[0].x + a[0].y`) instead of `a[0]` – tudoricc May 18 '15 at 22:42

2 Answers2

2

The exclusive-or operator works with unsigned long long, but not with uint2 (which for CUDA is a built-in struct containing two unsigned ints).

To make the code work, there are several options. Some that come to my mind:

  • you can use reinterpret-cast<unsigned long long &> before each uint2 in the line that does the exclusive-or (see How to use reinterpret_cast in C++?)

  • you can rewrite the code to use unsigned long long types everywhere you use uint2 now. This probably produces the most maintainable code.

  • you can rewrite the line for the exclusive-or among uint2 types, as a pair of exclusive-or lines using the .x and .y members of the uint2, as each is an unsigned int type.

  • you can define a union type to allow access to the data that is currently type uint2, as either a uint2 or a unsigned long long.

  • you can overload the ^ exclusive-or operator to work with uint2 types.

  • you can replace the line that produces the error with asm statements to generate the PTX code to perform the exclusive-or for you. See http://docs.nvidia.com/cuda/inline-ptx-assembly/index.html#using-inline-ptx-assembly-in-cuda

Community
  • 1
  • 1
ime
  • 126
  • 4
  • for the 3rd bullet do you mean that I should remember in .x the xfull xor for all the components (a[0] ....) .x and the same for y? – tudoricc May 19 '15 at 19:42
  • 1
    Where you currently have: `b[0] = a[0] ^ a[5] ^ a[10] ^ a[15] ^ a[20];` Instead you would have: `b[0].x = a[0].x ^ a[5].x ^ a[10].x ^ a[15].x ^ a[20].x;` `b[0].y = a[0].y ^ a[5].y ^ a[10].y ^ a[15].y ^ a[20].y; ` – ime May 19 '15 at 23:50
1

uint2 is simply a struct, you'll need to implement ^ using a[].x and a[].y. I couldn't find where the builtin declarations are but Are there advantages to using the CUDA vector types? has a good description of their use.

Community
  • 1
  • 1
Christian Sarofeen
  • 2,202
  • 11
  • 18