CUDA数组(CUDA Array)

CUDA传递结构体数组 在把CPU的数组结构体传递到GPU内存中需要好多问题,找不到太多的资料,最后只能靠自己慢慢摸索 CPU上的代码我们一般称为 Host代码 GPU上面的一般叫Device 代码,之所以这样区分是由于GPU的内存和CPU的内存是相互独立的,它们的数据没法直接相互调用,只能通过cuda的一些方法进行操作,最常用的是 cudaMalloc和cudaMemcpy cudaMalloc是用来在GPU上申请 阅读详情
AI摘要

本文详细介绍了CUDAArray的使用方法,包括一维、二维和三维CUDAArray的申请、赋值、复制和释放过程。同时,还讲解了如何绑定和解绑定CUDAArray,以及如何使用纹理内存进行取值。

CUDA数组(CUDA Array)

参考:
https://blog.youkuaiyun.com/hhko12322/article/details/12004329
http://blog.sciencenet.cn/blog-398465-342089.html

引言

CUDA Array is used for the Texture memory.
本篇谈一下不同维数的CUDA数组的申请,赋值,复制和释放。

CUDA array 在 cuda 中是一个特殊的类型,叫做 cudaArray,在 CUDA 中,他是专门给 texture 用的一种数组;通过cudaMallocArray()、cudaFreeArray()、cudaMemcpyToArray()等函数对其进行管理。此外,由于 cudaArray 本身不是template 的型別,所以在通过cudaMallocArray()来申请CUDA Array时,要通过cudaChannelFormatDesc这个特别的方式,来定义CUDA Array的类型。

申请CUDA Array

如:申请一个一维CUDA Array,类型是float 大小是width×height

cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
cudaArray* cuArray;
cudaMallocArray(&cuArray, &channelDesc, width, height);

cudaChannelFormatDesc 是一个用来描述 fetch 一个 texture 時,返回值的类型;
定义如下:

template<class T> struct cudaChannelFormatDesc cudaCreateChannelDesc< T>();

复制CUDA Array

而CUDA Array 需要主机端的线性内存赋值(copy):

cudaError_t cudaMemcpyToArray(struct cudaArray* dstArray,
                              size_t dstX, size_t dstY,
                              const void* src, size_t count,
                              enum cudaMemcpyKind kind);

cudaMemcpyKind是用来指定赋值的方向,有cudaMemcpyHostToHost、cudaMemcpyHostToDevice、cudaMemcpyDeviceToHost、cudaMemcpyDeviceToDevice四种值。

绑定CUDA Array

CUDA Array是要被Texture使用的,需要绑定到Texture cudaBindTextureToArray()

template<class T, int dim, enum cudaTextureReadMode readMode>
cudaError_t cudaBindTextureToArray(
               const struct texture<T, dim, readMode>& texRef,
               const struct cudaArray* cuArray);

解绑定:cudaUnbindTexture()

取值

而在存取上,和 linear memory 的 texture 時的 tex1Dfetch() 不同,是要使用 tex1D()、tex2D() 这两种,分別是用在 1D 和 2D 的 texture。其形式分別为:

template<class Type, enum cudaTextureReadMode readMode>
Type tex1D(texture<Type, 1, readMode> texRef, float x);

template<class Type, enum cudaTextureReadMode readMode>
Type tex2D(texture<Type, 2, readMode> texRef, float x, float y);

三维CUDA Array

上例描述了CUDA Array使用的全过程,其中CUDA Array是2维的,下面介绍3维的CUDA Array,为什么不介绍一维的CUDA Array?因为Texture本身对局部内存访问有优化,并且纹理内存一般都是基于二维的(图片都是二维的)。

