主机端libcu++ <cuda/std/mdspan>构造与访问问题咨询
libcu++ 2.1.0中mdspan的构造与访问问题解决
问题背景
使用nvcc 12.0搭配libcu++ 2.1.0复现mdspan示例代码时,遇到两个编译错误:
- 直接传入指针+维度整数构造mdspan失败,报错:
no instance of constructor "mdspan" matches the argument list
argument types are: (int *, int, int)
- 使用
[]逗号语法访问元素失败,报错:
error: no operator "[]" matches these operands
operand types are: cuda::std::__4::mdspan<int, cuda::std::__4::extents<std::size_t, 2UL, 3UL, 2UL>, cuda::std::__4::layout_right, cuda::std::__4::default_accessor> [ std::size_t ]
解决方案
1. 构造时指定编译时未知的extent
libcu++ 2.1.0的mdspan未支持直接通过多个整数参数推导extents的构造方式,若需使用编译时未知的动态维度,需显式使用cuda::std::dextents定义动态extents类型,再传入运行时维度大小:
- 2维动态数组:
cuda::std::mdspan<int, cuda::std::dextents<std::size_t, 2>>,构造时传入指针+两个维度的大小 - 3维动态数组:
cuda::std::mdspan<int, cuda::std::dextents<std::size_t, 3>>,构造时传入指针+三个维度的大小
2. 访问mdspan的数据
libcu++ 2.1.0的mdspan不支持C++23标准中的[]逗号访问语法(如ms[i,j]),需改用operator()来访问元素,即通过ms(i,j)(二维)或ms(i,j,k)(三维)的形式读写数据。
修正后的可编译代码
#include <cstddef> #include <vector> #include <cstdio> #include <cuda/std/mdspan> int main() { std::vector v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 使用动态extents构造运行时维度的mdspan auto ms2 = cuda::std::mdspan<int, cuda::std::dextents<std::size_t, 2>>(v.data(), 2, 6); auto ms3 = cuda::std::mdspan<int, cuda::std::dextents<std::size_t, 3>>(v.data(), 2, 3, 2); // 也可保留编译时固定extents的写法,访问时改用operator() // cuda::std::mdspan<int, cuda::std::extents<std::size_t, 2,6>> ms2(v.data()); // cuda::std::mdspan<int, cuda::std::extents<std::size_t, 2,3,2>> ms3(v.data()); // 用operator()访问二维view写入数据 for (std::size_t i = 0; i != ms2.extent(0); i++) for (std::size_t j = 0; j != ms2.extent(1); j++) ms2(i, j) = i * 1000 + j; // 用operator()访问三维view读取数据 for (std::size_t i = 0; i != ms3.extent(0); i++) { printf("slice @ i = %lu\n", i); for (std::size_t j = 0; j != ms3.extent(1); j++) { for (std::size_t k = 0; k != ms3.extent(2); k++) printf("%d ", ms3(i, j, k)); printf("\n"); } } }
编译命令保持不变:
nvcc -Ilibcudacxx-2.1.0/include/ -std=c++17 main.cu -o main
内容的提问来源于stack exchange,提问作者Abator Abetor
相关产品推荐
相关产品推荐

