OpenVX SDKの調査

EDIT: OpenVX 1.3が公開され、しかも、 [タイリングやOpenCLカーネルを含む、大巾に拡張されたOpenVX 1.3サンプル実装](https://github.com/KhronosGroup/OpenVX-sample-impl/tree/openvx_1.3) が提供されている。マジかよ。 [Khronosのプレスリリース](https://www.khronos.org/news/press/khronos-releases-openvx-1.3-open-standard-for-cross-platform-vision-and-machine-intelligence-acceleration) 。

設営やQAに使っている内製のCVフレームワークを標準ベースにしようということでOpenVXはどうかと検討している。...ちょっと厳しいかなという感想。

OpenGLがDirectXに比べて遅れていた時期があった(そしてOpenGLは止まってVulkanとかWebGPUになった)けど、ちょうどCVもそういう時期なんではないかと思う。

# OpenVXとは

OpenVX( https://www.khronos.org/openvx )はOpenGLやVulkan、OpenCLで知られるKhronosの規格で、

1. OpenCVの提供するような画像処理プリミティブで標準化できそうなものを抜き出して **C API** にしたもの (なのでカメラ入力やバーコード検出のようなセクシーな機能は存在しない)
2. その場でデータを処理するImmediateモードとグラフを構築、最適化してから実行するGraphモードの2つを持つ
3. Intel、AMD、nVidia のメジャーベンダがそれぞれSDKを公開している

このQiitaだとOpenCVタグの記事が1800以上あるのに **OpenVXは 4** (この記事が5つ目だ)というのでお察しという感じだが、さらに:

- Google、Apple、ARMのような重要なモバイルベンダが支持していない
- Xilinxは結局OpenVXの熱心なサポートを提供せず、一部互換プリミティブの提供に留まった
- IntelはOpenVX APIでのニューラルネットワークサポートをdeprecateして、専用のAPIを使わせている

という厳しい感じになっている。

重要な特徴は、OpenVXは処理グラフを **事前構築して最適化** の上実行することを想定している点。これをOpenCL一本で真面目にやろうとするとメッチャ苦労する(した)のでこういう部分を他所に任せられるのはかなり大きい。例えば、KhronosはRaspberry Pi向けのOpenVX実装を募集 https://www.khronos.org/rfq/openvx-implementation-on-the-raspberry-pi-platform していて、その中の要項として:

> The project will demonstrate the performance advantage of using the OpenVX API by implementing several optimizations that are enabled by OpenVX including:
>
>  -   Automatic optimization of memory access patterns via tiling and chaining;
>  -   Use of highly optimized kernels leveraging multimedia instruction sets;
>  -   Automatic parallelization to utilize multiple compute resources, including multicore CPUs and GPUs;
>  -   Automatic merging of common sequences of processing kernels into a single, higher-performance kernel.

と、最適化の実装を求めている( ~~もっとも、実際にこれに応募して実装を用意するような企業/個人は居ないだろう~~ EDIT:なんとリファレンス実装でサポートしてきた)。現実の実装では、IntelのOpenVXが比較的熱心なタイリング考察を持っている。

OpenVXは更にImport/Export拡張として一度構成したグラフのシリアライズを仕様化していて、これはSafety Critical プロファイルでは必須( https://qiita.com/takeoverjp/items/9a3ea016c2eb30a0fd7a )になっている。

# 各社のSDK

何か1つドキュメントを見るならIntelを薦める。OpenCVの本家だけあってよく纏まっている。登録不要だし。

OpenCLにおけるpocl( http://portablecl.org/ )のようなベンダ独立実装は無いようだ。OpenCVをwrapしただけの実装とか有っても良いと思うんだけど。。

重要なのは、各社とも **OpenVXを単体では提供しない** 点。いずれもOpenCVもバンドルしていて、各社独自のニューラルネットワークフレームワークが提供されている。

## Intel OpenVINO

- ドキュメント: https://software.intel.com/en-us/openvino-ovx-guide
- ホームページ: https://01.org/openvinotoolkit

IntelはOpenVINOのブランド名で自社のOpenVXと他のビジョン系フレームワークを配布している。一応OpenVX標準のCNNも実装しているが、自社のInfering Engineライブラリで広範なアクセラレータをサポートしているためか、そちらを推奨している。OpenVXのバージョンは1.1。

ダウンロードには登録が必要だが、ドキュメントはそのままWebから読める。特にOpenVINOはヘテロジニアス実行をちゃんとOpenVX的な意味で考察していて https://software.intel.com/en-us/openvino-ovx-guide-heterogeneous-computing-with-openvino-toolkit 、OpenVXが当初想定していたエコシステムをしっかり体現している。

ただOpenVXの現状もよく反映していて、Deprecateされた機能としてリリースノートには3点挙がっている:

> - Vision Algorithm Designer (VAD) is deprecated.
> - OpenVX* code generation with the Deep Learning Model Optimizer is deprecated.
> - CNN support through OpenVX* is deprecated, use the Deep Learning Inference Engine. For documentation, please refer to https://software.intel.com/en-us/openvino-toolkit/documentation.

Vison Algorithm DesignerはGUIアプリでOpenVXのグラフを構築することができた: https://software.intel.com/en-us/sample-auto-contrast-using-vision-algorithm-designer-for-openvx-graphs

後者2つはNNに関するもので、IntelはAlteraから買収したFPGAやMovidiusから買収したNN専用エンジンなど大量のハードウェアを抱えており、かつ、ビジョンを中心としたOpenVXには合わないユースケースも目指す必要性があるため、あまりOpenVXに構っている余裕が無いのではないかと思う。移行先となるDeep Learning Deployment Toolkitは **OpenCVの** GitHub organizationの中にある( https://github.com/opencv/dldt )。

## AMD MIVisionX

- ホームページ: https://gpuopen-professionalcompute-libraries.github.io/MIVisionX/
- GitHub: https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/tree/master/amd_openvx
- ダウンロード: https://github.com/GPUOpen-ProfessionalCompute-Libraries/MIVisionX/releases

**オープンソース実装** (MIT)。AMDは自社の推論エンジンを提供するとともに、MSのWinMLの統合もOpenVXのノードとして提供している。IntelはOpenVXを拡張するスタイルを取らなかったのとは対称的と言える。

SDKはマジでDLLとヘッダしかなく、ドキュメントは殆どない。DLLはOpenVX 1.2を名乗るが、 `vxMatchTemplateNode` のような1.2で追加されたノードは提供されず、1.1相当のセットになっているようだ。また、OpenCVのアルゴリズムもいくつかOpenVXノードとして提供している。

## NVIDIA VisionWorks

- ホームページ: https://developer.nvidia.com/embedded/visionworks

NVIDIAのVisionWorksはOpenVXベースのプラットフォームでCUDAに最適化されている。ただし **Windowsサポートは1.5系を最後に廃止された** 。

OpenVX 1.1実装と、OpenCV統合用ライブラリ、いくつかの専用ノード(ステレオマッチング等)を備えている。

## NXP VisionSDK

- ホームページ: https://www.nxp.com/support/developer-resources/software-development-tools/vision-sdk-studio:VISION-SDK-STUDIO

手元の環境ではインストールできなかった。。詳細不明。

## Khronos サンプル実装

- GitHub: https://github.com/KhronosGroup/OpenVX-sample-impl

**コレは熱い** 。KhronosはOpenVXのサンプル実装を提供しており、OpenCVをwrapしたりはしていない、 **Cによる手書き実装** となっている。オープンソース実装(Apache2.0)。

実用向きではないとしているが、実際に使ってみたらどれくらいの速度になるのかは気になるところ。OpenVGのサンプル実装( https://www.khronos.org/registry/OpenVG/ )は本当にマジで遅かったので期待を裏切らないパフォーマンスだとは思うけど。。

公開されているものとしては、事実上唯一のOpenVX 1.2実装と言える。

# リソース

他のKhronos規格に漏れず、OpenVXもドキュメントやCTS(テストスイート)がGitHub上に置かれている:

- https://github.com/KhronosGroup/OpenVX-Registry
- https://github.com/KhronosGroup/OpenVX-cts
- https://github.com/KhronosGroup/OpenVX-api-docs
- https://github.com/KhronosGroup/OpenVX-sample-impl

コンフォーマンステストが公開されたのは2018年の暮れで、ちょっと遅かったんじゃないかという気がする。

ちなみに、コンフォーマンステストはOpenCVの出力をリファレンス出力として採用していて、NNのテスト https://github.com/KhronosGroup/OpenVX-cts/tree/openvx_1.2/test_conformance/Networks/src にはAlexNetやGooglenetを含んでいる。

# 今後

ビジョンアプリケーションの前処理/後処理は無くならないので、そこには居場所があるような気がしないでもない。つまり、Intel/AMDいずれも、

1. プリミティブ処理のためのOpenVX
2. NNモデルのインポートと最適化を行うオフラインツール

の2点でSDKを構成しているので、OpenVXの方も最適化実行のためのオフラインツールを持っても良いと思っている。つまり、APIをグラフをオフラインで構築するためのTooling APIと、エッジデバイスで実際にグラフを実行するためのRuntime APIに分割すべきなのではないだろうか。

明快な実行モデルを持っていることとC APIであることはOpenCVとの差別化要素とも言えるが、まぁモバイルプラットフォームにはそれぞれ専用のAPIが有るし。。

インダストリの合意で構成されるとOpenVXと、兎に角動くものが大量に突っ込まれているOpenCVの対比は、何というか世間に求められているものを象徴しているように思える。最近Khronosは多くのWGをInactiveに分類していて、OpenXRの次に新しいAPI WGであるOpenVXでさえこの状況であることを考えると、もうAPI標準は世間的に求められていないのではないかという気がしてくる。