Форум программистов, компьютерный форум, киберфорум
CUDA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
0 / 0 / 0
Регистрация: 17.04.2018
Сообщений: 18

Понимание программы на с++ + CUDA

04.06.2019, 13:42. Показов 3329. Ответов 3

Студворк — интернет-сервис помощи студентам
(решение разреженной матрицы методом простых итераций)С чего мне начать, у меня не получается алгоритм сложения и умножения занести в кудовскую функцию.Помогите пожалуйста.



C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# include <iostream>//классы и функции
# include <vector>//библиотека для работы с векторами
# include <fstream>//определены несколько классов и подключены заголовочные файлы <ifstream> — файловый ввод и  <ofstream>  — файловый вывод.
# include <numeric>
# include <cmath>
# include <chrono>
# include <locale>//для работы с кириллицей
# include "SparseMatrix.h"
 
//__global__ void function (float *A, float *b, float *X, float *X_new, float *ABS)
 
 
 
 
 
using namespace std;//стандартное пространство имён
 
const size_t Max_Iter = 50;//size_t-максимальное число байтов или символов, на которые функция может повлиять.
 
void print(const vector<double> &X);//функция записывания в файл out_SI
 
vector<double> solve_SI(const SparseMatrix &A,double Epsilon);//вектор реализации метода
 
vector<double> multiple(SparseMatrix &matrix,const vector<double> &vec);//вектор перемножения матрицы на вектор
 
double norm(const vector<double> &vec);//функция вычисления нормы
 
vector<double> k_plus(const vector<double> &first,const vector<double> &second);//вектор сложения векторов
 
vector<double> multiple(const vector<double> &vec,const double scalar);//умножение матрицы на скаляр
void TransformMatrix(SparseMatrix &matrix);//функция приведения матрицы к необходимому виду
 
int main()
{
    setlocale(LC_ALL, "Russian");
    //system("chcp 1251");
    /*Matrix m;
    m[0][0] = 2;
    m[0][1] = 1;
    m[0][2] = 11;
    m[1][0] = -1;
    m[1][1] = 3;
    m[1][2] = 12;
 
    auto matrix = SparseMatrix(m,2,3);
    matrix.print();*/
    auto matrix = SparseMatrix("a01.txt", "b01.txt");//auto может использоваться вместо типа переменной, чтобы сообщить компилятору, что он должен присвоить тип переменной исходя из инициализируемого значения
    auto start = chrono::steady_clock::now();//chrono добавлена в с++11, steady_clock-так называемые устойчивые часы, то есть ход которых не подвержен внешним изменениям.
    
    
    //начало времени
    /*cudaEvent_t   start_d, finish_d;
    cudaEventCreate(&start_d);
    cudaEventCreate(&finish_d);
 
    cudaEventRecord(start_d, 0);*/ 
 
    auto X = solve_SI(matrix, 1.0e-015);
    auto end = chrono::steady_clock::now();
    auto diff = end - start;
 
    cout << "Задача решалась за " << chrono::duration_cast<chrono::seconds>(diff).count() << " секунд\n";
    ofstream out("out_SI.txt");//записываем все в файл
    for (const auto &el : X)
        out << el << '\n';
 
    //окончание времени
    /*cudaEventRecord(finish_d, 0);
    cudaEventSynchronize(start_d);
    cudaEventSynchronize(finish_d);
    cudaEventElapsedTime(&time_dev, start_d, finish_d);
    cout << "Time of DEVICE: " << time_dev / 1000 << endl;*/
 
    system("pause");//в конце останавливаем
}
 
