加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 服务器 > 系统 > 正文

从R调用CUDA编译的.dll

发布时间:2021-01-27 05:07:20 所属栏目:系统 来源:网络整理
导读:副标题#e# 我正在使用 Windows 7平台. 我将逐步介绍我执行的所有例程,以获取.dll文件(PASS),dyn.在R(PASS)中加载它并在R(FAIL)中唤起.Call函数. 当唤起.Call我得到: out- .Call("rowAND",as.integer(t(m)),nrow(m),ncol(m))**Error in .Call("rowAND",ncol
副标题[/!--empirenews.page--]

我正在使用 Windows 7平台.

我将逐步介绍我执行的所有例程,以获取.dll文件(PASS),dyn.在R(PASS)中加载它并在R(FAIL)中唤起.Call函数.

当唤起.Call我得到:

> out<- .Call("rowAND",as.integer(t(m)),nrow(m),ncol(m))
**Error in .Call("rowAND",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 thread per block
    rowOR<<<numBlocks,threadsPerBlock,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,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),ncol)
> out<- .Call("rowAND",ncol(m))
Error in .Call("rowAND",ncol(m)) : 
  C symbol name "rowAND" not in load table

我看到该函数似乎在源代码中正确定义,但在加载的库中无法“看到”.

我在这里缺少什么?提前致谢!

编辑:

基于@Dirk部分答案,将尝试编写将由C调用的CUDA dll项目.因此,我可以使用标准R CMD SHLIB编译目标C源.

喜欢:C(dll),部署到R里面调用CUDA dll.

完成后会更新!

编辑2:

我在下面回答了我自己的问题.我终于可以在R(WINDOWS平台)中实现CUDA了

解决方法

对于那些遇到同样困难的人,我决定回答我自己的问题.我可以将答案归类为问题的解决方法.

一天结束,我的问题是使用WINDOWS平台在R中实现CUDA GPU并行性.

我看到实现CUDA的大多数CRAN包(并非所有)都没有WINDOWS平台的二进制文件.换句话说,如果你尝试在WINDOWS中从源代码构建它就会失败.我猜他们还没有为WINDOWS构建,因为使用MinGW和nvcc编译器在WINDOWS中编译和链接.cu文件是一种技巧.

NVidia将VS2010作为WINDOWS开发的主要平台,eclipse插件仅支持Linux.虽然,nvcc编译器支持-ccbin选项,可以让它调用gcc,但配置“工具链”真是绝招.

我的解决方法是在VS2010中开发DLL项目,并使用VS2010本机编译器/链接器编译和链接DLL.

这个dll是内部调用CUDA GPU并行性的部分.

在VS2010中编译之后,我使用dyn.load()加载了dll,并在R中使用.C调用了它的函数.

它终于奏效了,最后我可以在WINDOWS平台上将CUDA GPU并行功能部署到R.

我可以使用NAMESPACE在包中部署相同的.dll,并在CRAN tar ball中提供dll源代码,旨在不侵犯开源策略.无论如何,这是一种解决方法.

两个重要因素:

1)使用extern“C”部署本机C中的所有导出函数.

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读