在当前的CUDA版本中,3D的线性内存是无法直接绑定到texture memory,一维的可以,因此,需要将数据首先放进一个3D的CUDA array,然后将3D CUDA array绑定到texture memory上,访问数组元素时,通过取纹理的函数tex3D(tex,x,y,z)可以返回坐标为(x,y,z)的元素。

  1. 创建CUDA 3D array
    在之前的CUDA版本中,extent.width与height,depth不同,其计数单位为bytes,所以在旧版本中必须使用array_width*sizeof(float),最新的3.1竟然悄悄的修改了。可以CUDA的文档一直是错误的,文档中记载width,height,depth均是in bytes,实际上赋值时使用元素个数即可。如果不直接赋值,还可以调用函数make_cudaExtent(extent,width,height,depth), 原理类似。

    cudaArray *d_u
    cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc< float>();
    cudaExtent extent;
    extent.width=array_width;
    extent.height=array_height;
    extent.depth=array_depth;
    cudaMalloc3DArray(&d_u,&channelDesc,extent);

  2. 复制数据至3D array
    首先解释一下pitched pointer的工具原理,如果访问数组元素u[x][y][z],通过pitched pointer访问则是u_p[x+y*pitch+ z*pitch*height ]。 显然,这里pitch=width,因此当创建pitched pointer时我们需要将width和height作为参数传递给函数make_cudaPitchedPtr()。在这里尤其要注意的是,pitched pointer指向的array与传统的C语言数组的存储方式不同,C语言访问元素u[x][y][z]是通过u[y*width*depth+x*depth+z]。因此为了正确读取所需元素,我建议逆序建立pitched pointer:
    copyParams.srcPtr = make_cudaPitchedPtr((void*)u, array_depth*sizeof(float), array_depth, array_height);
    此时相当于数组u[x][y][z]被转置,在CUDA3D array中对应元素为u[z][y][x],CUDA文档与指南中并未提及这一点区别,这个问题当时也困扰我很久,费尽周折才搞清楚,希望以后的SDK sample能覆盖这个注意点。

  3. 绑定3D array至texture memory

    normalized 设置是否对纹理坐标是否进行归一化。如果normalized是一个非零值,那么就会使用归一化到[0,1)的坐标进行寻址,否则对尺寸为width, height, depth的纹理使用坐标[0,width-1], [0,height-1], [0,depth-1]寻址。例如,一个尺寸为64×32的纹理可以通过x维度范围为[0,63],y维度范围[0,31]的坐标寻址。如果采用归一化方式对尺寸为64×32的纹理进行寻址,在x和y维度上的坐标就都是[0.0,1.0)。这样就可以保证纹理的坐标与纹理的尺寸无关。
    filterMode用于设置纹理的滤波模式,即如何根据坐标计算返回的纹理值。滤波模式可以是cudaFilterModePoint或者cudaFilterModeLinear。滤波模式为CudaFilterModePoint时,返回值是与坐标最接近的像元的值。CudaFilterModeLinear模式只能对返回值为浮点型的纹理使用,启用这一种模式时将拾取纹理坐标周围的像元,然后根据坐标与这些像元之间的距离进行插值计算。对一维纹理可以使用线性滤波,对二维纹理可以使用双线性滤波。返回值会是对最接近纹理坐标的两个像元(对一维纹理),四个像元(对二维纹理)或者八个像元(对三维纹理)进行插值后得到的值。

    texture< float,3,cudaReadModeElementType> tex_u;
    tex_u.filterMode = cudaFilterModePoint;
    tex_u.normalized = false;
    tex_u.channelDesc = channelDesc;
    if (cudaBindTextureToArray(tex_u, d_u, channelDesc) != (unsigned int) CUDA_SUCCESS) {
    printf(“[ERROR] Could not bind texture un”);
    return;
    }

接下来会介绍,三通道的RGB影像怎么处理,以及Texture Layer怎么使用。

CUDA加速——基于规约思想的数组元素求和 基于CUDA的数组规约求和 阅读详情

相关推荐

CUDA常见函数(二):纹理参考管理

主要是在图像处理时用到的一些函数,在这里汇总一下。

小P的博客 2002

Part.3 CUDA Array

Part.3 CUDA Array 在 CUDA Texture 文章的第一篇大概講了一下 texture 在 CUDA 裡的基本概念,而第二篇則是講了 linear memory 的 texture,接下來,自然就是 CUDA Array 的 texture 了~ CUDA Array CUDA array 在 cuda 中是一個特殊的資料型別,叫做 cuda...

