3

Windows 7 プラットフォームを使用しています。

以下に、.dll ファイルを取得する (PASS)、R で dyn.load する (PASS)、R で .Call 関数を呼び出す (FAIL) ために実行するすべてのルーチンを段階的に説明します。

.Call を呼び出すと、次のようになります。

> out<- .Call("rowAND", as.integer(t(m)), nrow(m), ncol(m))
**Error in .Call("rowAND", as.integer(t(m)), nrow(m), ncol(m)) : 
  C symbol name "rowAND" not in load table**

1) ソースコードの下:

#include <stdio.h>
#include <math.h>

#include <cuda_runtime.h>
#include <cuda.h>
#include <device_launch_parameters.h>

#include <R.h>
#include <Rdefines.h>

#include "cuPrintf.cuh"
#include "cuPrintf.cu"

#include "cuRow.h"
#include "cuError.h"

extern "C" { 
SEXP rowAND(SEXP x, SEXP r_nrow, SEXP r_ncol) {
    // input: 
    //              x=as.integer(t(m)), vector of integer values from R (t(m) because store values by col)
    //              r_nrow=nrow(m), scalar
    //              r_ncol=ncol(m), scalar

    //x = coerceVector(x, INTSXP); // force coercion to a matrix of real values

    // define deimension
    int nrow = asInteger(r_nrow);
    int ncol = asInteger(r_ncol);
    size_t m_size;
    size_t calc_size;
    m_size = nrow * ncol * sizeof(int); // m (input)
    calc_size = nrow * sizeof(int); // change to nrow/ncol depending on calculation (output)

    // R
    SEXP r;
    PROTECT(r = allocMatrix(INTSXP,nrow,1));

    // cuda error variable
    cudaError_t err;

    // allocate HOST 
    int *h_m = INTEGER(x);
    int *h_calc = INTEGER(r);

    // allocate DEVICE
    int *d_m = NULL, *d_calc = NULL;
    err = cudaMalloc((void **)&d_m, m_size); checkError(err);
    err = cudaMalloc((void **)&d_calc, calc_size); checkError(err);

    // copy host matrix to device
    err = cudaMemcpy(d_m, h_m, m_size, cudaMemcpyHostToDevice); checkError(err);

    // Initialize cuPrintf -- DEBUGGING
    cudaPrintfInit();

    dim3 numBlocks(nrow,1,1); // blocks
    dim3 threadsPerBlock(1,1,1); // 1 thread per block
    rowOR<<<numBlocks, threadsPerBlock,0,0>>>(d_m, d_calc, ncol); // main call

    // Terminate cuPrintf -- DEBUGGING
    cudaPrintfDisplay (stdout, true);
    cudaPrintfEnd ();

    err = cudaGetLastError(); checkError(err);

    // Copy the device result vector in device memory to the host result vector
    err = cudaMemcpy(h_calc, d_calc, calc_size, cudaMemcpyDeviceToHost); checkError(err);

    // Free device global memory
    err = cudaFree(d_m); checkError(err);
    err = cudaFree(d_calc); checkError(err);

    // Reset the device
    err = cudaDeviceReset();

    UNPROTECT(1);
    return r;
}

2) オブジェクト (.obj) を生成する nvcc を使用して、.cu ファイルをコンパイルします。したがって、ライブラリをリンクします (PASS)。ここでは問題ありません。.dll ファイルが生成されます。

3) R コマンドを使用して .dll をロードするとき: dyn.load IT PASS。ロードされた .dll は次の場所に表示されますgetLoadedDLLs()

> getLoadedDLLs()
                                                                                  Filename Dynamic.Lookup
base                                                                                  base          FALSE
methods       C:/Revolution/R-Community-6.2/R-2.15.3/library/methods/libs/i386/methods.dll          FALSE
Revobase    C:/Revolution/R-Community-6.2/R-2.15.3/library/Revobase/libs/i386/Revobase.dll           TRUE
tools             C:/Revolution/R-Community-6.2/R-2.15.3/library/tools/libs/i386/tools.dll          FALSE
grDevices C:/Revolution/R-Community-6.2/R-2.15.3/library/grDevices/libs/i386/grDevices.dll          FALSE
stats             C:/Revolution/R-Community-6.2/R-2.15.3/library/stats/libs/i386/stats.dll          FALSE
cuRow           C:/Users/msn/Documents/Visual Studio 2010/Projects/R_C/R_C/Debug/cuRow.dll           TRUE

4)ここに問題があります:関数rowANDがロードされているかどうかを確認すると、FALSEが表示されます:

> is.loaded("rowAND")
[1] FALSE
> 

したがって、明らかに、.Call を実行すると失敗します (ロードされていないため)。

> path.dll<-'C:/Users/msn/Documents/Visual Studio 2010/Projects/R_C/R_C/Debug'
> dyn.load(file.path(path.dll,paste0("cuRow", .Platform$dynlib.ext)))
> nrow<-10
> ncol<-3
> m<-matrix(sample(c(0,1),nrow*ncol,replace=TRUE),nrow,ncol)
> out<- .Call("rowAND", as.integer(t(m)), nrow(m), ncol(m))
Error in .Call("rowAND", as.integer(t(m)), nrow(m), ncol(m)) : 
  C symbol name "rowAND" not in load table

ソース コードでは関数が正しく定義されているように見えますが、読み込まれたライブラリでは「見えません」。

ここで何が欠けていますか?前もって感謝します!

編集:

@Dirkの部分的な回答に基づいて、Cによって呼び出されるCUDA dllプロジェクトを作成しようとします。したがって、標準のR CMD SHLIBを使用してターゲットCソースをコンパイルできます。

のように: C (dll)、内部で CUDA dll を呼び出す R にデプロイされます。

完了したら更新します!

編集2:

私は以下の私自身の質問に答えました。( )でようやくCUDA実装できましたRWINDOWS platform

4

3 に答える 3

2

あなたのケースで私がすることは、CRANで公開されている CUDA の既存の R パッケージを非常に詳しく調べることです。少なくともこれらのいくつかは Windows でも構築できると思います。

CUDA を使用する CRAN パッケージには、

もっと。詳細については、ハイパフォーマンス コンピューティングの CRAN タスク ビューを参照してください。

私は最初の(そして最も古い)ものに最も精通しています。コードの 1 つのレイヤーを使用して R から C を呼び出し、次に別のレイヤーを使用して C から NVidia のコンパイラ フロントエンドでコンパイルされた CUDA 対応コードを呼び出します。最後の例では、R から C/C++ への移行に Rcpp を使用しています。あなたのエラーは、1 つのステップをスキップしようとしたことが原因であると思われます。

于 2013-07-14T01:06:47.883 に答える
1

Windows 上の Visual Studio で CUDA を使用して R をコンパイルする場合、いくつかの重要なことがあります。

  1. __declspec(dllexport)キーワードで C 関数を宣言します( extern "C"のインストール)

    extern “C” __declspec(dllexport)
    
  2. R (32 ビットまたは 64 ビット) で同じバージョンをビルドします。そうしないと、R での DLL のロードは次のように失敗します。

ライブラリのロード エラー: %1 は有効な Win32 アプリケーションではありません。

  1. Visual Studio に CUDA ライブラリを正しくインクルードします。一般に、次の場所に追加されます。

ソリューション エクスプローラー → プロジェクト名

プロパティ→リンカー→入力→追加の依存関係

その他の詳細な手順については、NVIDIA ブログParallelRを参照してください。

于 2015-01-31T00:44:11.237 に答える