powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Нужна помощь по работе с CUDA на C#
2 сообщений из 2, страница 1 из 1
Нужна помощь по работе с CUDA на C#
    #38600141
VIP2020
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В интернете я нашел программу, которая рисует множество Мандельброта.
Пожалуйста, прокомментируйте код, чтобы я мог разобраться в приложении.

Приложение написано для этого задания:

авторМножество Мандельброта это множество таких комплексных чисел c таких, что последовательность z(n+1)=z(n)^2+c ограничена при z(0)=0. Напомним, что комплексному числу x+iy можно сопоставить точку (x,y). При этом (x+iy)(x+iy)=x^2-y^2+2xyi.

Напишите программу, которая получает данное множество на GPU. После запуска программы должен создаваться файл-изображение. Цвет пикселя должен зависеть от того, сколько итераций прошло до того, как точка вышла за границы круга с радиусом 100.

Например, мы хотим определить цвет пикселя c=(-1,0). Тогда z(0)=(0,0), z(1)=(-1,0), z(2)=(0,0), z(3)=(-1,0) и т.д. Поскольку точка не выходит за границы, то её цвет — чёрный. Если же c=(1,1), то z(0)=(0,0), z(1)=(1,1), z(2)=(1,3), z(3)=(-7,7), z(4)=(1,-97), z(5)=(-9407,-193). То есть на пятом шаге произошёл выход за границы. Поэтому цвет точки (1, 1) — очень близкий к белому.

Ядро должно отвечать за определение цвета одного пикселя. Соответственно суммарное количество потоков должно равняться суммарному количеству пикселей. Для пикселя в строке i и столбце j вам нужно сначала найти какой точке (x,y) он соответствует, затем определить цвет по описанной выше формуле и записать в массив цветов нужные значение.

Массив цветов пикселей это массив байт в котором четыре подряд идущие байта определяют прозрачную, синию, зелёную и красную состовляющую цвета. Чтобы получить доступ к массиву байт MSDN рекомендует следующий способ.


Вот код программы:

Код: 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.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Cudafy;
using Cudafy.Host;
using Cudafy.Translator;

namespace Zadanie_1
{
    public partial class Form1 : Form
    {
        static CudafyModule km = CudafyTranslator.Cudafy();
        static GPGPU gpu = CudafyHost.GetDevice(CudafyModes.Target);
        const int MAXITER = 255;
        const double XMAX = 0.7;
        const double XMIN = -2;
        const double YMIN = -1.2;
        const double YMAX = 1.2;
        const double YSTEP = 0.005;
        const double XSTEP = 0.005;
        const int SIZE = 640;
        
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            gpu.LoadModule(km);

            // Create a new bitmap.
            Bitmap bmp = new Bitmap(640, 640);

            // Lock the bitmap's bits.  
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            System.Drawing.Imaging.BitmapData bmpData =
                bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
                bmp.PixelFormat);

            // Get the address of the first line.
            IntPtr ptr = bmpData.Scan0;

            // Declare an array to hold the bytes of the bitmap. 
            int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] rgb = gpu.Allocate<byte>(bytes);

            gpu.Launch(new dim3(640), new dim3(640), "GetMas", rgb);
            gpu.CopyFromDevice(rgb, rgbValues);

            // Copy the RGB values back to the bitmap
            System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);

            // Unlock the bits.
            bmp.UnlockBits(bmpData);

            pictureBox1.Image = bmp;
            gpu.FreeAll();
        }

        [Cudafy]
        public static void GetMas(GThread thread, byte[] rgb)
        {
            int x = thread.threadIdx.x;
            int y = thread.blockIdx.x;

            double stepX = Math.Abs(XMAX - XMIN) / SIZE;
            double stepY = Math.Abs(YMAX - YMIN) / SIZE;

            double yc = XMIN + x * stepX;
            double xc = YMIN + y * stepY;
            byte iterations = 0;
            double yTemp1 = yc;
            double xTemp = xc;
            double yTemp2;
            double arg = (yc * yc) + (xc * xc);

            while ((arg < 10000) && (iterations < MAXITER))
            {
                yTemp2 = (yTemp1 * yTemp1) - (xTemp * xTemp) + yc;
                xTemp = (2 * yTemp1 * xTemp) + xc;
                yTemp1 = yTemp2;
                arg = (yTemp1 * yTemp1) + (xTemp * xTemp);
                iterations += 1;
            }

            rgb[y * SIZE * 4 + x * 4] = 0;
            rgb[y * SIZE * 4 + x * 4 + 1] = 0;
            rgb[y * SIZE * 4 + x * 4 + 2] = 0;
            rgb[y * SIZE * 4 + x * 4 + 3] = iterations;
        }
    }
}
...
Рейтинг: 0 / 0
Нужна помощь по работе с CUDA на C#
    #38600144
VIP2020
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот рабочий вариант приложения: http://dropmefiles.com/NCy4v

P.S. У меня приложение не запускается, т.к. видеокарта не NVidia поэтому и прошу прокомментировать.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Нужна помощь по работе с CUDA на C#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]