weixin_33755847的博客 285

CUDA编程中线程分配的数组在register中还是local memory中?

问题很简单,当我们在编写KERNEL的时候,分配了一个数组,那么这段数组空间是在register中,还是local memory中呢?通过几个测试,我们可以来看一下: 首先一些定义: #define BLOCK_SIZE 32 #define GRID_SIZE 1 #define ARRAY_SIZE 32 第一个kernel测试,静态索引static indexing,代码: __

1733

CUDA学习—cudaMallocArray()

名称: cudaMemcpyToArray – 在主机和设备间复制数据概要: cudaError_t cudaMemcpyToArray(struct cudaArray* dstArray,size_t dstX,size_t dstY,const void* src,size_t count,enum cudaMemcpyKind kind) cudaError_t cudaMemcpyT

渐行渐远 1万+

Ubuntu22.04下3分钟搞定GitHub加速:SwitchHosts+小鱼工具保姆级配置指南

本文提供Ubuntu22.04下快速解决GitHub下载超时问题的保姆级教程,通过SwitchHosts图形化工具和小鱼一键换源工具实现高效加速。详细步骤包括环境准备、工具安装配置及验证方法,帮助开发者轻松优化GitHub访问速度,提升工作效率。

weixin_29258297的博客 564

SMPTE ST 2110 概论(三)

