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

时间:2015-04-24 15:56:14

标签: gcc openmp xeon-phi offloading

背景

我们一直尝试使用新的GCC 5.1版本将OpenMP块卸载到Intel MIC(即Xeon Phi),但未成功。在GCC Offloading页面之后,我们将build.sh脚本放在一起构建了" accel"针对" intelmic"的目标编译器和主机编译器。编译似乎成功完成。

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

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

  • 为Xeon Phi卸货
  • Xeon Phi教程
  • Intel Xeon Phi卸载编程模型

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

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

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

问题

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

    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),它会在主机上编译并运行。此代码以相同的方式编译。

1 个答案:

答案 0 :(得分:1)

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