Using GSL with cygwin g++ - cygwin

trying to get the Gnu Scientific Library (gsl) to work in cygwin g++.
Cygwin is installed and updated with all default parameters and includes gsl:runtime, gsl-apps and gsl-doc. I am trying the example program given in the gsl website:
http://www.gnu.org/software/gsl/manual/html_node/An-Example-Program.html
include
#include <gsl/gsl_sf_bessel.h>
int
main (void)
{
double x = 5.0;
double y = gsl_sf_bessel_J0 (x);
printf ("J0(%g) = %.18e\n", x, y);
return 0;
}
Would anyone be so kind as to give me a version of the above program that actually works with g++? The header file is nowhere to be found with this default installation. How do I access the dll?
I also tried to install the non-default 'gsd-devel' (the developper tools), which gives me access to the header file but when I compile I am getting "Undefined reference to 'gsl__sf_bessel_J0'", even though the header file is found.
Any help greatly appreciated!

I am new to CygWin & GSL as well, and I after some research, I think the answer lies in the fact that the required libraries are not being linked. There is a clever little tool which comes with GSL called gsl-config. You can use this to get the linking information to the libraries. So in your case, the code:
#include <gsl/gsl_sf_bessel.h>
#include <stdio.h>
int
main (void)
{
double x = 5.0;
double y = gsl_sf_bessel_J0 (x);
printf ("J0(%g) = %.18e\n", x, y);
return 0;
}
can be compiled using g++ bessel.cpp -lm -lgsl -o bessel.out -L/usr/bin where the -lm -lgsl -L/usr/bin bit is the output of typing gsl-config --lib-without-cblas. Test using ./bessel.out.
Hope this helps, T

Related

Pytorch Tensor::data_ptr<long long>() not working on Linux

I cannot link my program to pytorch under Linux, get the following error:
/tmp/ccbgkLx2.o: In function `long long* at::Tensor::data<long long>() const':
test.cpp:(.text._ZNK2at6Tensor4dataIxEEPT_v[_ZNK2at6Tensor4dataIxEEPT_v]+0x14): undefined reference to `long long* at::Tensor::data_ptr<long long>() const'
I am building a very simple minimal example:
#include "torch/script.h"
#include <iostream>
int main() {
auto options = torch::TensorOptions().dtype(torch::kInt64);
torch::NoGradGuard no_grad;
auto T = torch::zeros(20, options).view({ 10, 2 });
long long *data = (long long *)T.data<long long>();
data[0] = 1;
return 0;
}
The command used to build it:
g++ -w -std=c++17 -o test-torch test.cpp -D_GLIBCXX_USE_CXX11_ABI=1 -Wl,--whole-archive -ldl -lpthread -Wl,--no-whole-archive -I../libtorch/include -L../libtorch/lib -ltorch -ltorch_cpu -lc10 -Wl,-rpath,../libtorch/lib
Pytorch has been downloaded from the link https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-1.7.0%2Bcpu.zip and unzipped (so I have the libtorch folder next to the folder with test.cpp).
Any ideas how to solve this problem? Same program works just fine under Visual C++.
P.S. I know pytorch is kind of designed for cmake, but I have zero experience with cmake and no desire to write a cmake-based build system for my app. Also, the examples they give are seemingly supposed to only work if pytorch is "installed" in the system. So I cannot just download the .zip with libs? And if I "install" it (e.g. from sources or in whatever other way) on an AVX512 system, will the binary I link to it and distribute to end-users work on non-AVX512? The documentation is completely incomprehensible for newbies.
UPDATE: I tried to do this via CMake following the tutorial https://pytorch.org/cppdocs/installing.html and got exactly the same error. Specifically, I renamed my directory to example-app and the source file to example-app.cpp. Then I created CMakeLists.txt in this directory with the following contents:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
Then
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH=../../libtorch ..
cmake --build . --config Release
And here's the output:
CMakeFiles/example-app.dir/example-app.cpp.o: In function `long long* at::Tensor::data<long long>() const':
example-app.cpp:(.text._ZNK2at6Tensor4dataIxEEPT_v[_ZNK2at6Tensor4dataIxEEPT_v]+0x14): undefined reference to `long long* at::Tensor::data_ptr<long long>() const'
Makes me think, maybe I forgot to include some header or define some variable?
Oh, this is all on Mint 19.2 (equivalent to Ubuntu 18.04), g++ version is 7.5.0, glibc is 2.27. Compiling with g++-8 gives the same result.
This is not a cmake-related error, it's just how the library was implemented. I do not know why, but it appears that the specialization of T* at::Tensor::data<T> const with T = long long was forgotten/omitted.
If you want to get your signed 64-bits pointer, you can still get it with int64_t:
auto data = T.data<int64_t>();
It's good practice to use these types for which the size is explicit in general, in order to avoid compatibility issues.