SMPTE ST 2110 概论(三)ST 2110-30:未压缩的PCM音频流ST 2110-31:非PCM音频传输ST 2110-40:辅助数据传输结语 ST 2110-30:未压缩的PCM音频流 鉴于音频系统是广播系统中最复杂,也是最重要的一套系统,我们先来回顾一下广电音频系统的历史。 最老式的音频都是基于模拟信号的,具有有限的动态范围,并且用连续的电压变化来描述音频。再后来就基于数字信号(...

Cidd0422的博客 1万+

Numba CUDA 内存管理完全指南:to_device 与各类设备数组分配 API 深度解析

Numba 的 CUDA 支持(`numba.cuda`)为开发者提供了一套与 NumPy 风格一致的内存管理 API,用于在主机与 GPU 之间分配、传输和共享数据。本指南以官方参考文档 [docs/source/cuda-reference/memory.rst](https://link.gitcode.com/i/95169e768b8c921debca3f9073e32bf5) 为骨架,

gitblog_00177的博客 869

Python爬虫实战:构建药监局药品批准信息本地查询系统

在医药信息化时代,药品批准信息的快速查询对于医药从业者、研究人员和普通消费者都具有重要意义。国家药品监督管理局(NMPA)提供了官方的药品查询系统,但有时我们需要建立本地数据库以便批量分析或离线查询。本文将详细介绍如何使用Python爬虫技术,结合最新的异步爬虫框架和技术栈,构建一个完整的药监局药品信息本地查询系统。本系统将实现以下功能:自动化爬取药监局官网的药品批准信息数据清洗和结构化存储建立本地查询接口数据定期更新机制pythonimport os"""药品类型枚举"""

2201_76125261的博客 727

array_fire学习 各个module总结

array_fire不是开源,但是是免费的库可以使用,总结起来,有点遗憾的是,大部分的数值计算的相关算法都没有,包括迭代求解和拟合等相关内容,其它差不多都有吧,自己记录一下,以备后日使用 主要包含的内容: 机器视觉算法,array生成,array内部函数,图像处理,输入输出,线性代数,常规数学计算,信号处理,统计分析,对于CUDA的相应操作,具体的内容可以通过下面链接查看 http://ar...

zhouzhouasishuijiao的博客 499

代码的自由之旅:用AI写出无版权烦恼的Verilog

他们还基于这个数据集,训练了一个名叫“FreeV”的AI模型,不仅能写出好用的Verilog代码,还把版权侵权的风险降到了仅3%。为了让AI安全地写Verilog,研究团队提出了三个“法宝”:一个检测AI是否会生成侵权代码的测试方法、一个干净的Verilog数据集FreeSet,还有一个基于FreeSet训练的AI模型FreeV。AI的记忆力超强,能记住训练时见过的代码。测试发现,一些用Verilog数据训练过的AI,比如VeriGen,生成侵权代码的概率从9%涨到了15%,说明它们可能学了不该学的代码。

步子哥的博客 1808

C#上位机案例:西门子S7协议通信+实时曲线显示(WinForm+ZedGraph)

创建/// PLC数据模型(对应DB1块)/// 采集时间(用于曲线的X轴)set;/// 温度值(℃)set;/// 压力值(MPa)set;/// PLC通信状态set;西门子S7协议通信和实时曲线显示,也是工控现场最常见的场景之一。整个开发过程的关键不在于“写出代码”,而在于“写出符合工控场景的稳定代码”——比如解耦通信逻辑与界面逻辑、处理跨线程问题、限制数据点数量、释放资源等。新手在学习时,建议先跟着步骤搭建好环境,跑通基础功能,再逐步尝试进阶优化。需要注意的是,工控上位机的核心是。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1342

【CUDA】【pycuda】第一个案例 翻倍数组

用于确定线程块处理的数据的位置或标识符,从而使每个线程块可以处理不同的数据部分。它表示当前执行的线程块(block)在其所属的网格(grid)中的索引值。在 CUDA 中,线程以线程块的形式组织,并且线程块可以被划分为更小的线程块,形成线程块的层次结构。for循环允许比线程多的数据元素加倍,但如果可以保证有足够数量的线程,则效率不高。在循环中,首先将指针 a->ptr 赋值给临时变量 a_ptr,然后通过索引 idx 访问数组元素,将其乘以 2,实现双倍操作。double_array 的内核函数,它使用。

prinTao的博客 317

IPGUARD客户端与应用程序冲突

客户端与应用程序冲突 症状 安装客户端之后,客户端的某些程序无法运行或使用过程中出现异常,卸载客户端后恢复正常。 原因分析 可能是客户端的某些功能与应用程序发生冲突导致。 解决方法 当出现这样的情况时,可以按照以下步骤确认。 步骤1:屏蔽主动注入 在客户端配置策略中,增加配置策略hookapi_disinj,值为1;待策略同步到客户端后,重启客户端确认问题是否解决。如果解决,则转到...

IP-Guard专栏 1410

numpy array / pytorch tensor 数据类型转换

array str 转 int timestamp = delta_pose[i, 0].astype(int) numpy 转 tensor a = numpy.array([1, 2, 3]) t = torch.from_numpy(a) print(t) #tensor([ 1, 2, 3])

weixin_37804469的博客 6859

与OpenClaw同类性质的AI智能体框架/工具汇总(小白友好)

OpenClaw的核心定位是「开源、本地优先、可执行真实任务的AI代理」,核心价值是让AI从“聊天”落地到“动手干活”(操控电脑/服务器、处理办公/系统任务)。结合这一核心,以下是同类性质的工具/框架,按「小白易上手程度」排序,每个产品重点说明和OpenClaw的异同、核心优势及适配场景,方便小白快速区分选择。

hy行者勇哥的博客 2107

TensorRT的安装:一步一步教会你如何安装TensorRT

TensorRT(Tensor Runtime)是由NVIDIA开发的一个用于深度学习推理(inference)优化的库,它可以在NVIDIA的GPU上加速神经网络模型的推理过程,从而提高模型的性能和效率。安装完成后,需要将CUDA的安装路径添加到系统环境变量中,以便系统能够找到CUDA的库文件。根据你安装的CUDA版本,将CUDNN的库文件复制到CUDA的安装目录中。要使用TensorRT,首先需要安装NVIDIA的CUDA和cuDNN库,并根据NVIDIA官方文档安装TensorRT。

Science prince的博客 2372

解决:TypeError: can‘t convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor

正如Numpy中所有的操作都是针对Numpy特有的变量类型Array,在Pytorch中几乎所有的操作都是针对Pytorch特有的变量类型Tensor。它们之间最大的不同是:Tensor既可以存储在GPU(或者’cuda’设备)上,也可以存储在cpu设备上(准确来讲是cpu的内存上);Tensor.cpu()的作用是将cuda上的Tensor传回到cpu上。首先,tensor,中文叫做张量,它是Pytorch中最基本的数据类型,同时也是最最最重要的数据类型,基本上后面你无时不刻都在和它打交道。

qq_51007474的博客 1988

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Numba 的 CUDA Array Interface(Version 3)完全指南:规范、同步语义与互操作实践

CUDA Array Interface(简称 CAI)是 Numba 为不同 CUDA 数组类对象实现之间互操作而设计的 Python 层接口规范,其思路借鉴自 NumPy Array Interface。本文以 Numba 官方文档 [docs/source/cuda/cuda_array_interface.rst](https://link.gitcode.com/i/32a2e18ad3

gitblog_00565的博客 139

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Pycharm在Debug时Tensor张量显示不全问题

Pycharm在Debug模式下Tensor显示不全问题

qq_47703137的博客 5780

JAX CHANGELOG 深度解读:从 0.4.31 版本回看 jax 与 jaxlib 的演进脉络

本文以仓库根目录的 [CHANGELOG.md](https://link.gitcode.com/i/7b5ccfb3277b0d1bad0b71a5f62b23c3) 为唯一主线,系统梳理 JAX 从 0.1.58 到 0.4.31 的完整发布历史,覆盖 Python/NumPy 版本策略、`jax.Array` 统一数组模型、jit/pjit 合并、export 序列化、CUDA 插件化安装

gitblog_00303的博客 447

【CUDA并行编程之七】数组元素之和

现在需要求得一个数组的所有元素之和,之前感觉似乎不太可能,因为每个线程只处理一个元素,无法将所有元素联系起来,但是最近学习了一段代码可以实现,同时也对shared memory有了进一步的理解。 一、C++串行实现 串行实现的方法非常之简单,只要将所有元素依次相加就能够得到相应的结果,实际上我们注重的不是结果,而是运行的效率。那么代码如下: array_sum.cc:

Marshall的专栏 974

darknet源码解析:cuda_push_array和cuda_make_array

更多darknet源代码学习笔记,参看:darknet源码学习:预测分类函数float *network_predict_gpu(network net, float *input) 将主机host的数据拷贝到GPU设备x_gpu中 void cuda_push_array(float *x_gpu, float *x, size_t n) { size_t size = sizeo...

haimianjie2012的专栏 975

理解CUDA[2]

BLOCK和GRID 许多的线程组织在一个BLOCK里,threadIdx变量指示该线程是哪一个线程。而BLOCK有一个限制:一个BLOCK最多能含有1024个线程。怎么办呢,我们可以使用多个BLOCK,多个BLOCK怎么组织呢?使用GRID!GRID和BLOCK的关系就和BLOCK和THREAD的关系类似。BLOCK和GRID可以是int类型,也可以是dim3类型>> 符号指定使用多少

继哲的专栏 665

Apache Arrow C++ API 参考指南:从内存管理到数据集查询的完整模块导航

Apache Arrow 是一个面向列式数据交换与内存内加速处理的多语言工具箱,其 C++ 实现是诸多语言绑定(Python、R、Ruby、Rust 等)的性能底座。本文以官方 C++ API Reference([docs/source/cpp/api.rst](https://link.gitcode.com/i/5c68097ea520a93b6b6f7f1ae0614c4b))为骨架,逐一

gitblog_00657的博客 204

pytorch:中numpy数组转Tensor: Expected object of backend CUDA and type float

在pytorch中,想要将numpy数组x_n转化为Tensor,并指定dtype,便于训练: x_t=torch.Tensor(x_n,dtype=torch.float32) 若是使用GPU,则需要加上cuda: x_t=x_t.cuda()

weixin_43925119的博客 314

CUDA C++ 高效入门第二章 -- CUDA 线程组织之两个数组相加

CUDA C++ 高效入门第二章 -- CUDA 线程组织之两个数组相加

cy1641395022的博客 240
上一篇: 独立OpenCV的SIFT算法并可调试
下一篇: VS调试第三方库的方法如OpenCV
fb_help
博客等级 码龄12年 206粉丝 244原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值