【问题标题】:Linking properly object files with nvcc (CUDA-RINSIDE)使用 nvcc (CUDA-RINSIDE) 正确链接对象文件
【发布时间】:2018-07-23 09:21:07
【问题描述】:

我正在尝试让Rinside 使用一些CUDA 代码。我第一次尝试直接用 NVCC 编译它们,但是用 nvcc 处理 Rinside 是不可能的,所以现在我正在尝试另一种方法。

我用g++ 编译Rinside 代码并获得目标文件(.o) 然后用nvcc 编译一些CUDA 代码并获得另一个.o,然后将它们链接在一起,但我得到一些“未引用错误”。

这是 RINSIDE 代码:

#include <RInside.h>                            // for the embedded R via RInside

extern "C"
void someCUDAcode();


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

    RInside R(argc, argv);                      // create an embedded R instance 
    someCUDAcode();
    exit(0);

}

这是 CUDA 代码:

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

__global__ void mykernel(int a){
  int id = threadIdx.x;
  int b = a;
  b++;
  id++;
}


extern "C"
void someCUDAcode() {
  mykernel<<<1, 1>>>(1);
}

这是我的makefile:

## and set R_HOME accordingly as an environment variable
R_HOME :=       $(shell R RHOME)

sources :=      $(wildcard *.cpp)
programs :=         $(sources:.cpp=)


## include headers and libraries for R 
RCPPFLAGS :=        $(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS :=         $(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS :=        $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK :=      $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)

## if you need to set an rpath to R itself, also uncomment
#RRPATH :=      -Wl,-rpath,$(R_HOME)/lib

## include headers and libraries for Rcpp interface classes
## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted
RCPPINCL :=         $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
##RCPPLIBS :=       $(shell echo 'Rcpp:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)


## include headers and libraries for RInside embedding classes
RINSIDEINCL :=      $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS :=      $(shell echo 'RInside:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)

## compiler etc settings used in default make rules
ifeq ($(HOST_OS),darwin)
    CXX := clang++ $(shell $(R_HOME)/bin/R CMD config CXX)
else
    CXX := $(shell $(R_HOME)/bin/R CMD config CXX)
endif
CPPFLAGS :=         -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS)
CXXFLAGS :=         $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
LDLIBS :=       $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS)

#########################################
CUDA_HOME = /usr/local/cuda-9.1


# This defines what the shared object libraries will be
PKG_LIBS= -L/usr/local/cuda-9.1/lib64 -Wl,-rpath,/usr/local/cuda-9.1/lib64 -lcudart -d

NVCC = $(CUDA_HOME)/bin/nvcc
CUDA_INC = $(CUDA_HOME)/include 
CUDA_LIB = $(CUDA_HOME)/lib64
R_INC = /usr/share/R/include
LIBS = -lcudart -d
NVCC_FLAGS = -Xcompiler "-fPIC" -I$(R_INC)

##-gencode arch=compute_20,code=sm_20 -gencode arch=compute_30,code=sm_30 -gencode arch=compute_35,code=sm_35 
### Define objects
cu_sources := $(wildcard *cu)
cu_sharedlibs := $(patsubst %.cu, %.o,$(cu_sources))

cpp_sources := $(wildcard *.cpp)
cpp_sharedlibs := $(patsubst %.cpp, %.o, $(cpp_sources))

OBJECTS = $(cu_sharedlibs) $(cpp_sharedlibs)

all : test.exe

test.exe: $(OBJECTS)

%.o: %.cpp $(cpp_sources)
        $(CXX) $< -c -fPIC -I$(CPPFLAGS) $(CXXFLAGS) $(LDLIBS)

%.o: %.cu $(cu_sources)
        $(NVCC) $(NVCC_FLAGS) -I$(CUDA_INC) $< -c

当我“制作”makefile 正确编译所有内容时,我获得了我的.o 文件,但是无法创建可执行文件。当我尝试使用“nvcctest.ocuda.o”编译它们时,我收到此错误:

pesco@pesco-PC:~/Scrivania/PURECUDA$ nvcc -o someCUDAcode.o test.o
test.o: nella funzione "Rcpp::Rstreambuf<false>::xsputn(char const*, long)":
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:56: riferimento non definito a "REprintf"
test.o: nella funzione "Rcpp::Rstreambuf<false>::sync()":
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:80: riferimento non definito a "R_FlushConsole"
test.o: nella funzione "Rcpp::Rstreambuf<true>::sync()":
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:76: riferimento non definito a "R_FlushConsole"
test.o: nella funzione "Rcpp::Rstreambuf<true>::xsputn(char const*, long)":
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:52: riferimento non definito a "Rprintf"
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:52: riferimento non definito a "Rprintf"
test.o: nella funzione "Rcpp::Rstreambuf<false>::xsputn(char const*, long)":
/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include/Rcpp/iostream/Rstreambuf.h:56: riferimento non definito a "REprintf"
test.o: nella funzione "main":
/home/pesco/Scrivania/PURECUDA/test.cpp:18: riferimento non definito a "RInside::RInside(int, char const* const*, bool, bool, bool)"
/home/pesco/Scrivania/PURECUDA/test.cpp:19: riferimento non definito a "someCUDAcode"
/home/pesco/Scrivania/PURECUDA/test.cpp:18: riferimento non definito a "RInside::~RInside()"
collect2: error: ld returned 1 exit status

但我不知道如何处理这个错误。我怎样才能正确地将它们链接在一起?谢谢你:)

我正在合作:

CUDA 9.1:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85

NVIDIA 驱动程序:

