OpenACC

**OpenACC** (*open accelerators*の略) は、クレイ、CAPS、NVIDIA、そしてPGIによって開発された並列コンピューティングのための標準の一つである。この標準は、ヘテロジニアスなCPU/GPUシステムの並列プログラミングを単純化するために設計された。

位置付けとしては、CUDAやOpenCLをさらに抽象化したものであり、OpenMPと似た存在である。

OpenMPのようにプログラマーは、ディレクティブと追加関数を使って高速化されるべき箇所を識別するようにC言語、C++、そしてFORTRANのソースコードを書き換えれば良い。OpenMP 4.0 とより新しいバージョンのようにOpenACCはCPUとGPUの両方を対象にすることができ、それらの上で計算コードを起動することができる。

OpenACCの会員は、OpenMPの将来のリリースで動作する予定のアクセラレーター（GPUやコプロセッサなど）に対応したり、OpenMPを拡張する共通仕様を作成したり、OpenMPの仕様に合わせるためにOpenMP標準化グループの会員として働いてきた。これらの活動は、ある技術報告書としてまとめられている。この報告書のコメントと議論は、年次スーパーコンピューティング会議（2012年11月、ソルトレイクシティ）に時期を合わせるだけでなく、NVIDIA以外のアクセラレーターがOpenMPに参加しているハードウェアベンダーの意見をサポートするという表明にも時期を合わせている。

2012年の国際スーパーコンピューティング会議（ISC’12）において、OpenACCは、NVIDIA、AMD そして Intel のアクセラレーター上で動作することを証明したが、性能データは公表されなかった。

2012年11月12日、SC12（2012年のスーパーコンピューティング会議）において、OpenACCバージョン2.0の草案が発表された 。
新しく提案された機能は、データ移動における新しい制御（非構造化データの取り扱いの改善と不連続メモリ対応の改善のような）、明示的な関数呼び出し、そして分割コンパイル（高速化コードライブラリの作成と再利用を可能にする）という機能を含んでいる。OpenACC 2.0は2013年1月に公式にリリースされた。

仕様バージョン2.5は、2015年10月にリリースされた。バージョン2.6は、2017年11月にリリースされた 。バージョン2.7は、2018年11月にリリースされた。

2019年4月3日にジョン・レベック（クレイの中核研究拠点クレイスーパーコンピューティングセンターの所長）は、「クレイはCCE/9.0におけるOpenACCのサポートを終了する」と発表した 。

## コンパイラのサポート
OpenACCは、商用コンパイラとして利用可能である。PGI（コンパイラバージョン12.6から）とクレイ（同社のハードウェアのみ）がサポートを行っている。

OpenUHは、CとFORTRANをサポートしているを基盤にしたオープンソースのOpenACCコンパイラである。ヒューストン大学のHPCToolsグループによって開発された。

OpenARCは、OpenACC 1.0仕様の全ての機能をサポートするためにオークリッジ国立研究所で開発されたオープンソースのCコンパイラである。実験的なオープンソースコンパイラaccULは、ラ・ラグーナ大学によって開発されている。

Omni Compilerは、筑波大学HPCS研究室と理化学研究所計算科学研究センターが共同研究しているオープンソースのコンパイラである。OpenACCの他、XcalableMP、及びXcalableMPをOpenACCと組み合わせたXcalableACCをサポートしている。

IPMACCは、ビクトリア大学 (カナダ)によって開発されたオープンソースのCコンパイラである。IPMACCは、OpenACCをCUDA、OpenCL、そしてISPCへ変換する。現在のところ、次のディレクティブのみがサポートされている。つまり、*data*, *kernels*, *loop*, そして *cache* である。

OpenACCに対するGCCのサポートは、進捗が遅かった。サムスンによるGPUを対象にした実装は、2013年9月に発表された。この実装は、OpenACC 1.1のコードをOpenCLへ変換する。2ヵ月後、「真」の実装の発表があった。今回はNVIDIAによるものであり、OpenACC 2.0に基づいたものであった。このことがいくつかの論争を引き起こした。OpenACC 2.0の実装がNVIDIA独自のPTXアセンブリ言語だけを対象にしており、PTXのために利用できるオープンソースのアセンブラあるいはランタイムは存在しなかった 。OpenACC/PTXに対する実験的サポートは、GCCのバージョン5.1の時点で終了した。GCC6とGCC7は、OpenACC 2.0a仕様のより改良された実装を搭載している。GCC 9.1は、OpenACC 2.5のサポートはほぼ完成していると発表した。

## 使用方法

対称型並列システムにおけるOpenMP 3.x あるいは初期のに似た使用方法であり、OpenACCにおけるプログラミングの主要な手段はディレクティブである。その仕様は、いくつかのサポート関数を定義するランタイムライブラリも含んでいる。それらを利用するために利用者は、C言語で"openacc.h"、あるいはFortranで"openacc_lib.h"をインクルードしなければならない。そして、*acc_init()*関数を呼び出す。

