Trying to include cblas functions in a new distribution

Hi,

I am writing code for a new distribution and would like to include some functions from blas (I have already got implementations of the distribution and gradients written in a very efficient and robust manner using blas).

At present I am able to compile the new_normal distribution example Stan Math Library: Probability Distributions in a way that I am happy with. As a very minimal working example I have replaced the code to calculate the log density with a very simple function in the file calc_log_like.hpp

double calc_log_likelihood(const int n_y, const int n_mu, const int n_sigma, const double* y,const double* mu,const double* sigma){
    double l_sum = 0.0;
    double y_copy [n_y];

    for (int i = 0; i < n_y; ++i){
        l_sum += -0.5 * std::pow((y[i] - mu[i]) / sigma[0], 2);
    }
    return l_sum;
}

While this code isn’t very general (it only works when mu and y are vectors of same length and sigma is a scalar it does let me test what I want. I can do

#include "calc_log_like.hpp"

inside new_normal.hpp and call the function to calculate the log density. This compiles and works fine during sampling.

Next, the simplest test of using a blas function I could think of was to use the dcopy() so I modified my function to be

extern "C"
{
    #include <cblas.h>
}

double calc_log_likelihood(const int n_y, const int n_mu, const int n_sigma, const double* y,const double* mu,const double* sigma){
    double l_sum = 0.0;
    double y_copy [n_y];

    cblas_dcopy(n_y, y, 1, y_copy, 1);

    for (int i = 0; i < n_y; ++i){
        l_sum += -0.5 * std::pow((y_copy[i] - mu[i]) / sigma[0], 2);
    }
    return l_sum;
}

I then use the make/local file with the following line

CXXFLAGS+= -L /usr/lib/x86_64-linux-gnu/atlas/ -lcblas

I am using ubuntu and have used apt-get install libatlas-base-dev to get blas

When I try to compile the model file I get the error

in function `calc_log_likelihood(int, int, int, double const*, double const*, double const*)':
ssm.hpp:(.text+0x430): undefined reference to `cblas_dcopy'

How can I link the blas functions correctly?

For linking you want to use LDFLAGS, try instead:

LDFLAGS+= -lcblas

If you’ve installed ATLAS through apt then the library and its objects should already be in the path that the compiler checks, so you don’t need to manually specify the path to the library (I think)

Thanks for the fast response.

Can i just add

LDFLAGS+= -lcblas

below the CXXFLAGS line in make/local? I tried doing that with both -lblas and -lcblas and neither option worked. Also tried leaving in

CXXFLAGS+= -L /usr/lib/x86_64-linux-gnu/atlas/

In case that was required. If that should have worked, any other ideas what I might need to do?

Ah I was close but a little off, it’s LDLIBS, not LDFLAGS:

LDLIBS += -lcblas

That did the trick. Thank you very much. Also, you were correct and I did not need to specify the path to the library.

1 Like