在.c文件中调用cuda函数
2014-04-19 17:17
330 查看
在.c文件中调用cuda函数
2014-04-19 17:17446人阅读 评论(0)
收藏
举报
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/b367fdce88ee208da19a58e7fab01f44.jpg)
分类:
cuda编程(1)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/b16356edc9d65f9de5798055c2b20c3c.jpg)
版权声明:本文为博主原创文章,未经博主允许不得转载。
问题描述:假设在Ubuntu的一个用户目录下有2个文件,main.c, VectorAdd.cu,其中 VectorAdd.cu有vectorAdd函数,main.c提供程序的入口main函数。现在为了在main.c中实现两个向量相加的操作,就需要调用 VectorAdd.cu中的vectorAdd函数
首先列出两个文件中的内容
[cpp]
view plain
copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//VectorAdd.cu
#include <cutil.h>
extern "C" void VectAdd(int *a, int *b, int *c, int length);
__global__ void Add(int *d_a, int *d_b, int *d_c, int length)
{
int id = threadIdx.x;
if(id < length)
d_c[id] = d_a[id] + d_b[id];
}
void VectAdd(int *a, int *b, int *c, int length)
{
unsigned int size = sizeof(int) * length;
int *d_a;
cudaMalloc((void**)&d_a,size);
int *d_b;
cudaMalloc((void**)&d_b,size);
int *d_c;
cudaMalloc((void**)&d_c,size);
cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);
cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);
Add<<<1, length>>>(d_a, d_b, d_c, length);
cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);
cudaFree(d_a);
cudaFree(d_b);
cudaFree(d_c);
}
//main.c文件
#include <stdio.h>
#include <malloc.h>
int main()
{
int *a, *b, *c;
int length = 32;
int i;
a = (int*)malloc(sizeof(int) * length);
b = (int*)malloc(sizeof(int) * length);
c = (int*)malloc(sizeof(int) * length);
for(i = 0; i < length; ++i)
{
a[i] = i;
b[i] = i;
}
VectAdd(a,b,c,length);
for(i = 0; i < length; i++)
{
printf("%d ",c[i]);
}
printf("\n");
return 0;
}
.cu文件实际上是按c++的语法规则来编译的,因此上述问题的实质也是如何在.c文件中调用.cpp,为方便讨论,假设在.c文件中调用.cu中的函数,为.cu文件使用nvcc编译,对.c文件使用gcc编译,具体的编译命令如在makefile文件所示:
[cpp]
view plain
copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
default: libcuda run
CUDA_DIR=/usr/local/cuda
SDK_DIR=/home/NVIDIA_GPU_Computing_SDK/C
CC=nvcc
C = gcc
CPP = g++
SOURCE = main.c
DEST = main
libcuda:
$(CC) $(INC) $(LIB) -c VectorAdd.cu -o VectorAddCu.o
ar cr libVectorAddCu.a VectorAddCu.o
run:
<span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a
$(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>
这篇《在.c文件中调用cuda函数》与《在.c文件中调用c++定义的函数》有很多相同的地方,详细的讲解我不再说明,不懂的可以去这里看,在.c文件中调用c++定义的函数,这里我主要说说两者的不同。
上面的Makefile文件中有这样一句话:
[cpp]
view plain
copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
-L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a
通过测试,如果不要这句话就会出现下面这样的错误:
[cpp]
view plain
copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
libVectAddCu.a(VectAddCu.o): In function `__sti____cudaRegisterAll_42_tmpxft_00004317_00000000_4_VectAdd_cpp1_ii_e5583c85()':
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xe): undefined reference to `__cudaRegisterFatBinary'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x69): undefined reference to `__cudaRegisterFunction'
libVectAddCu.a(VectAddCu.o): In function `__cudaUnregisterBinaryUtil()':
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x88): undefined reference to `__cudaUnregisterFatBinary'
libVectAddCu.a(VectAddCu.o): In function `__device_stub__Z3AddPiS_S_i(int*, int*, int*, int)':
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xb4): undefined reference to `cudaSetupArgument'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xd0): undefined reference to `cudaSetupArgument'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xec): undefined reference to `cudaSetupArgument'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x108): undefined reference to `cudaSetupArgument'
libVectAddCu.a(VectAddCu.o): In function `VectAdd':
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x187): undefined reference to `cudaMalloc'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x193): undefined reference to `cudaMalloc'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x19f): undefined reference to `cudaMalloc'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1b4): undefined reference to `cudaMemcpy'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1c9): undefined reference to `cudaMemcpy'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x216): undefined reference to `cudaConfigureCall'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x243): undefined reference to `cudaMemcpy'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x24c): undefined reference to `cudaFree'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x255): undefined reference to `cudaFree'
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x25e): undefined reference to `cudaFree'
这些错误是什么东西呢,是说程序在链接的时候找不到上面的这些符号,像'cudaMalloc'、‘cudaFree'等,这些符号对应的函数我没有定义,那么他们来自哪里呢。对,就是这些函数是有系统提供的,是存在于系统的库文件中-L$(CUDA_DIR)/lib64 -lcudart就是让编译器去链接(CUDA_DIR)/lib64中的libcudart.so文件,里面有它想要的东西的。
libVectorAddCu.a是我自己生成的一个库文件,这个库文件好像必须要放在最后面才行
[cpp]
view plain
copy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
<span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a
$(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>
这两行的代码中的内容是有一定的顺序的,由于我对linux不是太了解,目前对这种顺序还不是太了解,希望知道的能给我留言,谢谢!
相关文章推荐
- Python网络编程(Socket)
- 阿朱的好文章
- 关于终端和控制台的概念
- 15个热门的编程趋势及15个逐步走向衰落的编程方向
- select, poll和epoll的区别
- 输油管道问题
- 智能指针auto_ptr类模板的使用
- UIview需要知道的一些事情:setNeedsDisplay、setNeedsLayout
- 建造者模式
- 关于对客户浏览器兼容性的引导
- UIview需要知道的一些事情:setNeedsDisplay、setNeedsLayout
- 史上最精简,最强大的JavaScript遮罩层效果,支持ie firefox jQuery遮罩层
- SQL 注入
- VS2012发布网站
- QT 安装完成后,调试 ,IOS模拟器出错
- C++:float 转型到 std::string
- 简单道理
- 应用散列表和外拉链表统计文本中单词个数
- jsp学习笔记
- Jetty学习【三】 Handler