pesco@pesco-PC:~/Scrivania/PURECUDA$ nvidia-smi
Mon Jul 23 11:16:50 2018       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.48                 Driver Version: 390.48                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GT 740M     Off  | 00000000:01:00.0 N/A |                  N/A |
| N/A   58C    P8    N/A /  N/A |    110MiB /  2004MiB |     N/A      Default |
+-------------------------------+----------------------+----------------------+

UBUNTU 16.04 LTS G++:g++(Ubuntu 5.4.0-6ubuntu1~16.04.10)5.4.0 20160609

我希望我说清楚了,对不起我的英语!

【问题讨论】:

  • 我建议使用 Rinside 构建系统,然后链接附加的 CUDA 目标文件和库 (libcudart.so)。正如您在问题中所展示的那样,您显然需要链接很多 R 内部组件以使其正常工作,我不确定这是否可行
  • 看来R CMD config --ldflags 应该告诉您需要链接哪些内容以及链接它们所需的路径,如果您希望 nvcc 为您执行此操作
  • 非常感谢!!我会立即尝试做的!
  • 天哪,它工作!从 Rinside 构建系统开始,然后添加 .o 和 libcudart.so 使其工作,非常感谢!
  • 请写一个简短的答案,详细说明您是如何解决问题的。我会投票以确保这个问题被标记为已回答

标签: c++ r cuda


【解决方案1】:

正如@talonmies 建议的那样,您可以解决“未引用错误”,只需在使用 g++ 编译时添加 CUDA 对象文件和库,确切地说,我在 RInside 的示例文件夹中获取了一个新的 makefile,然后我添加到 LDLIBS .o 和 .so 的路径我刚刚从我之前的编译中获得并且一切正常,我不知道它是否正常工作,但至少我们有一个可执行文件!确切地说,这是新的 makefile:

R_HOME :=       $(shell R RHOME)

sources :=      $(wildcard *.cpp)
programs :=         $(sources:.cpp=)


## include headers and libraries for R 
RCPPFLAGS :=        $(shell $(R_HOME)/bin/R CMD config --cppflags)
RLDFLAGS :=         $(shell $(R_HOME)/bin/R CMD config --ldflags)
RBLAS :=        $(shell $(R_HOME)/bin/R CMD config BLAS_LIBS)
RLAPACK :=      $(shell $(R_HOME)/bin/R CMD config LAPACK_LIBS)

## if you need to set an rpath to R itself, also uncomment
#RRPATH :=      -Wl,-rpath,$(R_HOME)/lib

## include headers and libraries for Rcpp interface classes
## note that RCPPLIBS will be empty with Rcpp (>= 0.11.0) and can be omitted
RCPPINCL :=         $(shell echo 'Rcpp:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RCPPLIBS :=         $(shell echo 'Rcpp:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)

##NVCC HEADER AND DECLARATION TO CREATE THE CUDA OBJECT FILE

## include headers and libraries for RInside embedding classes
RINSIDEINCL :=      $(shell echo 'RInside:::CxxFlags()' | $(R_HOME)/bin/R --vanilla --slave)
RINSIDELIBS :=      $(shell echo 'RInside:::LdFlags()'  | $(R_HOME)/bin/R --vanilla --slave)

## compiler etc settings used in default make rules
CXX :=          $(shell $(R_HOME)/bin/R CMD config CXX)
CPPFLAGS :=         -Wall $(shell $(R_HOME)/bin/R CMD config CPPFLAGS)
CXXFLAGS :=         $(RCPPFLAGS) $(RCPPINCL) $(RINSIDEINCL) $(shell $(R_HOME)/bin/R CMD config CXXFLAGS)
LDLIBS :=       $(RLDFLAGS) $(RRPATH) $(RBLAS) $(RLAPACK) $(RCPPLIBS) $(RINSIDELIBS) /home/pesco/Scrivania/NEWTRY/someCUDAcode.o /usr/local/cuda/lib64/libcudart.so


all:        $(programs)
            @test -x /usr/bin/strip && strip $^

run:            $(programs)


clean:
            rm -vf $(programs)
            rm -vrf *.dSYM

还有新的 .cpp:

#include <RInside.h>         

extern "C"
void someCUDAcode();
           // for the embedded R via RInside

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

    RInside R(argc, argv);              // create an embedded R instance 

    someCUDAcode();

    R["txt"] = "Hello, world!\n";   // assign a char* (string) to 'txt'

    R.parseEvalQ("cat(txt)");           // eval the init string, ignoring any returns

    exit(0);
}

这是我通过“make”获得的:

g++ -I/usr/share/R/include -I/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/Rcpp/include -I/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/RInside/include -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g -Wall    rinside_sample0.cpp  -Wl,--export-dynamic -fopenmp  -L/usr/lib/R/lib -lR -lpcre -llzma -lbz2 -lz -lrt -ldl -lm  -lblas -llapack  -L/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/RInside/lib -lRInside -Wl,-rpath,/home/pesco/R/x86_64-pc-linux-gnu-library/3.2/RInside/lib /home/pesco/Scrivania/NEWTRY/someCUDAcode.o /usr/local/cuda/lib64/libcudart.so -o rinside_sample0

并运行可执行文件:

pesco@pesco-PC:~/Scrivania/NEWTRY$ ./rinside_sample0 
Hello, world!

【讨论】:

  • 完美!如果您愿意,几天后您将能够接受您的回答。
  • 非常感谢你,我会继续努力,如果我发现有什么奇怪的,我会立即报告!现在看起来很好,再次感谢您!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 2016-06-24
  • 1970-01-01
  • 2014-12-25
  • 2014-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多