如何使用 GCC 5.1 和 OpenMP 将工作卸载到 Xeon Phi

Posted

技术标签:

【中文标题】如何使用 GCC 5.1 和 OpenMP 将工作卸载到 Xeon Phi【英文标题】:How to use GCC 5.1 and OpenMP to offload work to Xeon Phi 【发布时间】:2015-04-24 15:56:14 【问题描述】:

背景

我们一直在尝试使用新的 GCC 5.1 版本将 OpenMP 块卸载到英特尔 MIC(即 Xeon Phi),但没有成功。在 GCC Offloading 页面之后,我们将 build.sh 脚本放在一起,为“intelmic”和主机编译器构建“accel”目标编译器。编译似乎已成功完成。

然后我们使用env.sh 脚本尝试编译下面列出的简单hello.c 程序。但是,这个程序似乎只在主机上运行,​​而不是在目标设备上运行。

由于我们通常不熟悉卸载以及编译 GCC,因此我们可能会在很多事情上做错。但是,我们已经调查了已经提到的资源以及以下资源(我没有足够的代表来发布链接):

至强融核的卸载 至强融核教程 英特尔至强融核卸载编程模型

最大的问题是他们通常引用英特尔编译器。虽然我们计划购买副本,但我们目前没有副本。此外,我们的大部分开发管道已经与 GCC 集成,我们更愿意保持这种方式(如果可能的话)。

我们已经安装了最新的 MPSS 3.5 发行版,进行了必要的修改以在 Ubuntu 下工作。我们可以成功通信并检查系统中 Xeon Phis 的状态。

在我们的努力中,我们也从未发现任何迹象表明代码在麦克风仿真模式下运行。

问题

    是否有人成功构建了主机/目标 GCC 编译器组合,实际上可以卸载到 Xeon Phi?如果是,您使用了哪些资源? 我们是否遗漏了构建脚本中的任何内容? 测试源代码有问题吗?它们编译时没有错误(除了下面提到的),并以 48 个线程(即主机系统中的逻辑线程数)运行。 由于 Google 搜索没有透露太多信息,是否有人对下一步有建议(除了放弃 GCC 卸载)?这是一个错误吗?

谢谢!

build.sh

#!/usr/bin/env bash                                                                                                                                           

set -e -x
unset LIBRARY_PATH

GCC_DIST=$PWD/gcc-5.1.0

# Modify these to control where the compilers are installed                                                                                                   
TARGET_PREFIX=$HOME/gcc
HOST_PREFIX=$HOME/gcc

TARGET_BUILD=/tmp/gcc-build-mic
HOST_BUILD=/tmp/gcc-build-host

# i dropped the emul since we are not planning to emulate!                                                                                                    
TARGET=x86_64-intelmic-linux-gnu
# should this be a quad (i.e. pc)?? default (Ubuntu) build seems to be x86_64-linux-gnu                                                                       
HOST=x86_64-pc-linux-gnu

# check for the GCC distribution                                                                                                                              
if [ ! -d $GCC_DIST ]; then
    echo "gcc-5.1.0 distribution should be here $PWD"
    exit 0
fi

#sudo apt-get install -y libmpfr-dev libgmp-dev libmpc-dev libisl-dev dejagnu autogen sysvbanner                                                              

# prepare and configure the target compiler                                                                                                                   
mkdir -p $TARGET_BUILD
pushd $TARGET_BUILD
$GCC_DIST/configure \
    --prefix=$TARGET_PREFIX \
    --enable-languages=c,c++,fortran,lto \
    --enable-liboffloadmic=target \
    --disable-multilib \
    --build=$TARGET \
    --host=$TARGET \
    --target=$TARGET \
    --enable-as-accelerator-for=$HOST \
    --program-prefix="$TARGET-"
    #--program-prefix="$HOST-accel-$TARGET-" \                                                                                                                
# try adding the program prefix as HINTED in the https://gcc.gnu.org/wiki/Offloading                                                                          
# do we need to specify a sysroot??? Wiki says we don't need one... but it also says "better to configure as cross compiler....                               

# build and install                                                                                                                                           
make -j48 && make install
popd

# prepare and build the host compiler                                                                                                                         
mkdir -p $HOST_BUILD
pushd $HOST_BUILD
$GCC_DIST/configure \
    --prefix=$HOST_PREFIX \
    --enable-languages=c,c++,fortran,lto \
    --enable-liboffloadmic=host \
    --disable-multilib \
    --build=$HOST \
    --host=$HOST \
    --target=$HOST \
    --enable-offload-targets=$TARGET=$TARGET_PREFIX

