How compile on linux KNN CUDA? - c

Recently, I found knn CUDA which is a group of Mex file that implement knn search based on brute force, but in the README.md I have not found the way to compile this files in matlab using a linux distribution. I would appreciate ideas about how cope with this issue.

I'm the author of this kNN code :)
Back in 2008, the code was written using the Windows XP OS.
Since I provide the source code, you should be able to produce linux mex files.
In the ReadMe, I give the following command line for Windows :
nvmex -f nvmexopts.bat knn_cuda_with_indexes.cu -I'C:\CUDA\include' -L'C:\CUDA\lib' -lcufft -lcudart -lcuda -D_CRT_SECURE_NO_DEPRECATE
Adapt it for your Linux distribution to generate your mex file.
A lot of things may have changed in 5 years so you may have to modify a few things.
However, the feedbacks I got from users indicate that it works just fine.
Try also to read about how to compile a CUDA code under Linux.
I guess NVidia provides a pretty nice tutorial.

You can also compile cuda+mex without nvmex. In MATLAB command, simply run the following two lines
>> !nvcc -c yourfile.cu -Xcompiler -fPIC -I$matlabroot/extern/include -I$matlabroot/toolbox/distcomp/gpu/extern/include
>> mex yourfile.o -L/usr/local/cuda/lib64 -L$matlabroot/bin/glnxa64 -lcudart -lcufft -lmwgpu
replace $matlabroot with appropriate path. (Note that ! invoke system command in matlab)
The first line create object file and then mex links library.
You might have to modify your CUDA path to /usr/loca/cuda-6.0/ or /usr/local/cuda-YOUR_VERSION/. Also for the cuda library /usr/local/cuda/lib64 or /usr/local/cuda/lib Please check.
If you want to optimize your code simply put -O3 -DNDEBUG
>> !nvcc -O3 -DNDEBUG -c yourfile.cu -Xcompiler -fPIC -I$matlabroot/extern/include -I$matlabroot/toolbox/distcomp/gpu/extern/include
the library link command is same.
Also please note that additional include path -I$path and library path -L$path or library -l$library might be required to suit your need.

Related

command line prompt command (want to understand what its doing)

I am doing the CS50 class, I have installed the cs50.h.
Based on the instructions I used the following command in terminal to compile my simple program and just want to make sure I understand everything im asking terminal to do.
Line is:
gcc -g hello.c -o hello -lcs50 -lm
I know the following*: gcc =
gcc = gnu compiler for C
-g = generate source-level debug information
Hello.c = name of the file we want to compile
-o = write output file
hello = our output file name
Can anyone tell me what -lcs50 and -lm are? My guess is that its calling on the library lcs50 in (-lcs50) but again this is a guess and would like to know for sure.
Everything works as it should with no issues
Thanks,
Mostly correct.
-o is not required to generate the output file, it's only needed to customize the name. (-o and the following name can only appear together).
-lcs50 means "link the library called cs50", not lcs50. It will try to find this file using several different name patterns, e.g. libcs50.so (on Linux), [lib]cs50.dll[.a] (on Windows), libcs50.a (on both), something else on Mac.
-lm links the standard math library, but I don't think you need to manually specify it on most modern GCC distributions.
Yes. For -lm, it's for the maths library, which is not linked by default. This is explained well at Why do you need an explicit `-lm` compiler option.

Compiling cmocka on windows

