pytorch的c++/cuda扩展,CUDA编程

news/2024/4/25 15:46:39/文章来源:https://blog.csdn.net/xx_xjm/article/details/130367955

当我开始动笔的时候,已经开始头疼了,因为我很清晰的意识到,所要整理的知识点真的很多~,多到我无法依靠记忆来长存,所以只能把它们写下来~~~。

ok,让我们开始吧。

主要分两部分来讲,一是cuda编程,二是pytorch的c++/cuda扩展;

先说cuda编程

 一:什么是cuda编程

我们知道C++,C这类的编程语言是为了让计算机执行我们的指令,确切一点是让计算机的cpu执行我们的执行,现在cuda编程则是要让显卡中的计算核心执行我们的指令;

所以,cuda编程其实就是编写显卡中计算核心执行指令。为了区别于.cpp,.c这样的文件,我们取.cu后缀来指明当前的代码文件是给显卡用的;

二:.cu文件的构成

(这部分基于个人理解,没有严格证明,仅方便理解,如有不正之处,欢迎指正)

因为显卡上面大量的都是计算单元,只有少量的控制单元,我们是无法像C++,C直接指挥CPU那样直接把代码编译成显卡能识别的东西,简单点说,就是,我们不能像C++,C这样写完代码后,编译链接完CPU就可以直接运行了。为此,我们是需要通过CPU转达我们的指令给到显卡;所以说到底,.cu文件也是写给CPU的,只不过你告诉了CPU要怎么去指挥显卡工作,从这个角度来看,其实.cu文件和.cpp等文件一样,都是C++的代码;

因此,.cu文件中包含两部分的内容,一是告诉CPU怎么传递信息和指挥显卡工作,二是指明具体显卡上面应该怎么操作;

三:.cu文件的编译

上面说了,.cu文件包含两部分内容,一部分是写给CPU的,一部分是写给GPU的,所以编译的时候自然需要先区分开这两部分代码,分别编译,然后再合起来一起链接,形成相应的可调用的库(动态库或者静态库),.cu文件的编译需要用到nvcc,这部分详细的可以参考:

(3条消息) CUDA学习(一)-NVCC的编译过程_nvcc编译_Scott f的博客-CSDN博客

nvcc编译网上有很多教程,这一片看不懂的话,大家也可以自查

 四:.cu文件的编写

这部分内容主要参考《CUDA编程基础与实践》---清华大学出版社,讲的非常好,强推!

我们前面说了,.cu文件中需要实现cpu对显卡(也就是设备端,后面若无特指,均以设备代替gpu)进行调用,这一步是通过核函数来实现的;

一个典型的,简单的cuda程序结构如下:

注:本文所用代码实例无特殊说明均来自《CUDA编程基础与实践》

int main(void)
{主机代码核函数调用主机代码return 0;
}

1:什么是核函数?

我们上面说了,.cu本质上还是写给CPU的,所以核函数其实也是C++函数的一种,只不过有一个特殊的限定词"__global__",用以指明“这个C++函数,是用来调用显卡的!”。

一个简单的核函数如下,其中__global__和void的顺序可以互换,另外,核函数的返回值必须是空类型:

__global__ void hello_world()
{printf("hello world")
}

 2:核函数的调用

核函数虽然是C++函数的一种,但是它的调用有一点区别,举例如下:

#include <stdio.h>
#include <stdlib.h>__global__ void hello_world()
{printf("hello world");
}int main(void)
{hello_world<<<1, 1>>>();cudaDeviceSynchronize();return 0;
}

可以看到,我们这里调用核函数的时候有一个<<<1,1>>>,这其实是指明核函数中的线程数目和排列情况,具体的可以自行百度或者参考书籍,简单理解就是分配多少计算资源来进行运算;

五:主机和设备之间的数据传输

在第四节中,我们简单用主机通过核函数来指挥设备进行工作,但没有进行数据的传输,在这一节,我们更细致的讲解主机和设备间的工作流程;

首先,我们写一个单纯的cpp代码,用于计算两个相同长度的一维数组对应元素之和,代码如下:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>const double EPSILON = 1.0e-15;
const double a = 1.23;
const double b = 2.34;
const double c = 3.57;void add(const double *x, const double *y, double *z, const int N);
void check(const double *z, const int N);int main(void){const int N = 100000000;const int M = sizeof(double) * N;double *x = (double *) malloc(M);double *y = (double *) malloc(M);double *z = (double *) malloc(M);for (int n = 0; n < N; ++n){x[n] = a;y[n] = b;}add(x,y,z,N);check(z, N);free(x);free(y);free(z);return 0;
}void add(const double *x, const double *y, double *z, const int N)
{for (int n=0; n <N; ++n){z[n] = x[n] +y[n];}
}void check(const double *z, const int N)
{bool has_error = false;for (int n = 0; n<N; ++n){if (fabs(z[n] - c)> EPSILON){has_error = true;}}printf("%s\n", has_error ? "has errors" : "no errors");
}

 double *x = (double *) malloc(M)这里;