make -j48 && make install
popd

env.sh

#!/usr/bin/env bash

TARGET_PREFIX=$HOME/gcc
HOST_PREFIX=$HOME/gcc
HOST=x86_64-pc-linux-gnu
VERSION=5.1.0

export LD_LIBRARY_PATH=/opt/intel/mic/coi/host-linux-release/lib:/opt/mpss/3.4.3/sysroots/k1om-mpss-linux/usr/lib64:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$HOST_PREFIX/lib:$HOST_PREFIX/lib64:$HOST_PREFIX/lib/gcc/$HOST/$VERSION:$LD_LIBRARY_PATH
export PATH=$HOST_PREFIX/bin:$PATH

hello.c(版本 1)

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) 

  int nthreads, tid;
  /* Fork a team of threads giving them their own copies of variables */

#pragma offload target (mic)
  
#pragma omp parallel private(nthreads,tid)
    
      /* Obtain thread number */
      tid = omp_get_thread_num();
      printf("Hello World from thread = %d\n", tid);
      
      /* Only master thread does this */
      if (tid == 0) 
        nthreads = omp_get_num_threads();
        printf("Number of threads = %d\n", nthreads);
          
#ifdef __MIC__
      printf("on target...\n");
#else
      printf("on host...\n");
#endif    
    
      

我们用以下代码编译了这段代码:

gcc -fopenmp -foffload=x86_64-intelmic-linux-gnu hello.c -o hello

hello_omp.c(第 2 版)

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) 

  int nthreads, tid;
  /* Fork a team of threads giving them their own copies of variables */

#pragma omp target device(mic)
  
#pragma omp parallel private(nthreads,tid)
    
      /* Obtain thread number */
      tid = omp_get_thread_num();
      printf("Hello World from thread = %d\n", tid);
      
      /* Only master thread does this */
      if (tid == 0) 
    nthreads = omp_get_num_threads();
    printf("Number of threads = %d\n", nthreads);
          
#ifdef __MIC__
      printf("on target...\n");
#else
      printf("on host...\n");
#endif    
    
      

几乎相同的东西,但我们尝试了

#pragma omp target device

语法。事实上,对于mic,它会抱怨,但对于任何设备号(即 0),它都会在主机上编译和运行。这段代码是用同样的方式编译的。

【问题讨论】:

当英特尔人员监控此站点时,您最好在英特尔论坛上发布此内容。 为什么选择 Intel 而不是 GCC? 根据 GCC Offloading 页面:“GCC 5 支持两种类型的卸载:OpenMP 到英特尔 MIC 目标(即将推出英特尔至强融核产品,代号为 KNL)"。因此,不支持卸载到当前一代的英特尔至强融核 (KNC)。 啊...@IlyaVerbin,我明白了。感谢您的评论。我错过了那个区别(骑士角与骑士登陆)。因此,换句话说,我们现在(以及未来使用此硬件)别无选择,只能使用英特尔编译器。 这可能会让您感兴趣。 xeon-phi-knights-corner-intrinsics-with-gcc。最近有大量的骑士角卡销售,但没有 GCC 的支持。 【参考方案1】:

可以使用 GCC 5 卸载到 Xeon Phi。为了让它工作,必须为本地 MIC 目标编译 liboffloadmic,类似于它的完成方式here。您设置的问题在于它编译主机仿真库(libcoi_host.so、libcoi_device.so),并且即使存在物理 Xeon Phi 也坚持使用仿真卸载。

【讨论】:

所以,澄清一下,您是说我们可以使用链接项目为我们的 Knights Corner Xeon Phi 卡编译一个 MIC 原生版本的 liboffloadmic 和 libgomp最新的 GCC 5?看saxpy 的例子,类似CUDA 的界面和简单的写#pragma omp target device(0) 不太一样。为什么测试 Makefile 需要 icc 用于 TBB?谢谢。

以上是关于如何使用 GCC 5.1 和 OpenMP 将工作卸载到 Xeon Phi的主要内容,如果未能解决你的问题,请参考以下文章

通过 GCC 学习 OpenMP 框架

如何正确升级OpenMP版本?

使用 OpenMP 4.0 (gcc 4.8.4) 而不是 OpenMP 3.1 (gcc 4.9.2) 时速度会降低

在 Xcode 4 (LLVM GCC) 中使用 _mm_shuffle_ps 时可能出现 OpenMP + SSE 错误

Helgrind (Valgrind) 和 OpenMP (C):避免误报?

OpenMP 5.1 规范是不是允许使用非矩形循环的折叠子句?