//умножение матрицы на вектор
//константная ссылка позволяет избежать копирования данных
//и защищает оригинал от изменения
vector<double> multiple(SparseMatrix &matrix,const vector<double> &vec)
{
    size_t n = matrix.m_nrows;
    vector<double> Res(n, 0);//<double>это тип, который быдет лежать в векторе, причем согласно методу изначально заполняем его нулями.
    for (size_t i = 0; i < n; ++i)
    for (size_t j = 0; j < n; ++j)
        Res[i] += matrix.get(i, j) * vec[j];
        return Res;
}
//вычисление нормы
double norm(const vector<double> &vec)//корень квадратный из скалярного(поэлементного) произведения векторов
{
    return sqrt(accumulate(vec.begin(), vec.end(), 0.0,[](double x, double y)//По умолчанию accumulate суммирует элементы. Нужно указать точку старта, конечную точку и значение от которого начинаем прибавлять.
    //0.0 — это параметр,который будет точкой отсчета
        //v.begin v.end-итераторы
    {
        return x + y*y;
    }));
}
//сложение векторов
vector<double> k_plus(const vector<double> &first,const vector<double> &second)//сумму координат заносим
{
    vector<double> r(first.size(), 0);//размер вектора, который заполняется нулями
    transform(first.begin(), first.end(), second.begin(), r.begin(), [](const double &x, const double &y)//transform-трансформирует(т.е. переносит измененное значение)каждый элемент из заданного диапазона в соответствии с предоставленной вами функцией, принимает на вход 2 вектора
    {
        return x + y;//представленное выражение(для каждой пары выполнит функцию, переданную крайним аргументом)
    });
    return r;
}
//умножение вектора на скаляр (поэлементное)
vector<double> multiple(const vector<double> &vec,const double scalar)
{
    vector<double> R(vec.size());//размер вектора
    transform(vec.begin(), vec.end(), R.begin(), [&scalar](const double &x)//и также тут выполняем вычисление от начала begin до конца end
    {
        return x*scalar;
    });
    return R;
}
//приведение матрицы к необходимому виду
void TransformMatrix(SparseMatrix &matrix)
{
    auto n = matrix.m_nrows;
    for (size_t i = 0; i<n; i++)
    {
        auto el = matrix.get(i, i);//получаем значение из ячейки (1.1, 2.2, 3.3 ...)
        if (el>0)
        {
            matrix.set(1 - el, i, i);//кладем значение в ячейку
            for (size_t j = 0; j<n; j++)
            if (i != j)
                matrix.set(-matrix.get(i, j), i, j);//то же самое
        }
        else
        {
            matrix.set(1 + el, i, i);
            matrix.set(-matrix.get(i, n), i, n);
        }
    }
}
//реализация метода
vector<double> solve_SI(const SparseMatrix &A,double Epsilon)
{
    size_t iter = 1;
    auto Matrix = A;
    auto n = Matrix.m_nrows;
 
    if (n == 0)
        return vector<double>{};
        
    auto B = Matrix.get_column(n);
 
    TransformMatrix(Matrix);
    auto X = vector<double>(n, 0);//вектор длины n и заполняет нулями
    while (iter<Max_Iter)//пока меньше 50 итераций
    {
        //делаем шаг
        auto Xnew = k_plus(multiple(Matrix, X), B);
        //расчитываем норму приращения(разница между 2-мя приближениями)
        double n2 = norm(k_plus(Xnew, multiple(X, -1)));
            if (n2<Epsilon)
        {
            cout << "Количество итераций:" << iter << '\n';
            return X;
        }
        X = Xnew;
        ++iter;
    }
    cout << "Метод расходится\n";
    
    return X;
    
}
 
void print(const vector<double> &X)
{
    for (const auto &el : X)
        cout << el << ' ';
    cout << '\n';
}






заголовочный файл.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#pragma once //препроцессорная директива,цель-исходный файл при компиляции подключался строго один раз
#include <iostream>//классы и функции
#include <unordered_map>//Определяет шаблонные классы unordered_map и unordered_multimap контейнера и их поддерживает шаблоны.
#include <string>//Определяет класс шаблонов контейнеров basic_string и некоторые вспомогательные шаблоны.
#include <regex>//анализа регулярных выражений 
#include <fstream>//определены несколько классов и подключены заголовочные файлы <ifstream> — файловый ввод и  <ofstream>  — файловый вывод.
#include <vector>//библиотека для работы с векторами
 
using namespace std;//стандартное пространство имён
 
typedef unordered_map <size_t, double> IndexValue;
typedef unordered_map  <size_t, IndexValue> Matrix;
 
struct SparseMatrix
{
 
    SparseMatrix(const string &A, const string &B)
    {
        ifstream in(A);
        string line;
        getline(in, line);//считали шапку
        in >> m_nrows;
        m_ncols = m_nrows + 1;
        getline(in, line);//считали значение
        getline(in, line);//считали шапку-2
        while (in)
        {
            size_t i, j;
            double val;
            in >> i >> j >> val;
            m_matrix[i][j] = val;
        }
        in.close();
        in.open(B);
        getline(in, line);
        getline(in, line);
        getline(in, line);
        while (in)
        {
            size_t i;
            double val;
            in >> i >> val;
            m_matrix[i][m_nrows] = val;
        }
        cout << "************************************************************************************************************************";
        cout << "Решение СЛАУ методом простой итерации:" << endl;
 
        cout << "Матрица, размером: " << m_matrix.size() << " x " << m_matrix.size() << '\n';
        cout << "Идет решение....ожидайте" << endl;
 
    }
 
