43

高レベルで GPU ベースの処理を可能にする C++ のライブラリ/拡張機能を調べています。私は GPU プログラミングの専門家ではないので、あまり深く掘り下げたくありません。仮想関数を持つクラスで構成されるニューラル ネットワークがあります。基本的に、GPU の割り当てを高レベルで行うライブラリが必要です。ほとんどの GPU 処理を行う GPU++ というシステムについて論文を書いた人がいます。コードはどこにも見つかりません。彼の論文だけです。

同様のライブラリを知っている人はいますか、または GPU++ のコードを持っている人はいますか? CUDA のようなライブラリはレベルが低すぎて、ほとんどの操作を処理できません (少なくとも、すべてのプロセスとアルゴリズムを書き直す必要があります。これはやりたくないことです)。

4

8 に答える 8

56

GPGPU プログラミング専用の高レベル ライブラリが多数あります。それらは CUDA や OpenCL に依存しているため、賢明に選択する必要があります (CUDA ベースのプログラムは、gpuocelotなどのプロジェクトで前処理ステップを経ない限り、AMD の GPU では実行されません)。

CUDA

NVIDIA のWeb サイトで、CUDA ライブラリの例をいくつか見つけることができます。

  • スラスト: 公式の説明がそれ自体を物語っています

Thrust は、C++ 標準テンプレート ライブラリ (STL) に似た並列アルゴリズム ライブラリです。Thrust の高レベル インターフェイスは、GPU とマルチコア CPU 間のパフォーマンスの移植性を可能にしながら、プログラマーの生産性を大幅に向上させます。確立されたテクノロジ (CUDA、TBB、OpenMP など) との相互運用性により、既存のソフトウェアとの統合が容易になります。

@Ashwin指摘したように、Thrust の STL に似た構文により、CUDA プログラムを開発する際に広く選択されたライブラリになります。例をざっと見てみると、このライブラリを使用することに決めた場合に作成するコードの種類がわかります。NVIDIA の Web サイトでは、このライブラリの主な機能が紹介されています。ビデオ プレゼンテーション(GTC 2012 から)も利用できます。

  • CUB : 公式の説明によると:

CUB は、CUDA プログラミング モードのすべてのレイヤーに最先端の再利用可能なソフトウェア コンポーネントを提供します。これは、CUDA カーネル プログラミング用の協調スレッドブロック プリミティブおよびその他のユーティリティの柔軟なライブラリです。

並列ソート、プレフィックススキャン、リダクション、ヒストグラムなど、デバイス全体、ブロック全体、およびワープ全体の並列プリミティブを提供します。

これはオープンソースであり、GitHubで入手できます。実装の観点からは高レベルではありません (CUDA カーネルで開発します) が、高レベルのアルゴリズムとルーチンを提供します。

  • mshadow : C++/CUDA の軽量 CPU/GPU マトリックス/テンソル テンプレート ライブラリ。

このライブラリは主に機械学習に使用され、式テンプレートに依存しています。

Eigen 3.3 から、CUDA カーネル内で Eigen のオブジェクトとアルゴリズムを使用できるようになりました。ただし、CUDA カーネル内で動的割り当てがトリガーされないようにするために、機能のサブセットのみがサポートされています。

OpenCL

OpenCLは異種プラットフォーム (マルチコア CPU、GPU など) をサポートするため、GPGPU コンピューティング以上のことを行うことに注意してください。

  • OpenACC : このプロジェクトは、GPGPU に OpenMP のようなサポートを提供します。プログラミングの大部分は、コンパイラとランタイム API によって暗黙的に行われます。サンプルコードは Web サイトで見つけることができます

OpenACC アプリケーション プログラム インターフェイスは、ホスト CPU から接続されたアクセラレータにオフロードされる標準 C、C++、および Fortran のコードのループと領域を指定するコンパイラ ディレクティブのコレクションを記述し、オペレーティング システム、ホスト CPU、およびアクセラレータ間の移植性を提供します。

  • Bolt : STL に似たインターフェースを備えたオープンソース ライブラリ。

Bolt は、異種コンピューティング用に最適化された C++ テンプレート ライブラリです。Bolt は、scan、reduce、transform、sort などの一般的なアルゴリズムの高性能ライブラリ実装を提供するように設計されています。Bolt インターフェイスは、C++ 標準テンプレート ライブラリ (STL) をモデルにしています。STL に精通している開発者は、Bolt API とカスタマイズ手法の多くを認識するでしょう。

  • Boost.Compute : @Kyle Lutzが言ったように、Boost.Compute は OpenCL に STL のようなインターフェイスを提供します。これは公式の Boost ライブラリではないことに注意してください (まだ)。

  • SkelCLは、「最新の並列異種システムのプログラミングを軽減するための高レベルの抽象化を提供するライブラリです」。このライブラリはスケルトン プログラミングに依存しており、詳細については研究論文を参照してください。

CUDA + OpenCL

  • ArrayFireは、オープンソースの (以前はプロプライエタリであった) GPGPU プログラミング ライブラリです。最初は CUDA をターゲットにしていましたが、現在は OpenCL もサポートしています。オンラインで入手可能なを確認NVIDIA の Web サイトには、主要な機能の概要がよくまとめられています。

補足情報

これは実際にはこの質問の範囲内ではありませんが、他のプログラミング言語にも同様のサポートがあります。