### ディレクティブ
OpenACCは、プラグマ（ディレクティブ）の幅広いリストを定義している。例えば、

```c
#pragma acc parallel
 #pragma acc kernels
```

別個のセマンティクス（意味論）を用いて、上の2行はアクセラレーター上で実行される並列な計算カーネル（ここで言うカーネルはOSの中心部ではなくて、アクセラレーター上で実行される計算プログラムのこと）を定義するために使われる。


```c
#pragma acc data
```

上はアクセラレーターと行き来するデータを定義したり、コピーしたりするための主要なディレクティブである。


```c
#pragma acc loop
```

上は `parallel` あるいは `kernels` の領域において並列性の形式を定義するために使われる。


```c
#pragma acc cache
 #pragma acc update
 #pragma acc declare
 #pragma acc wait
```


### ランタイム API
いくつかのランタイムAPI関数も定義されている。つまり、`acc_get_num_devices()`, `acc_set_device_type()`, `acc_get_device_type()`, `acc_set_device_num()`, `acc_get_device_num()`,
`acc_async_test()`, `acc_async_test_all()`, `acc_async_wait()`, `acc_async_wait_all()`, `acc_init()`, `acc_shutdown()`, `acc_on_device()`, `acc_malloc()`, `acc_free()` のことである。

通常、OpenACCは、ターゲットデバイスのために作業組織を処理するが、作業組織はgangとworkerを使って再定義されることもある。gangは複数のworkerから構成され、多くの処理要素を操作する（OpenCLのworkgroupに相当）。

## 関連項目
*XcalableACC
*XcalableMP
*C++ AMP
* CUDA
* OpenCL
* 
* OpenMP

## 出典

 
## 学習用参考書の例
* 片桐孝洋：「並列プログラミング入門: サンプルプログラムで学ぶOpenMPとOpenACC」、東京大学出版会、ISBN 978-4-13062456-5 (2015年5月29日)。 
* Rob Farber(Ed): *Parallel Programming with OpenACC*, Margan Kaufmann, ISBN 978-0-12-410397-9 (2017).
* Sunita Chandrasekaran and Guido Juckeland (Eds.): *OpenACC for Programmers: Concepts and Strategies*, Pearson Addison-Wesley, ISBN 978-0-13-469428-3 (2018).

## 学習用になりうるネット上の資料等
* Usage example from NVIDIA: part1, part2
* 成瀬彰：「OpenACCで始めるGPUコンピューティング:OpenACC 概要」
* 成瀬彰：「OpenACCで始めるGPUコンピューティング:ループの並列化」
* 成瀬彰：「OpenACCで始めるGPUコンピューティング:データ転送の最適化」
* 成瀬彰：「OpenACCで始めるGPUコンピューティング：ループの最適化」
* HPC WORLD / OpenACCとNVIDIA HPC SDKのユーザーコミュニティ
** OpenACC ディレクティブによるプログラミング
* 星野哲也：GPUコラム「OpenACCではじめるGPUプログラミング」アーカイブ 入門編 全12回、GDEP(2020年1月から2021年3月まで)
* 「OpenACCとMPIによるマルチGPUプログラミング入門」(2020年12月22日、東京大学情報基盤センター講習会資料)
* 「GPUプログラミング入門」(東京大学情報基盤センター，第188回お試しアカウント付き並列プログラミング講習会，2022年10月5日資料）
* 「OpenACCとMPIによるマルチGPUプログラミング入門」(2023年6月30日、東京大学情報基盤センター講習会資料)
* 「GPUプログラミング入門」 (2024年6月11日、東京大学情報基盤センター講習会資料)
* Stéphane Ethier: ''Introduction to GPU programming with OpenACC'', Research Computing Bootcamp (November 1st, 2019)
* (RIST主催の)HPCプログラミングセミナーで使用する資料の公開ページ ※ OpenACCについては「アクセラレータ入門」の資料を参照。
* 阿部光平(プロメテック・ソフトウェア株式会社)，GPUプログラミング入門（OpenACC）, Ver.2024.6.27 (released under CC-BY-NC-ND 4.0).
* 南将平(プロメテック・ソフトウェア株式会社)，GPUプログラミング実践編 (OpenACC)，Ver.2024.07.04 (released under CC-BY-NC-ND 4.0).
* 「OpenMPで並列化されたC++プログラムのGPU移植手法」(2025年6月3日、東京大学情報基盤センター講習会資料)
* 「GPUプログラミング入門」(2025年8月26日、東京大学情報基盤センター講習会資料)

## 外部リンク

* 公式サイト
* GPU移行（GPU移行に関するポータルサイト）（最先端共同HPC基盤施設（JCAHPC）)
*  OpenACC Programming:ディレクティブによるプログラミング (HPC WORLD)