【动手开发深度学习框架日记】GPU内存管理API

在【Tensor基本数据结构】一文中,Tensor类会将数据分为在CPU端计算还是在GPU端计算。对应的就是numpy或Quark子数据结构。Tensor实现了GPU内存数据到CPU数据、CPU到GPU的迁移,通过调用cpu()gpu()完成。数据的 Host to Device 以及 Device to Host 行为由CUDA提供,因此可以通过封装CUDA API供Python调用。本文主要解释CUDA的底层实现以及Python端的调用。

一、CUDA加速计算编程模型

若要使用CUDA来对矩阵运算进行GPU加速,就需要遵循一定的编程模型(建议先阅读 CUDA By Example,很好的入门CUDA编程书籍)。

首先我们创建了一个数据结构,数据结构中包含数据、形状、维度等等信息。CUDA计算使用的是GPU(Host)端的数据,那么我们怎么把创建好在CPU的数据放到GPU中呢?CUDA提供了一个简便的API,cudaMemcpy()。该API允许数据从Host复制到Device,同时也允许Device的数据复制到Host,需要传入数据的指针,数据大小还有你的选择(从cpu到gpu还是gpu到cpu)。有了这个工具呢,我们还需要一个可以在GPU内存上申请空间的函数,也就是cudaMalloc(),该函数需要传入数据指针和数据的大小。那么,大小如何得到?这时候我们就需要根据数据结构的shape、dim等参数进行计算。最后一个问题,如何释放GPU内存的空间?使用cudaFree()可以解决这个问题。

总结来说,想要利用CUDA实现GPU加速计算,要有一下几个步骤:

1. 创建数据,填补相关的数据信息(CPU端)
2. 创建GPU数据内存指针
3. cudaMalloc()分配GPU内存,需要计算数据的size
4. cudaMemcpy()将CPU的数据复制到GPU对应内存
5. 实现CUDA kernel函数,传入必要参数计算
6. cudaMemcpy()将计算结果从GPU复制回CPU
7. 完成计算后释放内存

二、内存管理API封装

上述的步骤其实是可以直接写在C++后端的算子API里的,但是为了Tensor管理的模块化和灵活性,打算将这些功能分散开,在创建GPU数据时完成对应的操作,之后再调用算子就是直接调用GPU内存进行计算了。

首先创建一个专门定义内存操作的.cu文件,我把它叫 MemSchedulor.cu。

为了方便筛查错误,我们需要定义一个宏,每当使用CUDA API时,在外面裹一层就好了。

#define CUDA_CHECK(func)                                                        \
  {                                                                            \
    cudaError_t e = (func);                                                    \
    assert((e == cudaSuccess) || (e == cudaErrorCudartUnloading));             \
  }

然后我们先封装内存分配函数,这里实现了CPU的封装和GPU的封装。

extern "C" float *AllocateDeviceData(int size){
	float *dev_data;
	CUDA_CHECK(cudaMalloc((void **)&dev_data, size));
	return dev_data;
}

extern "C" float *AllocateHostData(int size){
	float *host_data = (float *)malloc(size);
	return host_data;
}

函数内部实现都非常简单,就是创建一个指针变量,分配数据然后返回,在Python端接收即可。需要注意这里输入参数size代表的是字节数,那我们就需要实现一个自动根据shape和dim计算size的函数。

extern "C" inline int getSize(int dim, int *shape){
	// float32 by default, 4 bytes
	int size = 1;
	for(int i=0; i < dim; i++){
		size = size * shape[i];
		}
	return size * 4;
}

整个框架的数据类型是基于float32的,所以这里要乘4作为数据所占内存的最终大小。

释放内存的封装也很简单。

extern "C" void FreeDeviceData(float *data){
	CUDA_CHECK(cudaFree(data));
}

extern "C" void FreeHostData(float *data){
	free(data);
}

最后就是要实现数据的复制功能了,这里统一实现一个API,根据输入的参数来判定移动的方向。

extern "C" void CopyDataFromTo(float *from_data, float *to_data, Device from, Device to, int size){
	if(from == CPU && to == GPU){
		CUDA_CHECK(cudaMemcpy(to_data, from_data, size, cudaMemcpyHostToDevice));
	}
	else if(from == GPU && to == CPU){
		float *dev_data = (float *)from_data;
		float *host_data = (float *)to_data;

		CUDA_CHECK(cudaMemcpy(host_data, dev_data, size, cudaMemcpyDeviceToHost));
	}
}

以上就是MemSchedulor.cu所有的API封装,通过编译命令编译成动态链接库,使用ctypes导入库后就可以调用了。目前实现数据的分配、复制以及计算是没有问题的,但不代表这是最终版本,还需要以后开发完全后确定。

这就是内存管理的全部内容啦,之后还会进一步更新后端算子的封装以及使用cuDNN实现卷积的前向计算和求梯度运算(因为实现起来有些问题就直接调用cuDNN库了哈哈)。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了在GPU上搭建动手深度学习pytorch环境,你需要按照以下步骤进行操作。 首先,你需要安装Anaconda来管理你的Python环境。你可以从官方网站 https://www.anaconda.com/ 下载适用于你操作系统的Anaconda安装程序。安装完成后,你可以使用conda命令创建一个新的环境。 接下来,你需要安装CUDA。CUDA是用于支持GPU计算的NVIDIA的并行计算平台和API模型。你可以从NVIDIA的官方网站下载适用于你的显卡型号的CUDA安装程序进行安装。 然后,你需要安装CUDNN。CUDNN是一个针对深度神经网络加速的GPU库。你可以从NVIDIA的开发者网站下载CUDNN并按照安装说明进行安装。 接下来,你可以使用conda命令来安装pytorch。你可以复制以下命令,在新建的环境中输入: ``` conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch ``` 安装完成后,你可以在命令行中输入python进入Python解释器环境,并导入torch模块来测试pytorch的安装。你可以使用以下代码进行测试: ```python import torch from __future__ import print_function x = torch.rand(5, 3) print(x) print(torch.cuda.is_available()) # 测试CUDA是否可用 ``` 这样,你就成功搭建了动手深度学习pytorch环境,并且可以在GPU上进行深度学习任务了。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [01 动手学习深度学习-配置环境pytorch](https://blog.csdn.net/qq_44653420/article/details/123883400)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值