offload error: cannot find offload entry解决办法

1.问题描述

linux环境下,使用MIC架构的Xeon Phi(至强融核)协处理器进行进行host+mic编程时,源程序运行的毫无问题,但将其通过ar命令生成静态连接库供其他应用程序使用时,就会出现offload error: cannot find offload entry错误。

2.不生成静态链接库的正确版本

为了简化问题,将项目源码缩略为如下示例程序。
源文件offloadtest.cpp:

#include 
#include 
#include 

__attribute__((target(mic)))
void test_kernel(){
    int thread_num=omp_get_max_threads();//获取处理器最大可并行的线程数
    #pragma omp parallel for num_threads(thread_num) 
    for(int i=0;i<10;++i)
        printf("%d:in test kernel\n",i);
}

int main(int argc,char* argv[]){
    int dev=0;
    #pragma offload target(mic:dev)
    {
        test_kernel();
    }
}

编译指令:
使用intel C++编译器icpc进行编译,编译指令如下:

icpc -openmp -o offload.out offloadtest.cpp

执行offload.out,输出结果:
0:in test kernel
7:in test kernel
4:in test kernel
8:in test kernel
2:in test kernel
6:in test kernel
9:in test kernel
3:in test kernel
1:in test kernel
5:in test kernel

可见,for循环的代码已经在MIC上被多线程并行化执行,这样我们就利用MIC达到了CPU和MIC协同编程。

利用offload将设备代码加载到MIC端执行,这种,CPU和MIC协同计算的编程模式叫加载模式(offload模式),CPU端发起主函数,通过offload模式调用kernel到MIC上之行。

3.生成静态链接库供其他程序使用发生错误

在上面的代码中,将main()修改为调用MIC段代码的普通函数,修改结果如下:

#include 
#include 
#include 

__attribute__((target(mic)))
void test_kernel(){
    int thread_num=omp_get_max_threads();//获取处理器最大可并行的线程数
    #pragma omp parallel for num_threads(thread_num) 
    for(int i=0;i<10;++i)
        printf("%d:in test kernel\n",i);
}

void userKernel(){
    int dev=0;
    #pragma offload target(mic:dev)
    {
        test_kernel();
    }
}

利用icpc和ar命令将修改后的代码生成静态连接库offloadtest.a。生成静态链接库库makefile指令如下:

offloadtest.a:offloadtest.o
    ar crv $@ offloadtest.o
offloadtest.o:offloadtest.cpp
    icpc -openmp -o offload.out offloadtest.cpp

执行makefile就会生成静态链接库offloadtest.a。当offloadtest.a链接到其他应用程序时,调用MIC设备端函数test_kernel()时就会出现运行时错误:offload error: cannot find offload entry,程序崩溃。

4.解决办法

生成静态链接库时,使用如下指令:

offloadtest.a:offloadtest.o
    xiar -qoffload-build crv $@ offloadtest.o
offloadtest.o:offloadtest.cpp
    icpc -openmp -o offload.out offloadtest.cpp

在使用ar或者xiar时,加上-qoffload-build命令选项就可以了。本人实践证明,使用xiar时不加-qoffload-build命令选项也可以。

参考资料来自于Intel开发者社区,其原文如下:

From your question, it is unclear if your OpenMP code that worked was a host only or a host+offload code.

From what you have described, I suspect your app’s build procedure creates or uses static archives and one must contain your routine with the offload section; however, if the archive containing that routine was not built using xiar -qoffload-build then the required MIC specific archive is not created. While your app links, the MIC-image is missing the MIC-instance of the routine, so at execution time the host-side app reaches the offload, loads the MIC-image, but the run-time cannot find the routine because it does not exist.

You can visit this compiler reference on how to create offload libraires using xiar and xild.

但是需要注意的是,ar加上-qoffload-build命令选项或者使用xiar就会生成两个静态链接库,如offloadtest.a和offloadtestMIC.a,使用时,请将这两个静态链接库一并链接到程序中使用。

xiar是Intel 基于ar封装的一个用于生成静态链接库的工具。

查看ar的命令选项:

q[f]         - quick append file(s) to the archive

即,-q后面接相关文件,ar -q的作用就是将指定的文件快速附加到静态链接库中。

参考问下

[1]https://software.intel.com/en-us/forums/intel-many-integrated-core/topic/361425
[2]http://blog.csdn.net/k346k346/article/details/50083895

你可能感兴趣的:(HPC)