Меню Закрыть

Занятие 11. Программирование на CUDA. Часть 7. Множество Мандельброта

image_pdfimage_print

Реализация фрактала Множество Мандельброта

В данном примере будет продемонстрировано построение множества Мандельброта на CUDA C с использованием OpenCV (Open Source Computer Vision Library), которая из себя представляет библиотеку алгоритмов компьютерного зрения. В программе будут применяться следующие модули:

opencv_core — основная функциональность. Включает в себя базовые структуры, вычисления (математические функции, генераторы случайных чисел) и линейную алгебру, DFT, DCT, ввод/вывод для XML и YAML и т. д.;

opencv_highgui ввод/вывод изображений и видео.

Подробнее об opencv читайте тут.

Код построения множества Мандельброта:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
 
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
 
using namespace cv;
using namespace std;
 
#define HEIGHT 512 // must be multiple of block_size.y
#define WIDTH 512 // must be multiple of block_size.x
#define MAX_ITER 10000
 
void mandelbrotGPU(char*);
 
__global__ void calc(char* image_buffer);
 
#define cudaAssertSuccess(ans) { _cudaAssertSuccess((ans), __FILE__, __LINE__); }
 
inline void _cudaAssertSuccess(cudaError_t code, char *file, int line)
{
 
if (code != cudaSuccess) {
 
fprintf(stderr,"_cudaAssertSuccess: %s %s %d\n", cudaGetErrorString(code), file, line);
 
exit(code);
}
 
}
 
int main(int argc, char** argv)
{
 
IplImage* image_output = cvCreateImage(cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1);
 
mandelbrotGPU(image_output->imageData);
 
cvShowImage("GPU", image_output);
 
waitKey(0);
 
cvReleaseImage(&image_output);
}
 
void mandelbrotGPU(char* image_buffer)
{
 
char* d_image_buffer;
 
cudaAssertSuccess(cudaMalloc(&d_image_buffer, WIDTH * HEIGHT));
 
dim3 block_size(16, 16);
dim3 grid_size(WIDTH / block_size.x, HEIGHT / block_size.y);
 
calc<<<grid_size, block_size>>>(d_image_buffer);
 
cudaAssertSuccess(cudaPeekAtLastError());
cudaAssertSuccess(cudaDeviceSynchronize());
cudaAssertSuccess(cudaMemcpy(image_buffer, d_image_buffer, HEIGHT * WIDTH, cudaMemcpyDeviceToHost));
 
cudaAssertSuccess(cudaFree(d_image_buffer));
}
 
__global__ void calc(char* image_buffer)
 
{
int row = blockIdx.y * blockDim.y + threadIdx.y; // WIDTH
int col = blockIdx.x * blockDim.x + threadIdx.x; // HEIGHT
int idx = row * WIDTH + col;
if(col >= WIDTH || row >= HEIGHT) return;
 
float x0 = ((float)col / WIDTH) * 3.5f - 2.5f;
float y0 = ((float)row / HEIGHT) * 3.5f - 1.75f;
 
float x = 0.0f;
float y = 0.0f;
 
int iter = 0;
 
float xtemp;
 
while((x * x + y * y <= 4.0f) && (iter < MAX_ITER))
{
 
xtemp = x * x - y * y + x0;
 
y = 2.0f * x * y + y0;
x = xtemp;
 
iter++;
}
 
int color = iter * 5;
if (color >= 256) color = 0;
image_buffer[idx] = color;
 
}

Результат выполнения программы:

Mandelbrot

Связанные записи