使用Armadillo和MKL库针对x86(win32)进行构建

时间:2018-12-31 18:53:26

标签: python c++ armadillo intel-mkl

按照针对x64的相应指南(具有相应的x64-> x86更改)中所述的步骤,我在Visual Studio C ++ 2017中基于armadillo头文件显示了部分代码的链接错误。

我已经从其官方网站上下载了Armadillo最新的稳定发行版(armadillo-9.200.6.tar)。我还从英特尔网站下载了在英特尔i5处理器上运行的64位WIndows 10的MKL库。我在Visual Studio 2017中将它们链接如下:

Project> Properties> Configuration Properties> VC++ Directories> Include Directories:(注意: 以星号开头的行()作为犰狳设置的一部分*)

* C:\Program Files (x86)\Microsoft Visual Studio\Shared\armadillo-9.200.6\include
* C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.1.144\windows\mkl\include
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\include
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\atlmfc\include
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\VS\include
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\um
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\shared
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\winrt
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\cppwinrt
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\Include\um

Project> Properties> Configuration Properties> VC++ Directories> Library Directories:(注意: 以星号开头的行()作为犰狳设置的一部分*)

* C:\Program Files (x86)\Microsoft Visual Studio\Shared\armadillo-9.200.6\examples\lib_win64
* C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.1.144\windows\mkl\lib\intel64_win
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\lib\x86
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.16.27023\atlmfc\lib\x86
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\VS\lib\x86
C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\ucrt\x86
C:\Program Files (x86)\Windows Kits\10\lib\10.0.17763.0\um\x86
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\lib\um\x86
C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6.1\Lib\um\x86

Project> Properties> Configuration Properties> C/C++> General> Additional Include Directories:(注意: < em>带有星号()前缀的行已作为犰狳安装程序的一部分*)

* C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.1.144\windows\mkl\include
* C:\Program Files (x86)\Microsoft Visual Studio\Shared\armadillo-9.200.6\include
C:\Python36_86\include

Project> Properties> Configuration Properties> Linker> General> Additional Library Directories:(注意: < em>带有星号()前缀的行已作为犰狳安装程序的一部分*)

* C:\Program Files (x86)\IntelSWTools\compilers_and_libraries_2019.1.144\windows\mkl\lib\ia32_win
C:\Python36_86\libs

Project> Properties> Configuration Properties> Linker> Input> Additional Dependencies:(注意: < em>带有星号()前缀的行已作为犰狳安装程序的一部分*)

* mkl_core.lib
* mkl_sequential.lib
* mkl_intel_lp64.lib
* lapack_win64_MT.lib
* blas_win64_MT.lib

我正在开发C ++模块作为Python的扩展,因此我正在使用Win32的目标平台。幸运的是,犰狳代码的某些部分可以正常工作,而对于其中的某些部分,则将其显示为问题语句中以下列表中的错误。这是我要构建的代码。基本上是导入numpy数组,将它们相乘并将其作为Python对象返回。我正在做两次试验。试验1:通常使用三个for循环将其相乘(在此处进行注释),该循环成功运行。试验2使用armadillo(错误来源所在的行在注释的帮助下表示)。代码是:

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <Python.h>
#include <Windows.h>
#include <cmath>
#include <vector>
#include <string>
#include <iostream>
#include <armadillo>

#define PyTuple_GET_ITEM PyTuple_GetItem
#define PyTuple_GET_SIZE PyTuple_Size
#define PyArray_FLOAT NPY_FLOAT
#include <numpy/arrayobject.h>

using namespace std;
using namespace arma;

