Visual Studio 2019 で OpenCL プログラミングを行う

#目的
Visual Studio 2019 と OpenCL を使用して新しくプロジェクトを作成し、GPUで並列処理が実行できることを確認します。

#概要
OpenCL は GPU で並列処理を行うための標準化されたライブラリです。OpenCL と似たもので CUDA Toolkit がありますが、CUDA Toolkit は NVIDIA の GPU でのみ動作するプログラムを作成することができます。AMD や Intel, FPGA などの汎用デバイスなど、より幅広いプラットフォームに対応するために OpenCL を選択します。

OpenCL では通常の C++ でのコードと「カーネル」と呼ばれる .cl ソースコードの２つから成り立ちます。プログラムを実行するとCPUが通常の C++ で書かれたプログラムを実行し、その中で OpenCL のライブラリを呼び出し .cl ファイルをコンパイルして GPU 上で実行します。

また、CPU と GPU は直接やり取りをすることができず、GPU に搭載されているメモリを介してデータのやり取りを行うため、処理要求をメモリ上に書き込み、処理結果をメモリ上から取得するという形になります。

#開発環境
Intel Core i7-4790 3.60GHz
16GB Memory
NVIDIA GeForce GTX750Ti

#事前準備
Visual Studio 2019 と OpenCL , CUDA Toolkit は下記URLから別途インストールする必要があります。

Visual Studio 2019
https://visualstudio.microsoft.com/ja/downloads/

Intel® SDK for OpenCL™ Applications
https://software.intel.com/content/www/us/en/develop/tools/opencl-sdk/choose-download.html

NVIDIA CUDA Toolkit
https://developer.nvidia.com/cuda-toolkit-archive

CUDA Toolkit は OpenCL と NVIDIA GPU の橋渡しをするために必要となります。OpenCL は CUDA Toolkito を経由して GPU をコントロールします。GPUがGTX750Tiとかなり以前のもののため、CUDA Toolkit 8.0を使用する必要がありましたので、GPUボードに対応したCUDA Toolkit のバージョンを使用してください。また、CUDA Toolkit をインストールすると GTX750Ti のドライバーもインストールされました。

CUDA Toolkit をインストールする際に Visual Studio Integration でエラーが発生します。Visual Studio Integration はインストールする必要はないため、カスタムインストールを選択し事前にインストール対象から除外します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/7f8b5c77-10c1-7ff2-af12-7f78dfe87cae.png)

#Visual Studio 2019 でプロジェクトを作成
Visual Studio でプロジェクトを作成します。
プロジェクトタイプはC++ Console Appを選択します。
Empty OpenCL Project for windows や GPU OpenCL Project for Windows を選択してしまうと、OpenCLファイル .cl をコンパイルしようとしてビルドできないため、C++ Console Appを選択します。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/7e7130c7-5baf-b008-bc64-14b7becef151.png)

#ソースファイル作成
プロジェクトエクスプローラーで kernels フォルダを作成し、新規に kernel.cl ファイルを追加します。
この時 kernel.cl ファイルは OpenCL Kernel File を選択します。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/d46eac50-43e1-2d6d-4f6e-0ce67f57d55f.png)

Source Files フォルダ配下に C++ のソースを追加します。

Header Files 配下に Utils.h と cl2.hpp を追加します。
どちらも下記の OpenCL Tutorial から取得しました。
https://github.com/gcielniak/OpenCL-Tutorials

#プロジェクトの設定
Visual Studio のグローバルメニューから Project > Properties を開き下記のプロジェクト設定を変更します。

## C/C++ > General
* Additional Include Directories に $(INTELOCLSDKROOT)include を追加します。
* Debug Information Format を Program Database (/Zi) にします。
* SDL checks を空欄にします。
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/dbe298df-e91c-0387-d15d-0b9728095fa9.png)

## Linker > General 
* Additional Library Directories に $(INTELOCLSDKROOT)lib\x64 を追加します。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/8b17366f-0f88-103c-a3d0-9febf1ca9bcd.png)

## Linker > Input
* Output File に OpenCL.lib を追加します。
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/c3182634-6733-bb0f-abc7-f1e4bde0d020.png)

#実行
Debug > Start Debugging を実行すると下記のようにGPU上で kernel を実行することができます。
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514807/06343bc2-e7d1-a944-8d6d-2b56c4d71c44.png)