Cuda - Undefined symbols for architecture x86_64 OS X - c++

Here is my make file output:
nvcc -c -arch=sm_35 src/kmeans_cuda.cu
nvcc -c -arch=sm_35 src/sequence.c
nvcc -c -arch=sm_35 src/io.c
nvcc -c -arch=sm_35 src/main.c
nvcc -g -o cuda-means kmeans_cuda.o sequence.o io.o main.o
Undefined symbols for architecture x86_64:
"_kmeans", referenced from:
_main in main.o
(maybe you meant: cudaError (anonymous namespace)::cudaLaunch<char>(char*))
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1
On my main function i call kmeans();, kmeans, is a C function defined in kmeans_cuda.cu
void kmeans() {
long i,h,j,k; //counters
long delta; //Number of objects has diverged in current iteration
long nearest; //Nearest centroid
unsigned int distance,min_distance; //distance calculated by relation point-cluster
int *count,*recv_count;
int *send_label;
double begin,end,trans_init,trans_end;
// should call kernel, but is not calling yet, because it's not implemented ...
I already try to added __host__ on kmeans() declaration, but dind't fixed the problem.
I have now idea why i'm getting this error, because i'm linking the object with the function.

nvcc treats .cu files as C++ and you have your host code in .c files (i.e. in C, not C++).
The easiest solution is to simply rename your .c files to .cpp and treat your app as a C++ app instead of C. You could also declare kmeans() as extern "C" {...} to force the compiler to use a C binding instead of C++ binding for the function, but then you'd have to do that for every future function which is probably unnecessarily inelegant.

Related

Programming Principles and Practice 2nd ed chapter 8 drill 1

Problem:
I cannot get the code provided by the author to link via clang++ in chapter 8 of Programming Principles and Practice by Bjarne Stroustrup.
Code:
~/scratch/cpp/chp8 (09/10/2017-13:51:43[EDT]) cat my.cpp
#include <iostream>
#include "my.h"
void print_foo() { std::cout << foo << std::endl; }
void print(int i) { std::cout << i << std::endl; }
~/scratch/cpp/chp8 (09/10/2017-13:52:29[EDT]) cat my.h
#ifndef MY_H
#define MY_H
extern int foo;
void print_foo();
void print(int);
#endif
~/scratch/cpp/chp8 (09/10/2017-13:52:33[EDT]) cat use.cpp
#include "my.h"
int main() {
foo = 7;
print_foo();
print(99);
return 0;
}
Attempts:
I have tried a few different ways of compiling this:
One - Compile the driver app that contains the main function.
~/scratch/cpp/chp8 (09/10/2017-13:52:39[EDT]) clang++ -std=c++14 -stdlib=libc++ use.cpp -o use.cpp.o
Undefined symbols for architecture x86_64:
"print(int)", referenced from:
_main in use-2864c4.o
"print_foo()", referenced from:
_main in use-2864c4.o
"_foo", referenced from:
_main in use-2864c4.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Two - Specifically compile just the my.cpp file and not link. Although I was successful in compiling I'm not sure how to link use.cpp with this object file now.
~/scratch/cpp/chp8 (09/10/2017-14:09:40[EDT]) clang++ -std=c++14 -stdlib=libc++ -c my.cpp -o my.cpp.o
Three - Use all .cpp files.
~/scratch/cpp/chp8 (09/10/2017-14:15:32[EDT]) clang++ -std=c++14 -stdlib=libc++ my.cpp use.cpp
Undefined symbols for architecture x86_64:
"_foo", referenced from:
print_foo() in my-2243d1.o
_main in use-796f91.o
(maybe you meant: __Z9print_foov)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Question:
Besides the obvious question of what am I doing wrong, I'm more interested in what am I missing or miss understanding here?
Note:
I'm not looking for personal opinions or preferences on what I should or should not be doing. This is a purely education adventure that I'm taking with this book and I would like to keep it as such.
Misc:
~/scratch/cpp/chp8 (09/10/2017-14:15:25[EDT]) uname -a
Darwin abes-MacBook-Pro.local 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64 x86_64
~/scratch/cpp/chp8 (09/10/2017-14:15:28[EDT]) clang++ -v
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
The error you get has nothing to do with the difference between compiling and linking. Rather there is an error in your code. The reason for the error is because you are declaring the global variable foo but you never define it. You need to add the line
int foo = 0;
to one of your .cpp files. This probably makes the most sense in my.cpp.
Note that using global variables like this is considered a Coding Horror. You should not do this in real code.
Regarding compiling and linking:
Creating an executable from your C++ takes several steps. Here we will talk about compiling versus linking and how to do each of these steps manually. There are also other steps, but I will not get into them here.
First of all, you can compile and link all of your source files all at once:
$ clang++ -std=c++14 -stdlib=libc++ my.cpp use.cpp
I'm confused why this is not working in your "Attempt three". I will look into this more shortly.
To compile and link your source code manually, you can do the following:
$ clang++ -std=c++14 -stdlib=libc++ -c my.cpp -o my.o
$ clang++ -std=c++14 -stdlib=libc++ -c use.cpp -o use.o
$ clang++ -std=c++14 -stdlib=libc++ my.o use.o -o use
Note that I compile my.cpp to my.o rather than my.cpp.o. This is the common convention for this.
Also, once you are comfortable with these concepts, I strongly suggest that you use a build tool such as make or an XCode project which manages these steps for you automatically.

PostgreSQL external C function link failed on Mac OSX

I'm trying to build an external PostgreSQL function on OSX 10.11 with both clang and gcc, but link failed with the following errors:
c++ -I/usr/local/Cellar/postgresql/9.5.3/include/server -fpic -c ./main.c
c++ -shared -o ttt.dylib main.o
Undefined symbols for architecture x86_64:
"_deconstruct_array", referenced from:
_psql_nearest in main.o
"_elog_finish", referenced from:
_psql_nearest in main.o
"_elog_start", referenced from:
_psql_nearest in main.o
"_get_typlenbyvalalign", referenced from:
_psql_nearest in main.o
"_pfree", referenced from:
_psql_nearest in main.o
"_pg_detoast_datum", referenced from:
_psql_nearest in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
It looks like I need to link my library with some of PostgreSQL libraries. What are these libraries?
main.cpp:
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#include <utils/array.h>
#include <utils/lsyscache.h>
#include <catalog/pg_type.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(psql_nearest);
Datum psql_nearest(PG_FUNCTION_ARGS) {
if(PG_ARGISNULL(0) || PG_ARGISNULL(1)) {
elog(ERROR, "DOC2VEC: NULL INPUT DATA");
PG_RETURN_NULL();
}
ArrayType *_docVector = PG_GETARG_ARRAYTYPE_P(0);
Oid elTypeVals = ARR_ELEMTYPE(_docVector);
if (elTypeVals != FLOAT4OID) {
elog(ERROR, "DOC2VEC: INVALID INPUT DATA TYPE");
PG_RETURN_NULL();
}
int16 typeLenVals = 0;
bool typeByValVals = false;
char typeAlignVals = char(0);
get_typlenbyvalalign(elTypeVals, &typeLenVals, &typeByValVals, &typeAlignVals);
Datum *inputVals;
bool *nullVals;
int nVals;
deconstruct_array(_docVector, elTypeVals, typeLenVals, typeByValVals, typeAlignVals, &inputVals, &nullVals, &nVals);
pfree(inputVals);
pfree(nullVals);
PG_RETURN_NULL();
}
}
Thanks to PostgreSQL developers, they explained me the difference in Linux and OSX linking of external functions.
Instead of -shared you need -bundle -bundle_loader /path/to/postgres,
and there are some other linker flags that are advisable too.
Also, PostgreSQL expects the file extension for loadable modules to be .so even on OSX.
It's usually better to use PGXS to build extensions, instead of
learning such details for yourself.
Or you can crib from one of the extensions in the contrib/
source tree.
If you need to link, you will need the -L flag to point the linker to the path where the postgres libraries are located (the linker equivalent of the -I compiler flag). and the -l flag to actually link the libraries (one for each library); the library name without the lib prefix and without the extension.
In your case, something along the lines of -L/usr/local/Cellar/postgresql/9.5.3/lib -lpostgres
(There's a variety of library files in that directory; try -lpg to start with.
The reference to _pfree in your error message also suggest to link pgcommon, which contains the implementation of pgree (at least when using nm libpgcommon.a).
)
You may want to read up a bit more on compiling and linking in general; you do the right thing for compiling with the -I flag, but oddly then miss out on the linking step. And learning about make and Makefiles will come in handy.
I also don't understand the extern "C" { part for a .c file, which is clearly a C-only file. extern "C" is usually used in C++ files for compatibility with C.

