1

I am trying to use CUDA C for GPU computing, in particular matrix inversion problem. Meanwhile at the beginning of my code I have defined function. But, that seems to give me an error of "expected declation" at the line where I initiate "do".

I am new to C++ so haven't tried much.

#include<cublas_v2.h>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>

#define cudacall(call)
    do
    {
        cudaError_t err = (call);
        if (cudaSuccess != err)
        {
            fprintf(stderr, "CUDA Error:\nFile = %s\nLine = %d\nReason = %s\n", __FILE__, __LINE__, cudaGetErrorString(err));
            cudaDeviceReset();
            exit(EXIT_FAILURE)
        }
    }
    while (0);

"Expected Declaration"

Alecto Irene Perez
  • 10,321
  • 23
  • 46
  • 2
    What you're doing is defining a macro that expands to this block of code. However, you haven't shown where you're actually using the macro (`cudacall(/* something */)`). Could you add that code? – joshwilsonvu Jul 25 '19 at 17:01
  • 2
    That macro definition looks flawed. You need to add some backslashes (`\\`) at the end of each line to eat the newline characters. – Jesper Juhl Jul 25 '19 at 17:05
  • This could very well be a templated function instead. Edit : Nevermind, missed the end of the long `fprintf`. Edit 2 : Looking forward to [`std::source_location`](https://en.cppreference.com/w/cpp/experimental/source_location). – François Andrieux Jul 25 '19 at 17:08
  • 2
    @JoshWilson "What you're doing is defining a macro that expands to this block of code" - Except he is not. Macro definitions need to be on one line. So unless you tell the preprocessor to eat the newlines with \ (or manually place it all on one line), this is a macro that expands to an empty string, followed by some code that doesn't make any sense in it's context. – Jesper Juhl Jul 25 '19 at 17:08
  • 2
    If you are new to C++ then messing with macros is the last thing I'd advise. Where did you get idea for using macros from? – john Jul 25 '19 at 17:31
  • 1
    Possible duplicate of [Multi line preprocessor macros](https://stackoverflow.com/questions/10419530/multi-line-preprocessor-macros) – zett42 Jul 25 '19 at 19:20

1 Answers1

2

Multi-line macros need to have a \ to indicate that they continue on the next line. I lined all of them up at the end; scroll to see them.

#define cudacall(call)                                                         \
  do {                                                                         \
    cudaError_t err = (call);                                                  \
    if (cudaSuccess != err) {                                                  \
      fprintf(stderr, "CUDA Error:\nFile = %s\nLine = %d\nReason = %s\n",      \
              __FILE__, __LINE__, cudaGetErrorString(err));                    \
      cudaDeviceReset();                                                       \
      exit(EXIT_FAILURE)                                                       \
    }                                                                          \
  } while (0);

In general, please avoid macros if you can. Use lambdas and higher-order functions instead:

template<class F> 
void cudacall(F&& func) {                                                                    
    cudaError_t err = func();                                                  
    if (cudaSuccess != err) {                                                  
        fprintf(stderr, "CUDA Error:\nFile = %s\nLine = %d\nReason = %s\n",      
              __FILE__, __LINE__, cudaGetErrorString(err));                    
        cudaDeviceReset();                                                       
        exit(EXIT_FAILURE);                                                     
    }                                                                          
}

We can use it like this:

void dostuff() {
    bool wasICalled = false;
    cudacall([&]() {
        // Code goes here

        // We can access and modify local variables inside a lambda
        wasICalled = true; 

        // Return the error
        return cudaError_t{}; 
    }); 
}
Alecto Irene Perez
  • 10,321
  • 23
  • 46
  • Though templated functions are generally better than macros, the `__FILE__` and `__LINE__` macros (a significant part of the purpose of `cudacall`) will not work as intended. – joshwilsonvu Jul 25 '19 at 18:36
  • The macro has different observable behavior when compared to the function template (or rather its instantiation) and the lambda. Some things simply can only be done in a macro. – IInspectable Jul 25 '19 at 19:48
  • Hey, thanks! I was unaware of backslash to indicate that they will follow on to next line. Problem is solved now. – Dhyey Bhavsar Jul 26 '19 at 18:29