//Taking two numpy array as arguments, multiplying the two numpy arrays and
// returning it back as python object
static PyArrayObject *mmult(PyObject *self, PyObject *args)
{
    PyObject *vec1, *vec2;  

    (PyArg_ParseTuple(args, "OO", &vec1, &vec2));

    PyArrayObject *cvec1, *cvec2;

    cvec1 = (PyArrayObject*) PyArray_FROM_OTF(vec1, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);
    cvec2 = (PyArrayObject*) PyArray_FROM_OTF(vec2, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY);

    npy_intp *shape1 = PyArray_DIMS(cvec1);
    npy_intp *shape2 = PyArray_DIMS(cvec2);

    npy_intp shape3[2] = { shape1[0], shape2[1] };
    PyArray_Descr* cvec3_type = PyArray_DescrFromType(NPY_DOUBLE);

    PyArrayObject* cvec3 = (PyArrayObject *) PyArray_Zeros(2, shape3, cvec3_type,0);

    double *v1, *v2, *v3;
    v1 = (double*)PyArray_DATA(cvec1);
    v2 = (double*)PyArray_DATA(cvec2);
    v3 = (double*)PyArray_DATA(cvec3);


    /* TRIAL 1 : SUCCESSFUL
    for (int i = 0; i < shape1[0]; i++) {
        for (int j = 0; j < shape2[1]; j++) {
            for (int k = 0; k < shape2[0]; k++) {
                v3[shape3[1]*i+j] += v1[shape1[1] * i + k] *v2[shape2[1] * k + j];
            }
        }
    }
    */
    //TIRAL 2: Wih Armadillo
    arma::Mat<double> A1(shape1[0], shape1[1]);  //Successful
    arma::Mat<double> A2(shape2[0], shape2[1]);
    arma::Mat<double> A3(shape1[0], shape2[1]);

    for (int i = 0; i < shape1[0]; i++) {
        for (int j = 0; j < shape1[1]; j++) {   
            A1(i, j) = v1[shape1[1] * i + j];   //Successful
        }
    }

    for (int i = 0; i < shape2[0]; i++) {
        for (int j = 0; j < shape2[1]; j++) {  //Successful
            A2(i, j) = v2[shape2[1] * i + j];
        }
    }

    A3 = A1 * A2;  // -----> This is the line that is creating the errors

    for (int i = 0; i < shape1[0]; i++) {
        for (int j = 0; j < shape2[1]; j++) {
            v3[shape3[1] * i + j] = A3(i, j);
        }
    }


    // This piece of the code also do not work with armadillo. I took this from a demo code.
    // Create a 4x4 random matrix and print it on the screen
    arma::Mat<double> A = arma::randu(4, 4);
    std::cout << "A:\n" << A << "\n";
    // Multiply A with his transpose:
    std::cout << "A * A.t() =\n";
    std::cout << A * A.t() << "\n";

    return cvec3;
}

//Structure: Defines how C++ function is presented to Python
static PyMethodDef mhps_methods[] = {

    { "mmult", (PyCFunction)mmult, METH_VARARGS, nullptr },
    { nullptr, nullptr, 0, nullptr }

};

//Structure: Defines module as you want it to be referred to in your Python code.
static PyModuleDef mhps_module = {

    PyModuleDef_HEAD_INIT,
    "mhps",
    "faster codes for research modules",
    0,
    mhps_methods

};

//Method: Python calls this method when it loads the module using "import mhps"
PyMODINIT_FUNC PyInit_mhps() {
    import_array();
    return PyModule_Create(&mhps_module);
}

这是正在生成的错误:

module1.obj : error LNK2001: unresolved external symbol _sposv_
module1.obj : error LNK2001: unresolved external symbol _cgemv_
module1.obj : error LNK2001: unresolved external symbol _sdot_
module1.obj : error LNK2001: unresolved external symbol _sgemv_
module1.obj : error LNK2001: unresolved external symbol _zgemv_
module1.obj : error LNK2001: unresolved external symbol _dgemm_
module1.obj : error LNK2001: unresolved external symbol _sgesv_
module1.obj : error LNK2001: unresolved external symbol _zgesv_
module1.obj : error LNK2001: unresolved external symbol _sgemm_
module1.obj : error LNK2001: unresolved external symbol _dposv_
module1.obj : error LNK2001: unresolved external symbol _dgemv_
module1.obj : error LNK2001: unresolved external symbol _zposv_
module1.obj : error LNK2001: unresolved external symbol _cposv_
module1.obj : error LNK2001: unresolved external symbol _cgemm_
module1.obj : error LNK2001: unresolved external symbol _dsyrk_
module1.obj : error LNK2001: unresolved external symbol _ssyrk_
module1.obj : error LNK2001: unresolved external symbol _ddot_
module1.obj : error LNK2001: unresolved external symbol _zgemm_
module1.obj : error LNK2001: unresolved external symbol _dgesv_
module1.obj : error LNK2001: unresolved external symbol _cgesv_

1 个答案:

答案 0 :(得分:0)

在以下位置输入输入时,这是我的一个小错误

Project> Properties> Configuration Properties> Linker> Input> Additional Dependencies

mkl_intel_c.lib
mkl_sequential.lib
mkl_core.lib

我用上面的文件名完全替换了它。实际上是mkl文件夹中32位文件夹库中的文件。按照标题为“ Getting started with Armadillo a C++ Linear Algebra Library on Windows, Mac and Linux”的文章的说明,作者假定大多数人将其用于64位,因此未指定要包含在链接器输入列表中的特定文件。