Как скопировать динамическую матрицу в память устройства в CUDA?

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

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

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

Как мне это сделать?

А что не так с cudaMalloc и cudaMemcpy?

pptaszni 29.05.2019 20:14

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

Robert Crovella 29.05.2019 20:59

@ Ptaq666 выдает «Ошибка CUDA: недопустимый символ устройства».

Armeno 29.05.2019 21:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
368
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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

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, которые вам нужно сделать. И класс, разработанный специально для обработки вашей функциональности, не сломается, когда вы неизбежно совершите ошибку, пытаясь вручную обработать все управление указателями в исходном коде.

@ user10933809 Такое решение почти никогда не рекомендуется. Большинство сред гетерогенных вычислений имеют не особенно высокие ограничения на количество буферов, которые могут быть индивидуально адресованы для одного ядра. Если набор данных OP явно не ограничен очень небольшим числом (т. Е. TRANSACTIONS меньше 100), такое решение просто нежизнеспособно. Что я сделал, так это предоставил полезную структуру для быстрого преобразования их «массива указателей» на стороне хоста в плоский массив, который будет соответствовать макету данных, ожидаемому буферами данных устройства.

Xirema 29.05.2019 20:25

без сомнения, здесь массив должен быть сглажен. Мне просто интересно, не могли бы вы предоставить решение с массивом указателей.

Oblivion 29.05.2019 20:29

@ user10933809 Как я уже сказал: такое решение нежизнеспособно.

Xirema 29.05.2019 20:36

Нет, это не прямоугольная матрица @Xirema.

Armeno 29.05.2019 20:41

@Армено Это нормально; решение работает так, как если бы число, которое вы передаете как количество столбцов, равно самой большой строке ваших входных данных.

Xirema 29.05.2019 20:50

Спасибо @Xirema, но я ищу другой метод.

Armeno 29.05.2019 20:51

@Armeno Ну, если ваше ограничение «Я хочу скопировать его в память устройства только один раз», я не знаю, какое другое решение существует ...

Xirema 29.05.2019 20:53

@oblivion нет.ничего нет

Armeno 02.06.2019 21:22

Другие вопросы по теме