Vengineerの戯言

人生は短いけど、長いです。人生を楽しみましょう!

Intel oneAPI 2022 をインストールしてみた

はじめに

oneAPI 2022 が公開されたようなので、インストールしてみました。

www.intel.com

Windows 11 Pro & WSL2 & Ubuntu 20.04LTS

の条件にて、apt コマンドにてインストールしてみました。

www.intel.com

インストール後、下記のコマンドを ~/.bashrc に追加しました。

source /opt/intel/oneapi/setvars.sh

このサンプルコードを使ってみました。 説明のために引用します。

#include <CL/sycl.hpp>
#include <iostream>

constexpr int num=16;
using namespace sycl;

int main() {
  auto r = range{num};
  buffer<int> a{r};

  queue{}.submit([&](handler& h) {
    accessor out{a, h};
    h.parallel_for(r, [=](item<1> idx) {
      out[idx] = idx;
    });
  });

  host_accessor result{a};
  for (int i=0; i<num; ++i)
    std::cout << result[i] << "\n";
} 

sample.cpp という名前を付けてファイルに保存し、dpcpp コマンドでコンパイル、実行できます。

dpcpp sample.cpp
./a.out
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

上記のプログラムに対して、cpu_selector を追加したのが下記のコードです。

constexpr int num=16;
using namespace sycl;

int main() {
  auto r = range{num};
  buffer<int> a{r};

  sycl::cpu_selector selector;    
  sycl::queue q = sycl::queue(selector);
  std::cout << "device name = " << q.get_device().get_info<sycl::info::device::name>() << std::endl;;
  q.submit([&](handler& h) {
    accessor out{a, h};
    h.parallel_for(r, [=](item<1> idx) {
      out[idx] = idx;
    });
  });

  host_accessor result{a};
  for (int i=0; i<num; ++i)
    std::cout << result[i] << "\n";
} 

device name = に "11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz"が表示された。

./a.out
devicr name = 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

GPUで動かしてみる

constexpr int num=16;
using namespace sycl;

int main() {
  auto r = range{num};
  buffer<int> a{r};

  sycl::gpu_selector selector;    
  sycl::queue q = sycl::queue(selector);
  std::cout << "device name = " << q.get_device().get_info<sycl::info::device::name>() << std::endl;;
  q.submit([&](handler& h) {
    accessor out{a, h};
    h.parallel_for(r, [=](item<1> idx) {
      out[idx] = idx;
    });
  });

  host_accessor result{a};
  for (int i=0; i<num; ++i)
    std::cout << result[i] << "\n";
} 

sycl::cpu_selector を sycl::gpu_selector に変更して、コンパイルして実行したら、エラーが出ました。

./a.out
terminate called after throwing an instance of 'cl::sycl::runtime_error'
  what():  No device of requested type available. Please check https://software.intel.com/en-us/articles/intel-oneapi-dpcpp-compiler-system-requirements-beta -1 (CL_DEVICE_NOT_FOUND)
Aborted

Google君に聞いたら、同じようなエラーが出ている人がいました。どうやら最新のデバイスドライバにすると、OKのようです。

github.com

WDDM GPU Paravirtualization support for WSL2 にある、下記のWindowsデバイスドライバーをインストールしてみました。

www.intel.com

このデバイスドライバをインストールして、再起動しても同じエラーでした。

下記のドキュメントに書いてあるパッケージをインストールしたことにより、動くようになりました。

github.com

"devicr name = Intel(R) Graphics [0x9a49]"が表示されました。

./a.out
devicr name = Intel(R) Graphics [0x9a49]
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Windows 10 (21H1) & WSL2 & oneapi 2022

古いおしごと用のノートPC(Lenovo ThinkPad 13)でもやってみた。CPUは、Core i3 7100 です。CPU版は下記のようにOKでした。

device name = Intel(R) Core(TM) i3-7100U CPU @ 2.40GHz
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

GPU版は、デバイスドライバ―のインストールで下記のようなエラーが発生してしました。残念です

f:id:Vengineer:20211226142840p:plain

CPUとGPUの速度差

上記のプログラムの num の値を 16 から 10241024256 に設定し、CPUとGPUでの実行時間を計ってみました。前半がCPUで、後半がGPUです。 CPUのほうが速いですね。

devicr name = 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz

real    0m0.256s
user    0m0.428s
sys     0m0.271s
devicr name = Intel(R) Graphics [0x9a49]

real    0m0.349s
user    0m0.123s
sys     0m0.100s

ちなみに、num を 102410241024 (1GB x 4 = 4GB)にすると、次のようなエラーが発生しました。バッファが取れないようです。

evicr name = Intel(R) Graphics [0x9a49]
terminate called after throwing an instance of 'cl::sycl::runtime_error'
  what():  Native API failed. Native API returns: -61 (CL_INVALID_BUFFER_SIZE) -61 (CL_INVALID_BUFFER_SIZE)
Aborted

おわりに

Intel oneAPI 2022 をWindows 11 & WSL2 & Ubuntu 20.04LTS にインストールし、CPUとGPUで動くことを確認できました。