malloc返回的是一个void类型的指针,也即任意类型的指针,这个指针指向了分配的内存,所以*)malloc(sizeof(double) * 5)就是取出了malloc返回的指针中存储的内存的地址,把这个地址强制转化为double类型,并赋值给p指针,因此,此时的p指针指向的就是所分配的地址了。

接下来,我们将add函数在设备端执行,在这种情况下,一个典型的CUDA程序基本框架为:

头文件包含
常量定义/宏定义
C++自定义函数和CUDA核函数声明(原型)int main(void)
{分配主机和设备内存;初始化主机中的数据;将某些数据从主机复制到设备;调用核函数在设备中进行计算;将某些数据从设备复制到主机;释放主机与设备内存
}C++自定义函数和CUDA核函数的定义(实现)

未完待续~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_103474.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零开始写ChatGLM大模型的微调代码

cursor 的下载及安装&#xff08;免费版每月100次&#xff0c;升级pro 20刀/月&#xff09; cursor是一款与openai合作的&#xff0c;使用gpt-4的一款编程工具&#xff0c;它可以让你通过gpt-4进行辅助编程&#xff0c;以此提高效率。 下载地址&#xff1a;https://www.curso…

USART串口协议和USART串口外设(USART串口发送串口发送和接收)

1、通信接口 • 通信的目的&#xff1a;将一个设备的数据传送到另一个设备&#xff0c;扩展硬件系统 • 通信协议&#xff1a;制定通信的规则&#xff0c;通信双方按照协议规则进行数据收发 异步&#xff1a;需要双方约定一个频率 2、 硬件电路 • 简单双向串口通信有两根通信…

【Unity-ML】Unity机器学习(一)

安装环境&#xff1a;Windows10 Anaconda3(64-bit)&#xff0c;网上很多教程&#xff0c;例如这个anaconda下载及安装(保姆级教程) - 知乎anaconda包管理器和环境管理器&#xff0c;强烈建议食用 1.下载官网下载太慢可选用镜像下载 官网下载&#xff1a; Anaconda | Individua…

〖ChatGPT实践指南 - 零基础扫盲篇④〗- OpenAI API 相关介绍、提示-Prompt 与 完成-Completion

文章目录 ⭐ OpenAI API介绍⭐ 提示-Prompt 与 完成-Completion 介绍 这一章节将为各位小伙伴介绍一下 OpenAI 的 API 相关内容&#xff0c;以及在 ChatGPT 中两个经常被用来比较的名词&#xff1a;“提示-prompt” 与 “完成-completion”。 ⭐ OpenAI API介绍 OpenAI API 概…

JavaScript常用方法整理

文章目录 前言1.栈方法&#xff1a;push()、pop()2.队列方法&#xff1a;unshift()、shift()3.indexof()、lastIndexOf()、includes()4.操作方法&#xff1a;concat()、slice()、splice()5.Array.isArray()6.排序方法:sort()、reverse()7.转换方法&#xff1a;toString()、join…

【Winform学习笔记(二)】TextBox文本框实现按回车键触发Button事件

TextBox文本框实现按回车键触发Button事件 前言正文1、实现方法2、具体代码3、实现效果 前言 在本文中主要介绍 如何基于 Winform 框架实现 TextBox 文本框实现按回车键触发 Button 事件&#xff0c;该功能可实现在文本框中输入密码后不需要按登录或确定按钮&#xff0c;直接回…

vue页面内嵌iframe使用postMessage进行数据交互(postMessage跨域通信)

什么是postMessage postMessage是html5引入的API,它允许来自不同源的脚本采用异步方式进行有效的通信,可以实现跨文本文档,多窗口,跨域消息传递.多用于窗口间数据通信,这也使它成为跨域通信的一种有效的解决方案. vue父页面&#xff08;嵌入iframe的页面&#xff09; 在vue中…

webAPI学习笔记2(DOM事件高级)

1. 注册事件&#xff08;绑定事件&#xff09; 1.1 注册事件概述 给元素添加事件&#xff0c;称为注册事件或者绑定事件。 注册事件有两种方式&#xff1a;传统方式和方法监听注册方式 传统注册方式 利用 on 开头的事件 onclick <button οnclick“alert(hi~)”><…

如何构建可靠的台账数据——详解台账管理系统的使用方法