Cannot compile LibOTR

I am trying to use libotr but I have the following problem when attempting to compile a very basic library initialisation.
#include <libotr/proto.h>
int main(int argc, char const *argv[])
{
OTRL_INIT;
// OtrlUserState userstate = otrl_userstate_create();
return 0;
}
I am compiling it with the following command:
g++ main.cpp -o main -L /usr/local/lib/ -lotr
But for some reason I am getting:
Undefined symbols for architecture x86_64:
"otrl_init(unsigned int, unsigned int, unsigned int)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [bin/bin] Error 1
I explicitly checked and the library does indeed has the following symbols.
After a quick observation I noticed that libotr is using the C type name mangling and the problem is resolved just by adding the following lines to the library's include clause:
extern "C" {
#include <libotr/proto.h>
}
If you have similar problem just list the symbols of a library with the nm utility and check whether the symbol names begin with one or two underscores: _foo is C style, while __foo is C++ style.
P.S. I posted this since it took me a while to figure it out. I hope this question + answer would save you some time.

C++ will not run on my mac, symbol(s) not found for architecture x86_64

Heres the code, extremely basic Cpp
#include <iostream>
using namespace std;
int main(){
cout << "C++ is FUN!\n";
return 0;
}
The symbols that can not be found are "std" trying to use the name space, and "cout".
the full error message is.
make: *** [FirstProject] Error 1 FirstProject C/C++ Problem
Symbol 'cout' could not be resolved FirstProgram.cpp /FirstProject line 5 Semantic Error
Symbol 'std' could not be resolved FirstProgram.cpp /FirstProject line 2 Semantic Error
symbol(s) not found for architecture x86_64 FirstProject C/C++ Problem
EDIT:
here is the whole linker line:
make all
Building target: FirstProject
Invoking: Cross G++ Linker
g++ -o "FirstProject" ./FirstProgram.o
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [FirstProject] Error 1
Does anyone know what could potentially be the problem?
You are not compiling using a C++ compiler.
If you are using the GNU toolchain then use g++ and not gcc.
You need to compile then link:
g++ -c -o FirstProgram.o FirstProgram.c
g++ -o FirstProject FirstProgram.o
Or you can combine into one statement:
g++ -o FirstProject FirstProgram.c

