__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;
}