使用 Vulkan VkImage 作为 CUDA cuArray
使用 Vulkan VkImage 作为 CUDA cuArray
【问题标题】:Use Vulkan VkImage as a CUDA cuArray使用 Vulkan VkImage 作为 CUDA cuArray
【发布时间】:2019-08-20 20:01:10
【问题描述】:
将 Vulkan VkImage 用作 CUDA cuArray 的正确方法是什么?
我一直在尝试遵循一些示例,但是我在调用 cuExternalMemoryGetMappedMipmappedArray() 时收到了 CUDA_ERROR_INVALID_VALUE
以有序的方式提供信息。
我正在使用 CUDA 10.1
基本代码来自https://github.com/SaschaWillems/Vulkan,特别是我正在使用01 - Vulkan Gears 演示,丰富了saveScreenshot 方法09 - Capturing screenshots
我不会将快照图像保存到文件中,而是将快照图像作为 CUarray 发送到 CUDA。
我已启用以下实例和设备扩展:
std::vector<const char*> instanceExtensions = {VK_EXT_DEBUG_REPORT_EXTENSION_NAME,VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME };std::vector<const char*> deviceExtensions = { VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME };
我有一个VkImage,创建如下:
// Create the linear tiled destination image to copy to and to read the memory fromVkImageCreateInfo imageCreateCI(vks::initializers::imageCreateInfo());imageCreateCI.imageType = VK_IMAGE_TYPE_2D;// Note that vkCmdBlitImage (if supported) will also do format conversions if the swapchain color format would differimageCreateCI.format = VK_FORMAT_R8G8B8A8_UNORM;imageCreateCI.extent.width = width;imageCreateCI.extent.height = height;imageCreateCI.extent.depth = 1;imageCreateCI.arrayLayers = 1;imageCreateCI.mipLevels = 1;imageCreateCI.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;imageCreateCI.samples = VK_SAMPLE_COUNT_1_BIT;imageCreateCI.tiling = VK_IMAGE_TILING_LINEAR;imageCreateCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;imageCreateCI.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;VkExternalMemoryImageCreateInfoKHR extImageCreateInfo = {};/** Indicate that the memory backing this image will be exported in an* fd. In some implementations, this may affect the call to* GetImageMemoryRequirements() with this image.*/extImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR;extImageCreateInfo.handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;imageCreateCI.pNext = &extImageCreateInfo;// Create the imageVkImage dstImage;VK_CHECK_RESULT(vkCreateImage(device, &imageCreateCI, nullptr, &dstImage));// Create memory to back up the imageVkMemoryRequirements memRequirements;VkMemoryAllocateInfo memAllocInfo(vks::initializers::memoryAllocateInfo());VkDeviceMemory dstImageMemory;vkGetImageMemoryRequirements(device, dstImage, &memRequirements);memAllocInfo.allocationSize = memRequirements.size;// Memory must be host visible to copy frommemAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);VkExportMemoryAllocateInfoKHR exportInfo = {};exportInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;exportInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;memAllocInfo.pNext = &exportInfo;VK_CHECK_RESULT(vkAllocateMemory(device, &memAllocInfo, nullptr, &dstImageMemory));VK_CHECK_RESULT(vkBindImageMemory(device, dstImage, dstImageMemory, 0));从那里我会:
获取 Vulkan 内存处理程序:
intCuEncoderImpl::getVulkanMemoryHandle(VkDevice device,VkDeviceMemory memory) {// Get handle to memory of the VkImageint fd = -1;VkMemoryGetFdInfoKHR fdInfo = { };fdInfo.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR;fdInfo.memory = memory;fdInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;auto func = (PFN_vkGetMemoryFdKHR) vkGetDeviceProcAddr(device,"vkGetMemoryFdKHR");if (!func) {printf("Failed to locate function vkGetMemoryFdKHR\n");return -1;}VkResult r = func(device, &fdInfo, &fd);if (r != VK_SUCCESS) {printf("Failed executing vkGetMemoryFdKHR [%d]\n", r);return -1;}return fd;}导入内存:
CUDA_EXTERNAL_MEMORY_HANDLE_DESC memDesc = { };memDesc.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD;memDesc.handle.fd = getVulkanMemoryHandle(device, memory);memDesc.size = extent.width*extent.height*4;CUDA_DRVAPI_CALL(cuImportExternalMemory(&externalMem, &memDesc));并映射内存:这是失败的步骤。
CUarray CuEncoderImpl::getCUDAArrayFromExternalMemory(const VkExtent3D &extent,const CUexternalMemory &m_extMem) {CUmipmappedArray m_mipmapArray;CUresult result = CUDA_SUCCESS;CUarray array;CUDA_ARRAY3D_DESCRIPTOR arrayDesc = { };arrayDesc.Width = extent.width;arrayDesc.Height = extent.height;arrayDesc.Depth = 0;arrayDesc.Format = CU_AD_FORMAT_UNSIGNED_INT32;arrayDesc.NumChannels = 4;arrayDesc.Flags = CUDA_ARRAY3D_SURFACE_LDST;CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC mipmapArrayDesc = { };mipmapArrayDesc.arrayDesc = arrayDesc;mipmapArrayDesc.numLevels = 1;mipmapArrayDesc.offset = 0;CUDA_DRVAPI_CALL(cuExternalMemoryGetMappedMipmappedArray(&m_mipmapArray, m_extMem, &mipmapArrayDesc));CUDA_DRVAPI_CALL(cuMipmappedArrayGetLevel(&array, m_mipmapArray, 0));return array;
}我一直在尝试多种参数组合,但到目前为止都失败了。错误指向一个无效的参数,但我不知道如何找出问题所在。
唯一可行的方法是将 Vulkan 映像内存映射到主机缓冲区,然后将其复制到 CUDA 数组中......但我想这很昂贵,如果可能的话我想避免它。
【问题讨论】:
@talonmies Vulkan-CUDA 互操作性是 CUDA 10 的一项功能,请参阅 devblogs.nvidia.com/cuda-10-features-revealed
标签: cuda gpu nvidia vulkan cuda-arrays
【解决方案1】:
为了记录,我终于让它工作了。
我必须对问题中列出的代码进行一些注释和修改:
Vulkan-CUDA 互操作性被宣传为 CUDA 10 的一项功能,请参阅CUDA 10 Features revealed
要映射的图像的平铺必须是 `VK_IMAGE_TILING_OPTIMAL
imageCreateCI.tiling = VK_IMAGE_TILING_OPTIMAL;该图像的内存必须使用VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT 分配
memAllocInfo.memoryTypeIndex = vulkanDevice->getMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);导入内存时的内存描述符应使用内存要求中返回的内存大小(下面的size 是创建图像的代码中的memRequirements.size):
CUDA_EXTERNAL_MEMORY_HANDLE_DESC memDesc = { };memDesc.type = CU_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD;memDesc.handle.fd = getVulkanMemoryHandle(device, memory);memDesc.size = size;CUDA_DRVAPI_CALL(cuImportExternalMemory(&externalMem, &memDesc));最后映射的数组被描述为CU_AD_FORMAT_UNSIGNED_INT8,有四个通道和CUDA_ARRAY3D_COLOR_ATTACHMENT
CUDA_ARRAY3D_DESCRIPTOR arrayDesc = { };arrayDesc.Width = extent.width;arrayDesc.Height = extent.height;arrayDesc.Depth = 0;arrayDesc.Format = CU_AD_FORMAT_UNSIGNED_INT8;arrayDesc.NumChannels = 4;arrayDesc.Flags = CUDA_ARRAY3D_COLOR_ATTACHMENT;CUDA_EXTERNAL_MEMORY_MIPMAPPED_ARRAY_DESC mipmapArrayDesc = { };mipmapArrayDesc.arrayDesc = arrayDesc;mipmapArrayDesc.numLevels = 1;mipmapArrayDesc.offset = 0;CUDA_DRVAPI_CALL(cuExternalMemoryGetMappedMipmappedArray(&m_mipmapArray, m_extMem, &mipmapArrayDesc));
复制在这些更改之后,我能够让它工作。 我很少有更改是我这边明显的错误(比如大小),我在第 100 次仔细阅读文档时发现的一些东西,其他人是对文档中提示的猜测,最后,大量的试验和错误.
【讨论】:
非常感谢你,我设法在不到一天的时间内运行了它:)
不过,我不确定一件事。我们必须在这个管道中调用哪些销毁/释放函数?我猜,cudaFreeMipmappedArray 和 cudaDestroyExternalMemory,但不是 mipmap 级别的 cudaFreeArray?
CUDA 10 功能揭晓:图灵、CUDA 图等 |英伟达技术博客 (nvidia.com)
CUDA Toolkit 12.1 Downloads | NVIDIA Developer
NVIDIA/cuda-samples: Samples for CUDA Developers which demonstrates features in CUDA Toolkit (github.com)
相关文章:
使用 Vulkan VkImage 作为 CUDA cuArray
使用 Vulkan VkImage 作为 CUDA cuArray【问题标题】:Use Vulkan VkImage as a CUDA cuArray使用 Vulkan VkImage 作为 CUDA cuArray【发布时间】:2019-08-20 20:01:10【问题描述】:将 Vulkan VkImage 用作 CUDA cuArray 的正确方法是什么&am…...
电商API接口-电商OMS不可或缺的一块 调用代码展示
电商后台管理系统关键的一环就是实现电商平台数据的抓取,以及上下架商品、订单修改等功能的调用。这里就需要调用电商API接口。接入电商API接口后再根据自我的需求进行功能再开发,实现业务上的数字化管理。其中订单管理模板上需要用到如下API:seller_ord…...
Solaris ZFS文件系统rpool扩容
ZFS文件系统简介 Solaris10默认的文件系统是ufs(Unix Filesystem),当然也可以选装zfs;Solaris11默认的文件系统是zfs(Zettabyte Filesystem)。 ZFS文件系统的英文名称为Zettabyte File System,也叫动态文件…...
模式识别 —— 第二章 参数估计
模式识别 —— 第二章 参数估计 文章目录模式识别 —— 第二章 参数估计最大似然估计(MLE)最大后验概率估计(MAP)贝叶斯估计最大似然估计(MLE) 在语言上: 似然(likelihood…...
判断4位回文数-课后程序(Python程序开发案例教程-黑马程序员编著-第3章-课后作业)
实例1:判断4位回文数 所谓回文数,就是各位数字从高位到低位正序排列和从低位到高位逆序排列都是同一数值的数,例如,数字1221按正序和逆序排列都为1221,因此1221就是一个回文数;而1234的各位按倒序排列是43…...
【NLP】Word2Vec 介绍
Word2Vec 是一种非常流行的自然语言处理技术,它将每个单词表示为高维向量,并且通过向量之间的相似度来表示单词之间的语义关系。 1 One-Hot 编码🍂 在自然语言处理任务中,我们需要将文本转换为计算机可以理解的形式,即…...
3月6日,30秒知全网,精选7个热点
///石家庄地铁:在指定店铺购物金额不限 就可免费乘地铁 乘客只要在指定商铺或地铁站内36524便利店购物,便能得到一张当日乘车券,可免费乘坐地铁一次,不限里程 ///神州泰岳:公司语音机器人等产品能够进行多轮问答 公司…...
Python笔记 -- 字典
文章目录1、概述2、增删改查3、遍历3.1、遍历所有键值对3.2、分别遍历键和值4、嵌套4.1、字典列表4.2、在字典中储存列表4.3、在字典中储存字典1、概述 字典是一系列键值对,可将任何Python对象作为字典中的值 字典和列表容易混淆,列表也可用{} 字典是一…...
【独家】华为OD机试 - 滑动窗口(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...
MySQL调优 - SQL查询深度分页问题
一、问题引入 例如当前存在一张表test_user,然后往这个表里面插入3百万的数据: CREATE TABLE test_user (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键id,user_id varchar(36) NOT NULL COMMENT 用户id,user_name varchar(30) NOT NULL COMMENT 用…...
0306spring--复习
一,spring是什么 Spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的容器框架 理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架 优点࿱…...
动手实现一遍Transformer
最近乘着ChatGpt的东风,关于NLP的研究又一次被推上了风口浪尖。在现阶段的NLP的里程碑中,无论如何无法绕过Transformer。《Attention is all you need》成了每个NLP入门者的必读论文。惭愧的是,我虽然使用过很多基于Transformer的模型&#x…...
【Flutter入门到进阶】Flutter基础篇---弹窗Dialog
1 AlertDialog 1.1 说明 最简单的方案是利用AlertDialog组件构建一个弹框 1.2 示例 void alertDialog(BuildContext context) async {var result await showDialog(barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框context: context,builder: (context)…...
【操作系统】进程和线程的区别
文章目录1. 概述2. 进程3. 线程4. 协程5. 进程与线程区别1. 概述 进程和线程这两个名词天天听,但是对于它们的含义和关系其实还有点懵的,其实除了进程和线程,还存在一个协程,它们的关系如下: 首先,我们需要…...
Linux开发环境配置--正点原子阿尔法开发板
Linux开发环境配置–正点原子阿尔法开发板 文章目录Linux开发环境配置--正点原子阿尔法开发板1.网络环境设置1.1添加网络适配器1.2虚拟网络编辑器设置1.3Ubuntu和Windows网络信息设置Ubuntu网络信息配置方式:1.系统设置->网络->选项2.配置网络文件2源码准备2.…...
Android ThreadPoolExecutor的基本使用
ThreadPoolExecutor是Java中的一个线程池类,Android中也可以使用该类来管理自己的线程池,它为我们管理线程提供了很多方便。 线程池是一种能够帮助我们管理和复用线程的机制,它可以有效地降低线程创建和销毁的开销。使用线程池可以避免不必要…...
基于区域生长和形态学处理的图像融合方法——Matlab图像处理
✅ 大三下时弄的 文章目录最终效果图摘要1 研究背景及意义2 基本原理描述3 实验数据来源3.1 原始图像的来源3.2 天空背景图像的来源4 实验步骤及相应处理结果4.1 原始图像的预处理4.2 区域生长法分割图像4.3 形态学处理填充孔洞4.4 边缘检测根据二值图像构造RGB图像4.5 图像拼接…...
三个案例场景带你掌握Cisco交换机VLAN互通
VLAN间路由的方式现在主流的组网主要是依靠三层交换机通过配置SVI接口【有的厂商叫VLANIF接口】,当然也有比较小型的网络,它就一个出口路由器可管理的二层交换机,还有一种更加差的,就是出口路由一个可管理的二层交换机,…...
小白入门之持久连接与非持久连接的差别
对比 HTTP 0.9 已过时 HTTP1.0:非持续连接,每个连接只处理一个请求响应事务,有些服务器端甚至还在用此,可以在一定时间内复用连接,具体复用时间的长短可以由服务器控制,一般在15s左右。 HTTP 1.1 默认使用持…...
TypeScript篇.01-简介,类,接口,基础类型
1.简介(1)安装及编译安装: npm install -g typescript创建 .ts 后缀名的文件编译: tsc 文件名.ts 编译后会生成同名 .js 的文件查看: 在html文件中script引入js文件,运行查看控制台即可(2)类型注解TypeScript里的类型注解是一种轻量级的为函数或变量添加约束的方式 变量或函数声…...
PCIe 6.0 Flit Mode 实战解析:从TLP到Flit,你的数据包到底经历了什么?
PCIe 6.0 Flit Mode 深度解析:数据包的奇幻漂流之旅 当一颗来自CPU的事务请求被封装成TLP(Transaction Layer Packet)时,它即将开始一段穿越PCIe 6.0协议栈的奇妙旅程。这段旅程不再是传统PCIe版本中的"自由行"…...
ARM CoreSight ROM Tables解析与调试实践
1. ARM CoreSight ROM Tables基础解析在嵌入式调试领域,ARM CoreSight架构提供了一套完整的调试与追踪解决方案。作为该架构的关键组成部分,ROM Tables扮演着系统调试资源的"目录"角色。想象一下走进一个巨大的图书馆,ROM Tables就…...
保姆级教程:用Materials Studio切(111)晶面并构建真空层,一步步教你分析晶体生长
从零开始掌握Materials Studio晶体表面建模:以(111)晶面为例的完整实战指南 在材料模拟与计算化学领域,精确构建晶体表面模型是研究催化反应、界面特性以及材料生长机制的基础环节。Materials Studio作为业界广泛采用的模拟平台,其表面建模功…...
嵌入式Python库CI/CD实战:Travis CI自动化测试与发布
1. 项目概述与核心价值 如果你正在维护一个开源项目,或者在一个小团队里负责核心模块的开发,那么你一定对“这次改动会不会把别人的代码搞坏”这个问题感到头疼。尤其是在嵌入式开发领域,比如我们常用的CircuitPython库,代码最终要…...
卡梅德生物技术快报|骆驼纳米抗体:从原核表达、高通量测序到分子对接全流程实现
1. 问题背景(技术痛点)靶向结合分子开发中,传统抗体制备存在:分子量大,扩散与穿透效率有限;文库构建与淘选周期长,难以规模化;原核表达与纯化体系不稳定,批次差异大&…...
告别盗版与广告:Office 2021官方纯净部署实战指南
1. 为什么选择官方纯净部署Office 2021? 每次打开电脑看到弹窗广告,或者发现系统莫名变慢的时候,你是不是也怀疑过那些所谓的"破解版"办公软件?我去年就吃过这个亏——用了某个号称"永久激活"的Office安装包…...
Diablo Edit2:暗黑破坏神2角色存档编辑器的终极指南
Diablo Edit2:暗黑破坏神2角色存档编辑器的终极指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 你是否曾经在暗黑破坏神2中花费数小时刷装备却一无所获?是否因为技能点…...
构建安全通讯系统:从加密原理到工程实践的全方位指南
1. 项目概述:为什么我们需要一个“安全通讯系统”?在当今这个信息高度互联的时代,通讯早已渗透到我们工作和生活的每一个角落。从日常的即时消息、邮件往来,到企业内部的机密文件传输、远程会议,再到物联网设备间的数据…...
如何快速部署开源捉妖雷达Web版:面向新手的完整实时妖怪追踪指南
如何快速部署开源捉妖雷达Web版:面向新手的完整实时妖怪追踪指南 【免费下载链接】zhuoyao_radar 捉妖雷达 web版 项目地址: https://gitcode.com/gh_mirrors/zh/zhuoyao_radar 捉妖雷达Web版是一款基于现代Web技术开发的实时妖怪追踪工具,专为捉…...
如何使用Redis优化Trigger.dev任务队列:提升AI工作流性能的完整指南
如何使用Redis优化Trigger.dev任务队列:提升AI工作流性能的完整指南 【免费下载链接】trigger.dev Trigger.dev – build and deploy fully‑managed AI agents and workflows 项目地址: https://gitcode.com/gh_mirrors/tr/trigger.dev Trigger.dev是一个强…...