    SparseMatrix(const Matrix &matrix, size_t s1, size_t s2)
    {
        m_matrix = matrix;
        m_nrows = s1;
        m_ncols = s2;
    }
 
    void print()
    {
        for (size_t i = 0; i<m_nrows; i++)
        {
            for (size_t j = 0; j<m_ncols; j++)
                cout << m_matrix[i][j] << ' ';
            cout << '\n';
        }
    }
 
    double get(size_t i, size_t j)
    {
        return m_matrix[i][j];
    }
 
    vector<double> get_column(size_t j)
    {
        vector<double> R(m_nrows);
        for (size_t i = 0; i<m_nrows; i++)
        {
            R[i] = m_matrix[i][j];
        }
        return R;
    }
 
    void set(double val, size_t i, size_t j)
    {
        m_matrix[i][j] = val;
    }
 
    size_t m_nrows;//количество строк
    size_t m_ncols;//количество столбцов
 
private:
    Matrix   m_matrix;
};
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
04.06.2019, 13:42
Ответы с готовыми решениями:

Программы с поддержкой технологии nVidia CUDA
Доброго времени суток... Я вот последним временем заинтересовался этой технологией, как пользователь. Подскажите пожалуйста,...

Не запускается приложение под Cuda (CUDA directory not found)
Здравствуйте, пытаюсь скомпилировать приложение под Cuda но вылазит ошибка, что CUDA directory not found. В чем может быть проблема? Cuda...

Тестирование производительности программы написанной с использованием CUDA Runtime API
Уважаемые форумчане. У меня возник один вопрос: имеется программа меняющая местами сектора двух матриц больших размеров около 4 * 10^8, 4...

3
20 / 19 / 7
Регистрация: 31.01.2016
Сообщений: 79
04.06.2019, 19:44
Сделать надо примерно следующее:
1) создать device переменные через cudaMalloc((void**)&variable_name, size_of_array * sizeof(type));
2) скопировать значение переменных с host'a на device через cudaMemcpy(dev_var, host_var, size_of_array * sizeof(type), cudaMemcpyHostToDevice);
3) записать параметры запуска в виде:
C++
1
2
3
4
5
dim3 threads, blocks;// количество нитей в блоке и блоков в сетке
threads.x = ...;
threads.y = ...;
blocks.x = ...;
blocks.y = ...;
4) запустить функцию с этими параметрами в виде func <<<threads, blocks >>> (...) (о ней ниже);
5) скопировать результат обратно на host через cudaMemcpy(host_var, dev_var, size_of_array * sizeof(type), cudaMemcpyDeviceToHost);

По поводу функции:
1) она должна быть __global__, и вроде как даже void, но это неточно уже;
2) вместо циклов у вас будет два индекса, i = threadIdx.x + blockDim.x*blockIdx.x и j = threadIdx.y + blockDim.y*blockIdx.y; по ним и обращайтесь к элементам массива.
1
0 / 0 / 0
Регистрация: 17.04.2018
Сообщений: 18
04.06.2019, 20:27  [ТС]
Спасибо большое!
"она должна быть __global__, и вроде как даже void, но это неточно уже;"-да, так и будет, это основная функция пойдет

но как все вектора закинуть в неё, вот вопрос
0
20 / 19 / 7
Регистрация: 31.01.2016
Сообщений: 79
05.06.2019, 09:36
Через указатели, просто надо будет в неё вносить не только входные массивы, но и массив результатов.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.06.2019, 09:36
Помогаю со студенческими работами здесь

3 программы на понимание
Найти сумму двух матриц А(N,M) и В(N,M) Найти произведение двух матриц А(N,M) и В(M,K) Найти произведение матрицы А(N,M) на вектор В(N)...

Не понимание программы
Добрый день, недавно возникла нужда в небольшой программке, помогите пожалуйста Задача: вывести каждый элемент из массива, но в разном...

Folding@home система распределённых вычислений. Есть видеокарта с CUDA, а некуда использовать? Хотя вообще видеокарта с CUDA не обязательна.
Купил видеокарту уже давненько Palit GeForce GTX570 Sonic Platinum. У неё есть программно-аппаратная архитектура, называется CUDA. Вот я...

Понимание С++
Приветствую. У меня такой вопрос. Если я сейчас учусь с++ (читаю книгу), то нужно в этой книге каждый пример понимать и что-то с ним...

Понимание рекурсии
Доброго всем времени суток! В статье на Хабре &quot;Как я завалил собеседование в Twitter&quot; заинтересовала задачка. Для решения её сначала...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru