8

バックグラウンド

新しいGCC 5.1リリースを使用して、OpenMP ブロックを Intel MIC (つまり、Xeon Phi) にオフロードしようとしましたが、うまくいきませんでした。GCCオフロードページに続いて、"intelmic" およびホスト コンパイラ用の "accel" ターゲット コンパイラをビルドするスクリプトをまとめましbuild.sh。コンパイルは正常に完了したようです。

次に、スクリプトを使用して、以下にリストされている単純なプログラムenv.shをコンパイルしようとします。hello.cただし、このプログラムはホスト上でのみ実行され、ターゲット デバイスでは実行されないようです。

GCC のコンパイルだけでなく、一般的なオフロードにも慣れていないため、間違っている可能性があることが複数あります。ただし、既に言及されているリソースに加えて、次のことを調査しました (リンクを投稿するのに十分な担当者がいません)。

  • Xeon Phi のオフロード
  • Xeon Phi チュートリアル
  • インテル Xeon Phi オフロード プログラミング モデル

最大の問題は、通常 Intel コンパイラを参照していることです。コピーを購入する予定ですが、現在コピーはありません。さらに、開発パイプラインの大部分はすでに GCC と統合されており、(可能であれば) その状態を維持したいと考えています。

最新の MPSS 3.5 ディストリビューションをインストールし、Ubuntu で動作するように必要な変更を加えました。システム内の Xeon Phis のステータスを正常に通信して確認できます。

私たちの努力では、コードがマイク エミュレーション モードで実行されている兆候も見られませんでした。

質問

  1. 実際に Xeon Phi にオフロードするホスト/ターゲット GCC コンパイラの組み合わせを構築した人はいますか? もしそうなら、どのリソースを使用しましたか?
  2. ビルド スクリプトに欠けているものはありますか?
  3. テストソースコードに問題はありますか? それらはエラーなしでコンパイルされ (以下で説明するものを除く)、48 スレッド (つまり、ホスト システムの論理スレッドの数) で実行されます。
  4. 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) を使用すると、ホスト上でコンパイルおよび実行されます。このコードは、同じ方法でコンパイルされました。

4

1 に答える 1