Как скопировать динамическую матрицу в память устройства в CUDA? - PullRequest
0 голосов
/ 29 мая 2019

В моем коде у меня есть динамическая матрица.

int ** file_data = (int **)malloc(TRANSACTIONS * sizeof(int *));
file_data[0] = (int *)malloc((a_size+1) * sizeof(int));
file_data[1] = (int *)malloc((a_size+1) * sizeof(int));
file_data[2] = (int *)malloc((a_size+1) * sizeof(int));
................................................................

Я хочу скопировать его в глобальную память устройства только один раз.

Я использовал:

__device__ int raw_data[][];
...................................
...................................
...................................
cudaMemcpyToSymbol(raw_data[i], file_data[i], (a_size+1)*sizeof(int));

Но это не работает.

Как я могу это сделать?

1 Ответ

2 голосов
/ 29 мая 2019

Вам нужно сгладить данные

Если вы в первую очередь работаете только с прямоугольными матрицами, я бы в любом случае рекомендовал всегда хранить ваши матрицы таким образом, но в любом случае вам понадобитсявведите его в эту форму, прежде чем пытаться отправить эти данные в память устройства.

template<typename T>
class Matrix {
    std::vector<T> _data;
    size_t rows, columns;
public:
    Matrix(size_t rows, size_t columns) :rows(rows), columns(columns) {
        _data.resize(rows * columns);
    }

    T & operator()(size_t row, size_t column) & {
        return _data.at(row * columns + column); //Row-Major Ordering
    }

    T const& operator()(size_t row, size_t column) const& {
        return _data.at(row * columns + column);
    }

    T operator() size_t row, size_t column) const {
        return _data.at(row * columns + column);
    }

    T * data() & {
        return _data.data();
    }

    T const* data() const& {
        return _data.data();
    }

    std::pair<size_t, size_t> size() const {
        return {rows, columns};
    }

    size_t flat_size() const {
        return rows * columns;
    }

    size_t byte_size() const {
        return flat_size() * sizeof(T);
    }
};

int ** file_data = (int **)malloc(TRANSACTIONS * sizeof(int *));
file_data[0] = (int *)malloc((a_size+1) * sizeof(int));
file_data[1] = (int *)malloc((a_size+1) * sizeof(int));
file_data[2] = (int *)malloc((a_size+1) * sizeof(int));
//................................................................

Matrix<int> flat_data(TRANSACTIONS, a_size + 1);
for(size_t row = 0; row < TRANSACTIONS; row++) {
    for(size_t column = 0; column < a_size + 1; column++) {
        flat_data(row, column) = file_data[row][column];
    }
}
//ALTERNATIVE: use this instead of your manual mallocs in the first place!

cudaMemcpyToSymbol(flat_data.data(), /*buffer name*/, flat_data.byte_size());

Это имеет главное преимущество, заключающееся в том, что вам не нужно копировать каждую строку отдельно в свои собственные буферы, вы можете собрать их все вместе в памяти, сэкономив память и сократив количество вызовов API, которые вынужно сделать.И класс, разработанный специально для обработки вашей функциональности, не сломается, если вы неизбежно совершите ошибку, пытаясь вручную обработать все управление указателями в вашем исходном коде.

...