简体   繁体   中英

2D jagged array to 1D array in C++

I need to convert dynamic array of dynamic arrays into 1D array for CUDA computation.

Example pseudo code:

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

I found that the best way to pass 2D array to CUDA kernel is to flatten it but it works only for matrix ( i=block.x*M+block.y ) but not when each row has different count of columns.

EDIT:

I need to access 1D array elements like it was 2D using params, eg.: a & b.

Two possible approaches:

  1. Create a 2D matrix that is equal in dimension to the largest x dimension. So if x is an array of pointers of length N (each to a vector), and the maximum dimension of any individual vector is M, then create C(N,M), and fill each row of C with a vector of x . Then flatten it and transfer it to the device. This method, while requiring extra storage, will likely yield the fastest access on the device.

  2. Create a "compressed" storage format:

     xh = [1, 4, 3, 9, 2, 0, 5, 7, 6] xi = [0, 4, 6]

    transfer these vectors to the device (they are already flat.) On the device, access a member i, of vector j, by:

     myval = xh[xi[j] + i];

    for this method you may also want to pass a vector of limits:

     xl = [4, 2, 3]

    Because of the indirection through xi[j] potentially required for each access, this method may result in slower access on the device.

I do not know of a way to do this with arrays if you do not know how many columns are in each row. There is an easy way to do this with a vector though as you can use the iterator ranges. You can do it like:

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM