this guide may be outdated for MacOS versions beyond 10.14 Mojave (and implied Xcode versions)
Table of Contents
The GNU Scientific library (GSL) is a powerful C/C++ numerical library.
This guide assumes you already have a working C/C++ compiler - check by entering gcc --version in Terminal. OSX's default Clang compiler is fine, otherwise this page describes how to install gcc 4.9.
Apparently GSL can be installed through Homebrew via
brew install gslthough installing it manually is just as simple, which we now describe.
- Download gsl-latest.tar.gz from the GSL ftp site and unzip it anywhere (e.g. /Downloads)
- Open the unzipped
gslfolder in Terminal (e.g.cd ~/Downloads/gsl-2.4 - Run
sudo ./configure && make && make install
If the above gives a "permission denied" error, instead try
sudo make clean
sudo chown -R $USER .
./configure && make
make installYou'll now be able to include GSL into your code from anywhere.
sudo apt-get install libgsl-devYou'll now be able to include GSL into your code from anywhere.
Oh wait, explore the use of...
module load gsl/1.15 module load gsl/1.16 module load gsl/2.1
In the ARCUS terminal, download GSL anywhere
wget "ftp://ftp.gnu.org/gnu/gsl/gsl-latest.tar.gz"and unzip it
tar -xf gsl-latest.tar.gzthen open the new folder e.g.
cd gsl-2.4To install without admin permissions, we'll keep the GSL files in a folder called gsl .
Note some newer versions off gcc (e.g. 8) seem incompatible. Use an older version (e.g. gcc/5.3.0) and first call
module load binutils libtoolReplace YOURUSERNAME below with your ARCUS-B username (e.g. abcd1234) and run
export gsdir=/data/oums-quantopo/YOURUSERNAME/gsl
mkdir $gsdir
./configure --prefix=$gsdir && make && make install
We'll need to remember this location when compiling
Compiling GSL with our code is easy; we simply add library flags -lm -lgsl -lgslcblas to our calls to gcc.
For example, we'd adapt the QuEST makefile to include
#
# --- libraries
#
LIBS = -lm -lgsl -lgslcblasExactly as above for OSX.
Before compiling on ARCUS-B, we must extend LD_LIBRARY to include our gsl folder (replace YOURUSERNAME below)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/data/oums-quantopo/YOURUSERNAME/gsl/lib
This need only be done once each time we SSH into ARCUS.
Our compilation must additionally include the -lm -lgsl -lgslcblas libraries and flags -I/data/oums-quantopo/YOURUSERNAME/gsl/include and -L/data/oums-quantopo/YOURUSERNAME/gsl/lib.
For example, we'd modify the QuEST makefile to include
#
# --- libraries
#
LIBS = -lm -lgsl -lgslcblasand just after that, insert
#
# --- GSL link
#
GSL_INCLUDE = -I/data/oums-quantopo/YOURUSERNAME/gsl/include
GSL_LINK = -L/data/oums-quantopo/YOURUSERNAME/gsl/lib
and modify the rules list
#
# --- rules
#
%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_OMP) $(GSL_INCLUDE) -c $<
%.o: $(QUEST_DIR)/%.c
$(CC) $(CFLAGS) $(CFLAGS_OMP) $(GSL_INCLUDE) -c $<
and finally the build commands
#
# --- build
#
default: $(EXE)
$(EXE): $(OBJ)
$(CC) $(CFLAGS) $(CFLAGS_OMP) $(GSL_INCLUDE) -o $(EXE) $(OBJ) $(LIBS) $(GSL_LINK)
See a complete example of my QuEST & gsl makefile here.
The many different GSL functions are available in different source files.
For example, to use the matrix, linear equation solver, and matrix multiplication functionalities, respectively include
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_linalg.h>
#include <gsl/gsl_blas.h>View available functions and their necessary header files can be found here.
Sometimes GSL is so powerful, it's confusing to figure out how to do some simple things. So here are some examples
Matrices are dynamic objects, indexed from 0, which must be allocated before, and freed after, their use.
#include <gsl/gsl_matrix.h>gsl_matrix* myMatr = gsl_matrix_alloc(10,20);
// matrix of 8s
for (int i=0; i < 10; i++)
for (int j=0; j < 20; j++)
gsl_matrix_set(myMatr, i, j, 8);
int elem = gsl_matrix_get(myMatr, 3, 4);
gsl_matrix_free(myMatr);For a vector, replace matrix above with vector.
GSL's matrix operations come under 'Basic Linear Algebra Subprograms' (BLAS), listed here
#include <gsl/gsl_blas.h>To multiply matrices matrA and matrB and store the result in matrC (all of which must be previously allocated by gsl_matrix_alloc), call:
gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, matrA, matrB, 0.0, matrC); In the name gsl_blas_dgemm, the d refers to double-precision matrices, and the final m refers to matrix. The other arguments are explained here.
To multiply a matrix matrA and a vector vecB and store the result in vecC (previously allocated by gsl_matrix_alloc and gsl_vector_alloc), call:
gsl_blas_dgemv(CblasNoTrans, 1.0, matrA, vecB, 0.0, vecC);Linear algebra operations are provided by
#include <gsl/gsl_linalg.h>Here's how to solve A x = b (or matrA vecX = vecB) for x by LU decomposition, which involves creating an intermediate permutation structure
gsl_permutation* perm = gsl_permutation_alloc(vecB->size);
int swaps;
gsl_linalg_LU_decomp(matrA, perm, &swaps);
gsl_linalg_LU_solve(matrA, perm, vecB, vecX);
gsl_permutation_free(perm);By default, a numerical error (e.g. attempting to invert a non-invertible matrix) will cause an error message and execution to stop. To instead detect and handle numerical errors, include
#include <gsl/gsl_errno.h>and call
gsl_set_error_handler_off();before calling any numerical functions. Then functions (e.g. gsl_linalg_LU_solve) will return an integer 0 for success, otherwise an errorcode of those listed here (e.g. GSL_ERANGE, GSL_EIVANL).
Thank you for these clear, concise, and correct install instructions on OSX.