Compile error: Undefined symbols: "_main", referenced from: start in crt1.10.5.o

I have the following code:
#include <iostream>
using namespace std;
class testing{
int test() const;
int test1(const testing& test2);
};
int testing::test() const{
return 1;
}
int testing::test1(const testing& test2){
test2.test();
return 1;
}
after compilation, it gives me the following error:
Undefined symbols:
"_main", referenced from:
start in crt1.10.5.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Why is it complaining about main? Can't i declare main in another file and include this one?
Thanks a lot!
You have tried to link it already:
g++ file.cpp
That will not only compile it, but try to already create the executable. The linker then is unable to find the main function that it needs. Well, do it like this:
g++ -c file.cpp
g++ -c hasmain.cpp
That will create two files file.o and hasmain.o, both only compiled so far. Now you can link them together with g++:
g++ -omy_program hasmain.o file.o
It will automatically figure out that those are files already compiled, and invoke the linker on them to create a file "my_program" which is your executable.
If you declare the main function in another file, then you must compile the two files separately, and then link them into 1 executable.
Unless you include the entire contents of the file from the file with the main function, that will work too, though a bit odd. But, if you do this then you have to make sure that you compile the file which has the main() function.
Try these (they worked for me):
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
brew install mingw-w64
Please save your code before running.
For reference refer to this video