Error linking clang++ with dlib and intel mkl

1.1k views Asked by At

Here is a small program that incorporates a call to an Intel MKL library function and DLIB's optimization routine find_min_using_approximate_derivatives.

The code runs perfectly when compiled with the intel C++ compiler: icpc using the invocation:

    icpc main.cpp -I /Users/Username/Code/dlib-18.16 -DDLIB_USE_BLAS -I$MKLROOT/include -L$MKLROOT/lib/ -lmkl_core -lmkl_intel_thread -lpthread -lm -lmkl_intel_lp64 -DENABLE_DLIB -DDLIB_USE_BLAS

or by disabling the DLIB related portion of the code via:

clang++ main.cpp -I$MKLROOT/include -L$MKLROOT/lib/ -lmkl_core -lmkl_intel_thread -lpthread -lm -lmkl_intel_lp64

C++ code

    // #define ENABLE_DLIB

    #ifdef ENABLE_DLIB
      #include "dlib/optimization.h"
    #endif

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include "mkl.h"

    using namespace std;
    #ifdef ENABLE_DLIB
    using namespace dlib;
    #endif

    template<typename T>
    void printArray(T *data, string name, int len){
        cout << name << "\n";
        for(int i=0;i<len;i++){
            cout << data[i] << " ";
        }
        cout << "\n";
    }

    #ifdef ENABLE_DLIB
    typedef matrix<double,0,1> column_vector;

    double rosen (const column_vector& m)
    {
        const double x = m(0);
        const double y = m(1);
        return 100.0*pow(y - x*x,2) + pow(1 - x,2);
    }
    #endif

    int main()
    {
    #ifdef ENABLE_DLIB
        column_vector starting_point(2);
        starting_point = 4, 8;

        find_min_using_approximate_derivatives(bfgs_search_strategy(),
                                               objective_delta_stop_strategy(1e-7),
                                               rosen, starting_point, -1);
        cout << "\nBFGS rosen minimum lies at:\n";
        cout << "x = " << starting_point(0) << endl;
        cout << "y = " << starting_point(1) << endl;
    #endif

        int len=10;
        double *x=new double[len];
        double *y=new double[len];
        for(int i=0;i<len;i++){
            x[i]=(double)std::rand()/RAND_MAX;
            y[i]=(double)std::rand()/RAND_MAX;
        }
        printArray<double>(x, "x", len);
        printArray<double>(y, "y", len);

        //sum(x)
        double x_sum=cblas_dasum(len,x,1);
        cout<< "sum(x): "<< x_sum <<"\n";
    }

Nevertheless, it fails replacing icpc with clang++ above with multiple errors of the following kind:

Error

    In file included from /opt/intel/composer_xe_2015.3.187/mkl/include/mkl.h:48:
    /opt/intel/composer_xe_2015.3.187/mkl/include/mkl_cblas.h:584:6: error: conflicting types for 'cblas_cgemm'
    void cblas_cgemm(const  CBLAS_LAYOUT Layout, const  CBLAS_TRANSPOSE TransA,
         ^
    /Users/Username/Code/dlib-18.16/dlib/matrix/matrix_blas_bindings.h:75:18: note: previous declaration is here
                void cblas_cgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,

...suggesting a conflict between the cblas_* routines mirrored in MKL. The documentation for DLIB suggests using the DLIB_USE_BLAS preprocessor directive in order for it to link with MKL but evidently it doesn't seem to help using clang++.

How do I make this work?

0

There are 0 answers