0

I am pretty new with alglib and Cuda. I am trying to use Alglib for nonlinear list square fitting. Codes are working when I compile it in VC++ (.cpp) but when I am trying to compile same code but in a cuda file (.cu) it gives me this error:

Error   6   error C2668: 'round' : ambiguous call to overloaded function    
Error   7   error C2668: 'round' : ambiguous call to overloaded function    
Error   8   error C2668: 'round' : ambiguous call to overloaded function    
Error   9   error C2668: 'trunc' : ambiguous call to overloaded function    

Error   10  error MSB3721:

The command ""D:\NVIDIA\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2012 -ccbin "D:\Programme (x86)\Microsoft Visual Studio 11.0\VC\bin" -ID:\NVIDIA\include -ID:\NVIDIA\include --keep-dir Release -maxrregcount=0 --machine 32 --compile -cudart static -D_MBCS -Xcompiler "/EHsc /W3 /nologo /O2 /Zi /MD " -o Release\min.cu.obj "...\min.cu"" exited with code 2. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\CUDA 6.0.targets 597 9 Cuda_lsfit

Here is my codes :

# include <iostream>
# include "cuda_runtime.h"
# include "device_launch_parameters.h"
# include <cuda.h>
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "interpolation.h"

using namespace alglib;

void function_cx_1_func(const real_1d_array &c, const real_1d_array &x, double &func,      void *ptr) 
{
  // main function
   func = abs(c[0]*(1-exp(-x[0]/c[1])));;
}

int main(int argc, char **argv)
{
real_2d_array x = "[[50],[400],[550],[750],[1200],[2000]]";
real_1d_array y = "[1384,792,642,258,91,868]";
real_1d_array c = "[0.5,500]";
double epsf = 0; //minimum of step size difference
double epsx = 0.000001;  //minimum of function changes
ae_int_t maxits = 0; //maximum iteration 0 = unlimitted number
ae_int_t info;
lsfitstate state; // structure contains information about algoritm
lsfitreport rep;
double diffstep = 0.0001;

// Fitting 

lsfitcreatef(x, y, c, diffstep, state);
lsfitsetcond(state, epsf, epsx, maxits);
alglib::lsfitfit(state, function_cx_1_func);
lsfitresults(state, info, c, rep);
printf("%d\n", int(info)); 
printf("%s\n", c.tostring(1).c_str()); 

return 0;
}

Any solution would be appreciated.

Thanks, Mohsen

mohsen67
  • 3
  • 3
  • 1
    If you want to ask a "why doesn't this code compile" question, you will need to post the shortest code which demonstrates the problem. – talonmies Jul 03 '14 at 13:57
  • I solve it but honestly I am not sure if it is the best solution. I just defined the round function and trunc should use from alglib library. now it compiles and it gives me correct result. – mohsen67 Jul 03 '14 at 15:57
  • 1
    I do not see any calls to `trunc()` or `round()` in the posted code. These functions are supported in CUDA device code and they are overloaded for argument types of `float` and `double`. Calling with an argument of any other type could cause the kind of error message you are seeing. However the error messages you are showing seem to be MSVC error messages, so the problem seems to be in the host code portion of the .cu file. Check the prototypes in the host header files (are you including all necessary header files ?) and compare the argument type passed inside the application code. – njuffa Jul 03 '14 at 21:19
  • @njuffa: I wonder whether this is a namespace conflict resulting from the `using namespace alglib;` – talonmies Jul 04 '14 at 06:16
  • @talonmies: I do not have any experience with, or insight into, the use of namespaces in .cu file. When there are issues with the host code (as appears to be the case here), my standard recommendation is to move the affected code out of the .cu and into a .cpp file. – njuffa Jul 04 '14 at 07:19
  • @njuffa :thank you for help. I am trying to make my code parallel step by step ( may be it is not a good way) but first I don't want to use kernel I just simply run same cpp codes but in .cu file. therefore it is not my final code. As talonmies said I also think that the problem caused by using namespace alglib. – mohsen67 Jul 04 '14 at 09:01
  • I just clear $ using namespace alglib; $ and it works now. Thank you – mohsen67 Jul 04 '14 at 09:32
  • My guess is that alglib includes those functions in its namespace. When you compile with nvcc, the compiler automagically adds the CUDA includes, which then produce conflict with the CUDA math library definitions/overlays of the same functions – talonmies Jul 04 '14 at 16:32
  • @talonmies it seems you have identified the issue. If you wish to provide an answer I would upvote it. – Robert Crovella Jul 06 '14 at 21:33

1 Answers1

1

This would appear to have been a namespace conflict between the definitions of mathematical functions which CUDA adds during compilation, and including the whole alglib namespace into the translation unit. Removing

using namespace alglib;

from the code apparently solved the problem.

In general, unconditionally importing a large namespace into another is a very poor design practice in C++, because it can lead to very hard to diagnose conflicts like this, as well as slowing down compilation.

talonmies
  • 70,661
  • 34
  • 192
  • 269
  • `round()` and `trunc()` are standard C/C++ math functions, and since CUDA relies on the host header file `math.h` for prototypes for those, I would think that this is where the symbols are introduced. The functions themselves are perfectly operational in CUDA, not sure why `alglib` would want to redefine them. – njuffa Feb 22 '16 at 09:07
  • @njuffa: The standard C++ math functions are, by default, defined in the `std` namespace. The fact you can reference them without requiring an explicit namespace means that they are getting imported by the CUDA compilation trajectory. They are probably also imported into the `alglib` namespace. When that is then imported into the default translation unit, a conflict results, or at least that appears to be the root cause in this case. – talonmies Feb 22 '16 at 09:27
  • Good point. I wonder whether that (the fact one can refer to math functions without explicit namespace) was required for a seamless transition of CUDA from a C to a C++ language. – njuffa Feb 22 '16 at 09:31
  • @njuffa: That would be my guess. Just a gentle hint, if you wouldn't mind upvoting the answer (its a community wiki so there isn't and rep involved), this question will fall off the unanswered queue for the CUDA tag, which is why I added it. – talonmies Feb 22 '16 at 09:34