How to build and use libicu in webassembly

I am interested in the word iterator of the ICU63 library in a JavaScript project (in a browser). So after reading the docs, I believe that ICU uses UTF-16 by default which is the same than JS and it would avoid me to encode JS strings into something else.
First step was to build a wrapper with the only function that I need (I don't know yet if it is working):
#include "emscripten.h"
#include <string.h>
#include <unicode/brkiter.h>
#include <unicode/unistr.h>
#include <unicode/errorcode.h>
using namespace icu_63;
EMSCRIPTEN_KEEPALIVE
int splitWords(const char *locale, const uint16_t *text, uint16_t *splitted) {
//Note that Javascript is working in UTF-16
//icu::
UnicodeString result = UnicodeString();
UnicodeString visibleSpace = UnicodeString(" ");
int32_t previousIdx = 0;
int32_t idx = -1;
//Create a Unicode String from input
UnicodeString uTextArg = UnicodeString(text);
if (uTextArg.isBogus()) {
return -1; // input string is bogus
}
//Create and init the iterator
UErrorCode err = U_ZERO_ERROR;
BreakIterator *iter = BreakIterator::createWordInstance(locale, err);
if (U_FAILURE(err)) {
return -2; // cannot build iterator
}
iter->setText(uTextArg);
//Iterate and store results
while ((idx = iter->next()) != -1) {
UnicodeString word = UnicodeString(uTextArg, idx, idx - previousIdx);
result += word;
result += visibleSpace;
previousIdx = idx;
}
result.trim();
//The buffer contains UTF-16 characters, so it takes 2 bytes per point
memcpy(splitted, result.getBuffer(), result.getCapacity() * 2);
return 0;
}
It compiles and looks good except that symbols are missing when trying to link because I have no clue about how to proceed.
LibICU looks to need a lot of builtin data. For my case, the frequency tables are mandatory for using the word iterator.
Should I try to copy my wrapper into the source folder and try to figure out how to use emconfigure. Or is it possible to link the libicu when I try to compile my wrapper? Second option looks like a waste of data as I am not interested by the larger portion of the lib.
In my experience, the easiest way to deal with libraries is to build the libraries using emconfigure/emmake first then link them statically with your own code. Like the following:
$ emcc your_wrapper.cpp \
your_compiled_libICU_static_lib.a \
-o result.js
Compiling libraries using emconfigure/emmake sometimes quite hard because you may need to modify the source code in order to make it work in WebAssembly.
But...Good news! Emscripten provides ports of some popular and complicated libraries and ICU is one of them.
You can compile your code without compiling ICU yourself using -s USE_ICU=1 flag:
$ emcc your_wrapper.cpp \
-s USE_ICU=1 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-std=c++11
The caveats is that Emscripten ICU port is ICU 62. So you need to change using namespace icu_63; to using namespace icu_62;
While -s USE_ICU=1 is convenient when you can easily modify your build flags, I've found it more convenient to install ICU from source, because I also had to build other libraries whose configure/make/build processes do not play nicely with -s USE_ICU=1 (at least not without plenty of modification) and instead expect a more traditional way to find and link to the icu libs.
Unfortunately, building libicu does not seem to work with the usual configure && make install without some tweaking. To do that, first you have to do a "regular" native build (./configure && make) to create the necessary local files.
Then, if you do not need PTHREADS, you can build in a fairly straightforward manner as follows, assuming /opt/wasm is your PREFIX.
PKG_CONFIG_LIBDIR=/opt/wasm/lib/pkgconfig emconfigure ./configure --prefix=/opt/wasm --with-cross-build=`pwd` --enable-static=yes --enable-shared=no --target=wasm32-unknown-emscripten --with-data-packaging=static --enable-icu-config --enable-extras=no --enable-tools=no --enable-samples=no --enable-tests=no
emmake make clean install
If you do need PTHREADS for some downstream consumer of the lib, you might have to rebuild the lib with that enabled from the get-go. This is trickier because configure scripts will break when they do their tests that require building and running C snippets, due to warnings about requiring additional node flags (see https://github.com/emscripten-core/emscripten/issues/15736), which to the configure scripts mean an error. The easiest solution I found was to temporarily modify make_js_executable in emcc.py:
...
with open(script, 'w') as f:
# f.write('#!%s\n' % cmd); ## replaced with the below line
f.write('#!%s --experimental-wasm-threads --experimental-wasm-bulk-memory\n' % cmd)
f.write(src)
...
With that hack done, you can proceed to something like the below (though possibly, not all of those thread-related flags are absolutely needed)
CXXFLAGS='-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -O3 -pthread' CFLAGS='-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -O3 -pthread' FORCE_LIBS='-s PTHREAD_POOL_SIZE=8 -s USE_PTHREADS=1 -pthread -lm' PKG_CONFIG_LIBDIR=/opt/wasm/lib/pkgconfig emconfigure ./configure --prefix=/opt/wasm --with-cross-build=`pwd` --enable-static=yes --enable-shared=no --target=wasm32-unknown-emscripten --with-data-packaging=static --enable-icu-config --enable-extras=no --enable-tools=no --enable-samples=no --enable-tests=no
emmake make clean install
After that, set your emcc.py back to its original state. Note that if you try to build the tools, they will fail-- I haven't yet found a solution to that-- but the lib does successfully install with the above.

Undefine references of functions from CUDA

I am looking for a way to use cufft.h a CUDA toolkit which perform GPU parallelization of fast fourier transform.
First of all, I downloaded cuda library and cufft through synaptic.
Then I used the sample program from the cufft documentation from NVidia.
my cuda library is located at /usr/local/cuda-9.0 on my laptop.
I added those include :
1 #include <iostream>
2 #include <cstdio>
3 #include "/usr/local/cuda-9.0/include/cuda.h"
4 #include "/usr/local/cuda-9.0/include/cuda_runtime_api.h"
5 #include "/usr/local/cuda-9.0/include/cufft.h"
I compile like this :
g++ -Wall main.cpp -o main
and get undefine references error for each cuda-like functions (cudaMalloc,cudaGetLastError, etc...)
I am pretty young about library implementation and I don't understand what should I do to include properly this cuda-cufft library...
The nvidia documentation talk about filename.cu but I don't know what this is about...
Thank you for your time :)
n.b : I added cuda.h and cuda_runtime_api.h after reading a forum (I forgot which it was). Apparently, only cuda_runtime_api.h is necessary (I tried without cuda.h and get the same errors).
Here is a complete sample code (that doesn't do anything useful) and a sample g++ compile command that will properly compile and link the code:
$ cat t1338.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cuda_runtime.h>
#include <cufft.h>
int main() {
size_t work_size;
int fft_sz = 32; // Size of each FFT
int num_ffts = 1; // How many FFTs to do
cufftComplex *in_buf_h, *in_buf_d, *out_buf_d;
// Allocate buffers on host and device
in_buf_h = new cufftComplex[fft_sz*num_ffts];
cudaMalloc(&in_buf_d, fft_sz*num_ffts*sizeof(cufftComplex));
cudaMalloc(&out_buf_d, fft_sz*num_ffts*sizeof(cufftComplex));
cudaMemset(out_buf_d, 0, fft_sz*num_ffts*sizeof(cufftComplex));
// Fill input buffer with zeros and copy to device
memset(in_buf_h, 0, fft_sz*num_ffts*sizeof(cufftComplex));
cudaMemcpy(in_buf_d, in_buf_h, fft_sz*num_ffts*sizeof(cufftComplex), cudaMemcpyHostToDevice);
// Plan num_ffts of size fft_sz
cufftHandle plan;
cufftCreate(&plan);
cufftMakePlan1d(plan, fft_sz, CUFFT_C2C, num_ffts, &work_size);
// Execute the plan. We don't actually care about values.
cufftExecC2C(plan, in_buf_d, out_buf_d, CUFFT_FORWARD);
// Sync the device to flush the output
cudaDeviceSynchronize();
return 0;
}
$ g++ t1338.cpp -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lcudart -lcufft
$
Your include statements are probably OK as-is, but I have used a format that says "search on the standard path for this file" and then I identify an addition to the standard path with
-I/usr/local/cuda/include
However your compile command is definitely missing the necessary link apparatus. You need to specify where to find the libraries (the path) with -L and then indicate the specific libraries to include, which are both the CUDA runtime library (-lcudart) and also the CUFFT library (-lcufft):
-L/usr/local/cuda/lib64 -lcudart -lcufft
The CUDA toolkit normally gets installed with sample codes which will have sample Makefiles you can inspect, or just compile those projects to see typical compilation command usage.
As I mentioned, this source code is incomplete. It doesn't do anything useful. It is just to demonstrate proper compilation behavior. In particular, I've omitted proper error checking, which I recommend you include in your actual codes.
Depending on whether your install created a symbolic link or not, you may need to change the above paths to:
-I/usr/local/cuda-9.0/include
and
-L/usr/local/cuda-9.0/lib64 -lcudart -lcufft

Linking GSL library to RcppGSL on Windows machine

I try to link the GSL library to the RcppGSL package. The following is my test function:
# colNorm.cpp
// [[Rcpp::depends(RcppGSL)]]
#include <RcppGSL.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_blas.h>
extern "C" SEXP colNorm(SEXP sM) {
try {
RcppGSL::matrix<double> M = sM; // create gsl data structures from SEXP
int k = M.ncol();
Rcpp::NumericVector n(k); // to store results
for (int j = 0; j < k; j++) {
RcppGSL::vector_view<double> colview = gsl_matrix_column (M, j);
n[j] = gsl_blas_dnrm2(colview);
}
M.free() ;
return n; // return vector
} catch( std::exception &ex ) {
forward_exception_to_r( ex );
} catch(...) {
::Rf_error( "c++ exception (unknown reason)" );
}
return R_NilValue; // -Wall
}
The GSL library is succesfully linked to the RcppGSL if the following command does not throw a compiler error:
sourceCpp("colNorm.cpp")
Since I am using Windows machine, I need to define environment variables such that RcppGSL knows where the GSL library is located.
I tried editing the environment variable, but the following compiler error shows that the package is still unable to find the GSL library:
g++ -m64 -I"C:/PROGRA~1/R/R-31~1.1/include" -DNDEBUG -I"C:/CodeLibrary/lib"/include - I"C:/PROGRA~1/R/R-31~1.1/library/Rcpp/include" -I"C:/PROGRA~1/R/R-31~1.1/library/RcppGSL/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c colNorm.cpp -o colNorm.o
g++ -m64 -shared -s -static-libgcc -o sourceCpp_38624.dll tmp.def colNorm.o -LC:/CodeLibrary/lib/lib -lgsl -lgslcblas -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lRblas -lgfortran -Ld:/RCompile/CRANpkg/extralibs64/local/lib/x64 -Ld:/RCompile/CRANpkg/extralibs64/local/lib -LC:/PROGRA~1/R/R-31~1.1/bin/x64 -lR
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgsl
c:/program files/r/r-3.1.1/rtools/gcc-4.6.3/bin/../lib/gcc/i686-w64-mingw32/4.6.3/../../../../i686-w64-mingw32/bin/ld.exe: cannot find -lgslcblas
collect2: ld returned 1 exit status
I set an environment variable LIB_GSL equal to "C:/CodeLibrary/lib". In the first line, the compiler takes my environment variable and adds /include. In the second line, the compiler adds /lib. Those locations do not exist on my C drive, maybe that's the reason why it cannot find the library.
I would be really happy, if someone with a lot of compiler experience could show how to successfully link a 3rd party library to a package on Windows machine.
Maybe more environment variables need to be defined?
Thanks Dirk for your handholding! I got it finally up and running.
Three things have to be done:
1) Download the local300 folder from your link and allocate folder on your drive. The path cannot contain any whitespaces, i.e. C:/Program Files/local300 will not work but
C:/local300 will work
2) Set the environment variable LIB_GSL equal to this path, e.g. LIB_GSL to C:/local300
3) The compiler looks at LIB_GSL/lib for libgsl.a and libgslcblas.a (-lgsl and -lgslcblas). However, in LIB_GSL/lib are subfolders i386 and x64. I didn't know how to change the place the compiler looks for the files, thus I copied everything from inside x64 and put it into LIB_GSL/lib folder (one folder level above).
This allows RcppGSL to compile code without errors.
Look at this page which is (after a link or two) pointed to from the R Installation and Administration manual, appendix D for Windows.
Expand that, see where it puts headers and the library for GSL and adjust LIB_GSL accordingly.
This is what CRAN itself uses, so we know it works.