随着数字化的发展&#xff0c;越来越多的企业开始采用电子台账管理&#xff0c;实现了对各项业务数据的及时准确保存和管理。而在台账管理应用中&#xff0c;发票管理、工单管理和库房台账是三大重要方面。下面我将详细介绍一下台账管理系统。 一、发票管理 1.收票台账报表 …

【Python小技巧】使用Gradio构建基于ChatGPT的 Web 应用(附源码)

文章目录 前言一、Gradio是什么&#xff1f;二、使用Gradio构建基于ChatGPT的 Web 应用1. 安装gradio库2. 安装openai库&#xff08;ChatGPT的python库&#xff09;3. Web 应用示例&#xff08;源代码&#xff09; 总结 前言 随着人工智能的不断发展&#xff0c;各种智能算法越…

UE4架构初识(五)

UE4仿真引擎学习 一、架构基础 1. GameInstance UE提供的方案是一以贯之的&#xff0c;为我们提供了一个GameInstance类。为了受益于UObject的反射创建能力&#xff0c;直接继承于UObject&#xff0c;这样就可以依据一个Class直接动态创建出来具体的GameInstance子类。 UGam…

【Golang项目实战】手把手教你写一个备忘录程序|附源码——建议收藏

博主简介&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;数据结构、Go&#xff0c;Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: Go语言核心编程近期目标&#xff1a;写好专栏的每一篇文章 前几天瑶瑶子…

blender 制作城市建筑模型

我不是很会用blender 但是他可以直接制作一篇区域的建筑模型 BlenderGIS插件 城市建筑3D模型自动生成 教程_Zhichao_97的博客-CSDN博客 学习了两种 一种是通过geo.json自己加了一堆mesh 或者geometry 自己用three 做的模型 另一种是用blender 做一个整个的模型直接导入进去 …

降低风险和最大化成功:如何解决项目管理中的成本差异

作为项目经理&#xff0c;你知道让项目按计划进行并按预算进行对于项目管理的成功至关重要。你可以使用的关键工具之一是成本差异分析。但成本差异到底是什么&#xff0c;如何利用它来发挥优势呢&#xff1f; 定义成本差异 成本差异是项目实际成本与预算或计划成本之间的差异…

企业本地文档如何实现规范在线管理?

随着企业数字化生产方式的不断推进&#xff0c;网络办公和在线协作越来越普遍&#xff0c;企业内部可能出现大量的文件和文档&#xff0c;这些文档多存在于不同的设备和存储介质上&#xff0c;这给企业的信息管理带来了一定程度的困难。为了提高企业的知识管理效率&#xff0c;…

【大数据之Hadoop】二十、Yarn基础框架及工作机制

1、Yarn基础框架 Yarn是一个资源调度平台&#xff0c;负责为运算程序提供服务器运算资源&#xff0c;相当于一个分布式的操作系统平台&#xff0c;而MapReduce等运算程序则相当于运行于操作系统之上的应用程序。 YARN主要由ResourceManager、NodeManager、ApplicationMaster和…

修炼汇编语言第二章:内存地址空间(概述)

目录 前言 一、主板和接口卡 二、存储器各类芯片 三&#xff1a;内存地址空间 总结 前言 什么是内存地址空间呢&#xff1f;如果地址线为10&#xff0c;那么可以寻址1024个地址空间&#xff0c;这1024个地址空间就构成这个CPU的内存地址空间&#xff0c;下面本文将会介绍…

Python如何连接Mysql及基本操作

1.什么要做python连接mysql&#xff0c;一般是解决什么问题的 做自动化测试时候&#xff0c;注册了一个新用户&#xff0c;产生了多余的数据&#xff0c;下次同一个账号就无法注册了&#xff0c;这种情况怎么办呢&#xff1f;自动化测试都有数据准备和数据清理的操作&#xff…

代码在洛谷上跑得慢怎么办?

前言 你有没有试过以下几种情况&#xff1a; 代码在别的OJ上能过&#xff0c;在洛谷上就T了你的代码和同学的几乎相同&#xff0c;但他的AC了&#xff0c;你的却TLE了 遇到这些情况&#xff0c;你可能要花上一个多小时才能解决&#xff0c;甚至难以解决&#xff0c;将问题一…

C. Magic Ship(二分 + 前缀和)

Problem - C - Codeforces 你是一艘船的船长。最初你站在一个点(x1&#xff0c;y1)上&#xff08;很明显&#xff0c;海上的所有位置都可以用笛卡尔平面描述&#xff09;&#xff0c;你想要前往一个点(x2&#xff0c;y2)。 你知道天气预报——长度为n的字符串s&#xff0c;仅由…