I'm trying to compile a simple unit test on my windows machine.
When I'm trying to compile my test I'm using the shared library flag.
gcc -c -L./bin/ -lcmocka .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o -o main
But the second line throws this error:
undefined reference to `_cmocka_run_group_tests'
However, if I'm compiling using directly the cmocka.c file which I downloaded from their git it works fine:
gcc -c .\lib\cmocka.c .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o .\cmocka.o
What am I doing wrong in the first compilation?
In addition, I would happy to understand the difference between the two compilations. Which one is the better practice?
Thank you
In order to compile your code, the compiler does not need to know where to look for the library. It's enough if the compiler "finds" the declarations of the functions which are usually in the header files provided by the library.
This step is done in the first line of your compilation procedure (maybe you need to specify the folder to the header files by adding -Ipath/to/headers/):
gcc -c .\Test.c .\src\some_module.c
The library itself is "combined" with your code during the linking step, which is done during your second compilation step. Here you need to specify the library (and its path via -Lpath/to/library, if the linker does not find the library on its own):
gcc .\Test.o .\some_module.o -o main -L./bin/ -lcmocka
You should definitely not use your second approach and compile the library by yourself.

How to compile a C program without knowing the include files

I have some example C code that I'm looking to adapt to suit my needs. Before then I'm trying to compile the example as it is. The C code contains a #include reference, and I can find the .h file in an 'inc' directory. There is also a corresponding 'lib' directory. I am struggling to find the command line I need to compile the code.
So far I've managed to get to the following;
gcc -o amqsinqa -I/opt/mqm/inc amqsinqa.c -L/opt/mqm/lib -lcmqc
But it 'cannot find -lcmqc'. I've looked in lib and quite correctly there is no cmqc. How do I determine what -l option I need here?
The code looks fairly simple, there is the include reference;
#include <cmqc.h>
And the call itself;
MQCONN(QMgrName,&Hcon,&CompCode,&CReason);
If I omit the -l option from the command line I get;
undefined reference to 'MQCONN'
Which isn't a surprise. MQCONN is present in cmqc.h though.
To try to help others, this reference is useful:
64 bit apps: https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q028490_.htm
32 bit apps:
https://www.ibm.com/support/knowledgecenter/SSFKSJ_9.1.0/com.ibm.mq.dev.doc/q028480_.htm
In summary:
-I is for the product includes, which are (For Linux) usually in /opt/mqm/inc
-L is the path to the libraries in your example which are (For Linux) usually in /opt/mqm/lib (for 32 bit applications) and /opt/mqm/lib64 (for 64 bit
applications)
-l (lower case L) is for the required library/libraries,
and the actual library you need is either:
mqm - server bound C applications (ie -lmqm, which links with libmqm.so)
mqic - client bound C applications (ie -lmqic, which links with libmqic.so)
.. and a suffix of _r if you are building as a threaded application (ie you are linking with -lpthread as well, ie providing -lmqm_r or -lmqic_r which in effect links with libmqm_r.so or libmqic.so)
cmqc.h is the name of the main header file, and there are other cmq*.h headers you can optionally include as well.
If you are using the (stabilized) C++ libraries there's other libraries to include on the command line but that's outside the scope for this answer - see the referenced links
Thanks to all the above for the guidance. Looks like I was missing a few things. This is what I did;
Use nm to identify which .so file contained what I wanted. This returned libmqm.so.
Move that into the -l command, which gave me;
gcc -o amqsinqa -I/opt/mqm/inc amqsinqa.c -L/opt/mqm/lib -lmqm
But it left me with a 'skipping incompatible' warning message followed by a 'cannot find' error message.
Most common Google answer to this issue was a 32/64 bit mismatch, so I searched for a 64 bit version of the same, which ended up being in lib64. So the final compile command is;
gcc -o amqsinqa -I/opt/mqm/inc amqsinqa.c -L/opt/mqm/lib64 -lmqm
You should review the gcc options, in particular the '-m' option,
If you want to build a 32-bit MQ application then you do:
gcc -m32 -o amqsinqa -I/opt/mqm/inc amqsinqa.c -L/opt/mqm/lib -lmqm
If you want to build a 64-bit MQ application then you do:
gcc -m64 -o amqsinqa -I/opt/mqm/inc amqsinqa.c -L/opt/mqm/lib64 -lmqm

ld: warning: directory not found for option: -LC_ID_DYLIB=/usr/lib

I'm using OSX command line gcc and attempting to build a dynamic library. when I do the build I get the following warning. How is it it is not finding this library given /usr/lib is well known? And /usr/lib does indeed exist on my machine
this is what I am using:
gcc -arch i386 cata/*.c -dynamiclib -o build/cata.dylib -LC_ID_DYLIB=/usr/lib
Thanks
the way i solved it was to make it so the string that got stuck in the library (on where to find the library at runtime) was relative to nowhere -- if that makes sense. so it would be forced to use the LD_LOAD_PATH.
I was using the other flags because someone suggested I use them.
so the gcc i ended up using is this:
# my tree is like this
# cata/*.c
# build/*.dylib
#
cd build
gcc -arch i386 ../cata/*.c -dynamiclib -o cata.dylib
Doing this compiles/makes a library in the same directory where it thinks it is 'used' (basically having no path). I am now free to put it somewhere else. When it is later linked at compile time by a different program and then examined using
otool -L
it appears with no path in front of the library name. This is apparently preferable as now when the system goes to try to find it it resorts to looking at the standard libraries and eventually finds it (because I install it to one of the standard locations).
In the original way, otool -L was showing it having a required path of
'build/cata.dylib'
This made it un-findable and which is why i was trying to use the apple documentation to get around the problem.
This doesn't really solve why LC_ID_DYLIB doesn't work. I looked into the Loader.h file (line 643) and it has room for an identifier(0xd), a path, and a structure, so I don't really understand why my path wasn't getting picked up. but its two different topics. Loader.h is runtime and the other is gcc AFAIK. I'm still learning apple.

Linking after using f2c

I used f2c to translate a huge Fortran subroutine into C. The header says the following:
/* fourier.f -- translated by f2c (version 20090411).
You must link the resulting object file with libf2c:
on Microsoft Windows system, link with libf2c.lib;
on Linux or Unix systems, link with .../path/to/libf2c.a -lm
or, if you install libf2c.a in a standard place, with -lf2c -lm
-- in that order, at the end of the command line, as in
cc *.o -lf2c -lm
Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
http://www.netlib.org/f2c/libf2c.zip
*/
I am using ubuntu 10.04. How can I link the object file with libf2c?
You would have to install the libf2c2-dev package -- but as the f2c package already depends on it, all you may need is to add -lf2c to your Makefile.
Are you compiling the resulting C file with gcc? Then add "-lf2c -lm" to the gcc compile command.
Why not compile with a Fortran compiler, such as gfortran? It's easily available for Ubuntu.
By passing -lf2c -lm to the line which will create the executable from the objects. Which compiler are you using on Ubuntu? GCC?
gcc -c fourier.c -lf2c -lm
Could be as simple as that.
Well - no direct answer to your linking problems, but:
Since you're working with Linux: Why don't you compile you fortran code as is and link it directly with the C-code? GCC can do that. Converting the code is of course doable but it is by no way required.
Nils

Resources