static compile glfw

I'm trying to compile glfw as static link on Linux Mint (based on Ubuntu 10.04) using GCC 4.4.3.
Inside my project directory i got "external/glfw" which contains glfw 2.7.1 source. I've compiled it by running "make x11-install" which gives:
/usr/local/include/GL/glfw.h
/usr/local/lib/libglfw.a
/usr/local/lib/pkgconfig/libglfw.pc
i also got this simple code in test.c:
#include <stdio.h>
#include <stdlib.h>
#include "external/glfw/include/GL/glfw.h"
int main( int argc, char const* argv[] )
{
if( !glfwInit() ){
fprintf( stderr, "glfwInit Failed\n" );
}
glfwOpenWindowHint( GLFW_FSAA_SAMPLES, 4 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MAJOR, 3 );
glfwOpenWindowHint( GLFW_OPENGL_VERSION_MINOR, 1 );
glfwOpenWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
// Open a window and create its OpenGL context
if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW )){
fprintf( stderr, "glfwOpenWindow failed\n" );
glfwTerminate();
return -1;
}
return 0;
}
i'm trying to compile glfw as static link and compiled the code using gcc with flags:
/usr/bin/gcc `pkg-config --cflags libglfw` -o test test.c \
`pkg-config --libs libglfw` -lXrandr -lX11 -lGLU -lGL -pthread -lm
and it doesn't give me any error. but when i try to execute the binary it shows that i've failed to call glfwOpenWindow.
could any one help me please? thank you for your time guys!
cheers!
P
EDIT 1: I think the problem lies with the linking process and not the code. Because if i have libglfw2 and libglfw-dev installed (ubuntu packages), then the executable runs just fine. What i want here is to have glfw statically linked and not to rely on distro package share libs for the binary to run.
EDIT 2 as per datenwolf suggestion i tried to debug with gdb. i never use gdb before but i use perl debugger a lot. somehow they share a lot of similarities. i recompile glfw and my test.c with -ggdb.
flowing with gdb it shows that my code goes into glfwOpenWindow() which is in "window.c" in glfw source code. since i'm new to gdb i don't know how to evaluate expression or get the value of variables. based on quick search on google all i know is "whatis" to see the date type. but i think my code stops when it reached line 484 in "window.c"
if( wndconfig.glProfile &&
( wndconfig.glMajor < 3 || ( wndconfig.glMajor == 3 && wndconfig.glMinor < 2 ) ) )
{
// Context profiles are only defined for OpenGL version 3.2 and above
return GL_FALSE;
}
now i'm not sure how come using static link glfw thinks i'm not on OpenGL 3.2 and above, while having libglfw2 installed it works just fine?
thanks for your help guys! especially datenwolf!
EDIT 3 Thanks for the help guys. After some help from people in stackoverflow and old nabble I manage to write it down what needs to be done to statically linked GLFW and GLEW and put it on http://www.phacks.net/static-compile-glfw-and-glew/
So your error is that the call to glfwOpenWindow failed? No unresolved symbol or shared object not found messages before even main() gets called? Then you successfully linked against GLFW statically.
I think your problem lies in the parameters you pass to glfwOpenWindow:
glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW )
So you're requesting zero red, green or blue bits per channel, but 32 depth bits. I doubt your system supports that. I'd try
glfwOpenWindow( 1024, 768, 8,8,8,0, 24, 8, GLFW_WINDOW )
that's what most systems support well.
Your example program requests OpenGL 3.1 and a context profile. Profiles are only defined for OpenGL 3.2 and above, which is most likely why glfwOpenWindow fails in this case. To fix this, either request a version above or equal to 3.2, or remove the request for a context profile.
For more information about modern OpenGL context creation with GLX, upon which this part of GLFW is a thin layer, see
http://www.opengl.org/registry/specs/ARB/glx_create_context.txt .

Resources