0

__pgi_gangidx()コンパイラ拡張関数は、関数を実行するギャングの数値 ID を返すことになっています (こちら参照)。ただし、並列セクション ループ内での使用方法がわかりませんでした。

以下のコードでは、いくつかの可能性を試していますが、そのうちの 1 つだけが望ましい答えをもたらします。残念ながら、これは並列セクション ループを順番に実行します。

この変数int placeは、複数のグローバル配列へのより複雑なギャング固有の参照の代役であるため、簡単には削除できません。

コードは次のようにコンパイルできます。

pgc++ -fast -acc -ta=tesla,cc60 -Minfo=accel test.cpp

コード:

#include <iostream>
#include "openacc.h"

void ResetIds(int *const ids, int size){
  //Ensure everything is zeroed
  for(int i=0;i<size;i++)
    ids[i] = 0;  
}

void ShowVector(int line, int *const ids, int size){
  std::cout<<"Line "<<line<<": ";
  for(int i=0;i<size;i++)
    std::cout<<ids[i]<<" ";
  std::cout<<std::endl<<std::endl;
}

int main(){
  int gangs  = 10;
  int gwidth = 10;
  int size   = gangs*gwidth;
  int *ids   = new int[50*size];

  //Works!
  //Gives: 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
  ResetIds(ids, size);
  #pragma acc parallel num_gangs(gangs) copy(ids[0:size])
  {
    int place = __pgi_gangidx();
    #pragma acc loop seq
    for(int i=0;i<10;i++)
      ids[place*gwidth+i] = 14;
  }  
  ShowVector(__LINE__, ids, size);

  //Gives: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  ResetIds(ids, size);
  #pragma acc parallel num_gangs(gangs) copy(ids[0:size])
  {
    int place = __pgi_gangidx()*gwidth;
    #pragma acc loop 
    for(int i=0;i<10;i++)
      ids[place+i] = 14;
  } 
  ShowVector(__LINE__, ids, size);

  //Gives: 14 14 14 14 14 14 14 14 14 14 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  ResetIds(ids, size);
  #pragma acc parallel num_gangs(gangs) copy(ids[0:size])
  {
    int place = __pgi_gangidx();
    #pragma acc loop
    for(int i=0;i<10;i++)
      ids[place*gwidth+i] = 14;
  }  
  ShowVector(__LINE__, ids, size);

  //Gives: 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 0 14
  ResetIds(ids, size);
  #pragma acc parallel num_gangs(gangs) copy(ids[0:size])
  {
    int place = __pgi_gangidx();
    #pragma acc loop worker
    for(int i=0;i<10;i++)
      ids[place*gwidth+i] = 14;
  }  
  ShowVector(__LINE__, ids, size);

  return 0;
}
4

1 に答える 1