C++ 中的二维锯齿状数组到一维数组
2D jagged array to 1D array in C++
我需要将动态数组的动态数组转换为一维数组以进行 CUDA 计算。
示例伪代码:
x[0] = [1, 4, 3, 9]
x[1] = [2, 0]
x[2] = [5, 7, 6]
y = flatten(x) // Eg.: [1, 4, 3, 9, 2, 0, 5, 7, 6]
get_index(a, b) // Should return index in 1D array
// that coresponds to element in original 2D array
y[get_index(0, 2)] = 4
y[get_index(1, 0)] = 2
y[get_index(2, 2)] = 7
我发现将二维数组传递给 CUDA 内核的最佳方法是将其展平,但它仅适用于矩阵 (i=block.x*M+block.y
),但不适用于每行具有不同列数的情况。
编辑:
我需要使用参数像访问二维数组元素一样访问一维数组元素,例如:a & b。
两种可能的方法:
创建一个维度等于最大 x
维度的二维矩阵。因此,如果 x
是一个长度为 N 的指针数组(每个指针指向一个向量),并且任何单个向量的最大维度为 M,则创建 C(N,M),并用一个x
的向量。然后将其压平并转移到设备上。此方法虽然需要额外的存储空间,但可能会在设备上产生最快的访问速度。
创建"compressed"存储格式:
xh = [1, 4, 3, 9, 2, 0, 5, 7, 6]
xi = [0, 4, 6]
将这些向量传输到设备(它们已经是平面的。)在设备上,通过以下方式访问向量 j 的成员 i:
myval = xh[xi[j] + i];
对于此方法,您可能还想传递一个限制向量:
xl = [4, 2, 3]
由于每次访问都可能需要通过 xi[j]
进行间接访问,因此此方法可能会导致设备访问速度变慢。
如果您不知道每行中有多少列,我不知道有什么方法可以对数组执行此操作。有一种简单的方法可以使用向量执行此操作,因为您可以使用迭代器范围。你可以这样做:
std::vector<std::vector<int>> data2d;
std::vector<int> data1d;
data1d.reserve(data2d.size() * data2d[0].size()); // reserve some memory. this is a guess of what is needed
for (const auto row : data2d)
data1d.insert(data1d.end(), row.begin(), row.end());
我需要将动态数组的动态数组转换为一维数组以进行 CUDA 计算。
示例伪代码:
x[0] = [1, 4, 3, 9]
x[1] = [2, 0]
x[2] = [5, 7, 6]
y = flatten(x) // Eg.: [1, 4, 3, 9, 2, 0, 5, 7, 6]
get_index(a, b) // Should return index in 1D array
// that coresponds to element in original 2D array
y[get_index(0, 2)] = 4
y[get_index(1, 0)] = 2
y[get_index(2, 2)] = 7
我发现将二维数组传递给 CUDA 内核的最佳方法是将其展平,但它仅适用于矩阵 (i=block.x*M+block.y
),但不适用于每行具有不同列数的情况。
编辑:
我需要使用参数像访问二维数组元素一样访问一维数组元素,例如:a & b。
两种可能的方法:
创建一个维度等于最大
x
维度的二维矩阵。因此,如果x
是一个长度为 N 的指针数组(每个指针指向一个向量),并且任何单个向量的最大维度为 M,则创建 C(N,M),并用一个x
的向量。然后将其压平并转移到设备上。此方法虽然需要额外的存储空间,但可能会在设备上产生最快的访问速度。创建"compressed"存储格式:
xh = [1, 4, 3, 9, 2, 0, 5, 7, 6] xi = [0, 4, 6]
将这些向量传输到设备(它们已经是平面的。)在设备上,通过以下方式访问向量 j 的成员 i:
myval = xh[xi[j] + i];
对于此方法,您可能还想传递一个限制向量:
xl = [4, 2, 3]
由于每次访问都可能需要通过
xi[j]
进行间接访问,因此此方法可能会导致设备访问速度变慢。
如果您不知道每行中有多少列,我不知道有什么方法可以对数组执行此操作。有一种简单的方法可以使用向量执行此操作,因为您可以使用迭代器范围。你可以这样做:
std::vector<std::vector<int>> data2d;
std::vector<int> data1d;
data1d.reserve(data2d.size() * data2d[0].size()); // reserve some memory. this is a guess of what is needed
for (const auto row : data2d)
data1d.insert(data1d.end(), row.begin(), row.end());