从C ++链接到Fortran库(Lapack) [英] Link to Fortran library (Lapack) from C++

查看:275
本文介绍了从C ++链接到Fortran库(Lapack)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C ++代码中使用 Lapack 。我很困惑如何正确链接到图书馆。这是一个与我的代码调用Lapack函数相对应的小例子:

  #include< iostream> 

namespace lapack {externC{
void ilaver(int * major,int * minor,int * patch); }}

int main()
{
int major = 0;
int minor = 0;
int patch = 0;
lapack :: ilaver(& major,& minor,& patch);
std :: cout<<主要< <<次要<< <<补丁<<的std :: ENDL;
返回0;如果我尝试使用GCC 4.8.5(Linux openSUSE)进行编译,则可以使用以下命令来编译它:我收到以下错误消息:

 > g ++ ilaver.cpp -o ilaver -L /softs/lapack/3.7.1/64/gcc/4.8.5/lib64 -l lapack 
/tmp/ccHvDCAh.o:在函数`main'中:
ilaver.cpp :(。text + 0x33):对'ilaver'的未定义引用
collect2:错误:ld返回1退出状态

我知道这是一个名称混乱的问题。如果我在代码中添加一个下划线并在GCC中添加了下划线,那么它就可以正确编译GCC:

  #include<的iostream> 

namespace lapack {externC{
void ilaver_(int * major,int * minor,int * patch); }}

int main()
{
int major = 0;
int minor = 0;
int patch = 0;
lapack :: ilaver _(& major,& minor,& patch);
std :: cout<<主要< <<次要<< <<补丁<<的std :: ENDL;
返回0;
}

但它不能在Windows下的英特尔编译器中编译。在那里,修改是不同的,我必须将它改为 lapack :: ILAVER ,然后编译它。



我的代码必须通过几种编译器(GCC,Intel,MSVC)在几种配置下编译(Linux / Mac / Windows)。我怎么能更通用,并确保它将在一大组编译器下编译?

解决方案

像添加下划线这样的黑客根据它们的性质是特定于平台的。支持大量平台和编译器的方式手工,需要大量的不愉快和繁琐的工作。

获得可移植性的最简单方法是使用LAPACKE,官方的C接口LAPACK。这还有一个好处,就是不必重新声明所有你需要的功能。



下面是一个简单的例子:

  #include< iostream> 
#include< lapacke.h>

int main()
{
//通过使用lapack_int,我们也支持LAPACK-ILP64
lapack_int major = 0;
lapack_int minor = 0;
lapack_int patch = 0;
LAPACKE_ilaver(& major,& minor,& patch);
std :: cout<<主要< <<次要<< <<补丁<<的std :: ENDL;
返回0;
}

更多信息可以在官方文档



请注意,LAPACKE只处理LAPACK,如果你还需要BLAS例程,您可以从 CBLAS 获取这些例程。


I'm using Lapack in my C++ code. I'm quite confused how to properly link to the library. Here is a small example corresponding to my code calling a function from Lapack:

#include <iostream>

namespace lapack { extern "C" {
  void ilaver(int* major, int* minor, int* patch); } }

int main()
{
    int major = 0;
    int minor = 0;
    int patch = 0;
    lapack::ilaver(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

If I try to compile it with GCC 4.8.5 (Linux openSUSE), I get the following error:

> g++ ilaver.cpp -o ilaver -L /softs/lapack/3.7.1/64/gcc/4.8.5/lib64 -l lapack
/tmp/ccHvDCAh.o: In function `main':
ilaver.cpp:(.text+0x33): undefined reference to `ilaver'
collect2: error: ld returned 1 exit status

I understood it's a name mangling problem. If I change my code adding an underscore at the end of the function name, it compiles properly with GCC:

#include <iostream>

namespace lapack { extern "C" {
  void ilaver_(int* major, int* minor, int* patch); } }

int main()
{
    int major = 0;
    int minor = 0;
    int patch = 0;
    lapack::ilaver_(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

But it doesn't compile with Intel's compilers under Windows. There, the mangling is different, I have to change it to lapack::ILAVER, and then it compiles.

My code must be compiled under several configurations (Linux/Mac/Windows) with several compilers (GCC,Intel,MSVC). How can I be more generic and be sure it will compile under a large panel of compilers ?

解决方案

As you have already discovered, hacks like adding the underscore are platform-specific by their nature. Supporting a big range of platforms and compilers that way "by hand" requires a large amount of unpleasant and tedious work.

The easiest way to get portability is to use LAPACKE, the official C interface to LAPACK. This also has the added benefit of saving you from having to re-declare all the functions you need.

Here's a simple example:

#include <iostream>
#include <lapacke.h>    

int main()
{
    // By using lapack_int, we also support LAPACK-ILP64
    lapack_int major = 0;
    lapack_int minor = 0;
    lapack_int patch = 0;
    LAPACKE_ilaver(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

More information can be found in the official documentation.

Note that LAPACKE only handles LAPACK, if you also need BLAS routines, you can get those from CBLAS.

这篇关于从C ++链接到Fortran库(Lapack)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