線形代数 (たとえば) やその他の特定の操作を行う必要がある場合は、CUDA および OpenCL 用の専用数学ライブラリも利用できます (例: ViennaCLCUBLASMAGMAなど)。

また、これらのライブラリを使用しても、非常に特殊な計算を行う必要がある場合、低レベルの操作を実行できなくなるわけではないことに注意してください。

最後に、C++ 標準ライブラリの将来について言及できます。並列処理のサポートを追加するための広範な作業が行われました。これはまだ技術仕様であり、GPU について明確に言及されているわけではありません (Thrust の開発者である NVIDIA の Jared Hoberock が直接関与していますが) が、これを実現する意志は間違いなくそこにあります。

于 2013-05-12T08:52:04.727 に答える
35

Thrustライブラリは、コンテナー、並列プリミティブ、およびアルゴリズムを提供します。この機能はすべて、STL に似た構文にうまくまとめられています。そのため、STL に精通している場合は、CUDA カーネルを 1 つも作成しなくても、Thrust だけを使用して CUDA プログラム全体を実際に作成できます。クイック スタート ガイドの簡単な例を見て、Thrust を使用して記述できる高レベルのプログラムの種類を確認してください。

于 2013-05-10T08:52:08.627 に答える
2

高次元のコンテナーと、これらのコンテナーをカーネル コードで渡したり操作したりする機能を探している場合、私はここ数年、自分の科学研究プロジェクトを支援するためにecuda API の開発に費やしてきました (そのため、ペース)。うまくいけば、それは必要なニッチを埋めることができます. 使用方法の簡単な例 (ここでは C++11 の機能が使用されていますが、ecuda は C++11 より前のコンパイラでも問題なく動作します):

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <vector>

#include <ecuda/ecuda.hpp>

// kernel function
__global__
void calcColumnSums(
  typename ecuda::matrix<double>::const_kernel_argument mat,
  typename ecuda::vector<double>::kernel_argument vec
)
{
    const std::size_t t = threadIdx.x;
    auto col = mat.get_column(t);
    vec[t] = ecuda::accumulate( col.begin(), col.end(), static_cast<double>(0) );
}

int main( int argc, char* argv[] )
{

    // allocate 1000x1000 hardware-aligned device memory matrix
    ecuda::matrix<double> deviceMatrix( 1000, 1000 );

    // generate random values row-by-row and copy to matrix
    std::vector<double> hostRow( 1000 );
    for( std::size_t i = 0; i < 1000; ++i ) {
        for( double& x : hostRow ) x = static_cast<double>(rand())/static_cast<double>(RAND_MAX);
        ecuda::copy( hostRow.begin(), hostRow.end(), deviceMatrix[i].begin() );
    }

    // allocate device memory for column sums
    ecuda::vector<double> deviceSums( 1000 );

    CUDA_CALL_KERNEL_AND_WAIT(
        calcColumnSums<<<1,1000>>>( deviceMatrix, deviceSums )
    );

    // copy columns sums to host and print
    std::vector<double> hostSums( 1000 );
    ecuda::copy( deviceSums.begin(), deviceSums.end(), hostSums.begin() );

    std::cout << "SUMS =";
    for( const double& x : hostSums ) std::cout << " " << std::fixed << x;
    std::cout << std::endl;

    return 0;

}

できるだけ直感的になるように書きました (通常は、std:: を ecuda:: に置き換えるのと同じくらい簡単です)。STL を知っている場合、ecuda は、CUDA ベースの C++ 拡張機能が行うことを論理的に期待することを行う必要があります。

于 2016-02-02T20:54:07.897 に答える
2

もう 1 つの高レベル ライブラリはVexCLです。これは、OpenCL 用のベクトル式テンプレート ライブラリです。ベクトル演算の直感的な表記法を提供し、MIT ライセンスの下で利用できます。

于 2013-05-18T06:38:28.720 に答える
1

cpp-opencl プロジェクトは、開発者が GPU を簡単にプログラミングできるようにする方法を提供します。OpenCL を使用する代わりに、C++ で直接 GPU にデータ並列処理を実装できます。

http://dimitri-christodoulou.blogspot.com/2014/02/implement-data-parallelism-on-gpu.htmlをご覧ください。

ソースコード: https://github.com/dimitrs/cpp-opencl

以下の例を参照してください。parallel_for_each ラムダ関数のコードは GPU で実行され、残りはすべて CPU で実行されます。より具体的には、「square」関数は、CPU (std::transform への呼び出しを介して) と GPU (compute::parallel_for_each への呼び出しを介して) の両方で実行されます。

#include <vector>
#include <stdio.h>
#include "ParallelForEach.h"

template<class T> 
T square(T x)  
{
    return x * x;
}

void func() {
  std::vector<int> In {1,2,3,4,5,6};
  std::vector<int> OutGpu(6);
  std::vector<int> OutCpu(6);

  compute::parallel_for_each(In.begin(), In.end(), OutGpu.begin(), [](int x){
      return square(x);
  });


  std::transform(In.begin(), In.end(), OutCpu.begin(), [](int x) {
    return square(x);
  });

  // 
  // Do something with OutCpu and OutGpu …..........

  //

}

int main() {
  func();
  return 0;
}
于 2014-02-07T19:43:37.440 に答える