必要な機能を集めていく方針で説明していきます。
とりあえず、PCに刺さっているGPUを調べないと始まりません。どのGPUに演算させるべきかも決められないでしょう。
よって利用可能な全アクセラレータを検索します。これらの処理にはacceleratorオブジェクトを用います。
vector<accelerator> vAcs;
vAcs = accelerator::get_all();
for (int i = 0; i < vAcs.size(); i++) {
wcout << vAcs[i].get_description() << "\n";
}
これですべてのアクセラレータ(以降GPU)を画面に表示できると思います。しかしこれだけでは変なGPUも表示されていると思います。刺さっているのは1枚なのに、4つ表示されていたり・・・
これはエミュレータで構成されているGPUで、実際に用いることはありません。デバッグには使えるのでしょうか?
よってこれらを排除したものを表示します。
vector<accelerator> vAcs;
vector<accelerator> vNoEmurate;
vAcs = accelerator::get_all();
for (int i = 0; i < vAcs.size(); i++) {
if(vAcs[i].is_emulated == false)
{
vNoEmurate.push_back(vAcs[i]);
}
}
これでエミュレータ動作のGPUを除外できます。vectorクラスを用いているのでこのように簡単に調べられます。vAcsにはエミュレータ動作以外のGPUを示すacceleratorオブジェクトが入っていることでしょう。
では、以下にエミュレータ動作のGPUを除外し、搭載メモリ量、倍精度のサポート、ディスプレイ出力に使われているかどうか等の情報を表示し、使うGPUを選べるコードを示します。
#include <amp.h>
#include <iostream>
#include <vector>
using concurrency::accelerator;
using std::cout;
using std::cin;
using std::wcout;
using std::vector
accelerator ChoseAccelerator()
{
vector<accelerator> allAccl = accelerator::get_all();
vector<accelerator> validAccl;
int numAcs = allAccl.size();
for(int i=0;i<numAcs;i++)
{
if(!allAccl[i].is_emulated)
{
validAccl.push_back(allAccl[i]);
}
}
if(validAccl.size() == 0)
{
cout << "GPGPUに利用できそうなGPUはなさそうじゃの。";
throw -1;
}
wcout << "以下の候補から選びんす。" << "\n\n";
for(int i=0;i<validAccl.size();i++)
{
wcout << i <<" : "<< validAccl[i].get_description() << "\n";
cout << " メモリ量 : "
<< (double)validAccl[i].dedicated_memory/1024/1000 << " [GB]\n";
cout << " 完全なる倍精度浮動小数演算のサポート : ";
if(validAccl[i].supports_double_precision)
cout << "true\n";
else
cout << "false\n";
cout << " ディスプレイ出力に使われているか : ";
if(validAccl[i].has_display)
cout << "true\n";
else
cout << "false\n";
}
printf("\nさあ、好きなものを選んでくりゃれ。自己責任で。\n\n");
cin.exceptions(ios::failbit);
int selAcs;
while(true)
{
cout << "デバイス番号 = ";
try{
cin >> selAcs ;
}
catch(...){
cout << "この甲斐性なしめ。数字を入力せんか。\n";
cin.clear();
cin.seekg(0);
continue;
}
cout << "\n";
if(0 <= selAcs && selAcs < validAccl.size())
{
cout << selAcs <<"番じゃな。了解じゃ。\n";
return validAccl[selAcs];
}
cout << "たわけ。0~" << validAccl.size() -1 << "までじゃ。"
<<selAcs<<"番のGPUなんて存在せん。\n";
}
throw -1;
}
これで、使用するGPUを示すacceleratorオブジェクトを手に入れることができました。
次からはこのオブジェクトを用いていろんな操作をしていきます。