Hello !
I’ve a problem with my Mandelbrot program in CUDA, using the SDL library : i’ve always a black window, and never any draw in. I’ve done this program in
C in CPU and it’s works perfectly.
I think the problem is in the kernel, but I can’t find the way to solve it.
So I need some help ! :D
The’re my C program :
[codebox]#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
void fractale (SDL_Surface *screen, SDL_Surface *pixel, SDL_Surface *localisation, TTF_Font *font,
double x, double y, double zoom, int interation);
int main(int argc, char *argv)
{
int continuer = 1, iteration = 80;
double zoom = 1, x = 0, y = 0;
SDL_Event event;
TTF_Font *font = NULL;
SDL_Surface *screen = NULL, *pixel = NULL, *localisation = NULL;
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
screen = SDL_SetVideoMode(640, 640, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
SDL_WM_SetCaption("Fractale de Mandelbrot", NULL);
pixel = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0);
font = TTF_OpenFont("lucon.ttf", 10);
SDL_WarpMouse(screen->w / 2, screen->h / 2);
SDL_ShowCursor(0);
// Appel de la méthode fractale
fractale(screen, pixel, localisation, font, 0, 0, zoom, iteration);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
continuer = 0;
break;
case SDLK_KP5:
fractale(screen, pixel, localisation, font, x, y, zoom, iteration += 30);
break;
case SDLK_KP2:
fractale(screen, pixel, localisation, font, x, y, zoom, iteration -= 30);
break;
case SDLK_KP_PLUS:
fractale(screen, pixel, localisation, font, x, y, zoom += zoom /2, iteration);
break;
case SDLK_KP_MINUS:
fractale(screen, pixel, localisation, font, x, y, zoom -= zoom /2, iteration);
break;
case SDLK_RIGHT:
fractale(screen, pixel, localisation, font, x+=0.2/zoom, y, zoom, iteration);
break;
case SDLK_LEFT:
fractale(screen, pixel, localisation, font, x-=0.2/zoom, y, zoom, iteration);
break;
case SDLK_UP:
fractale(screen, pixel, localisation, font, x, y-=0.2/zoom, zoom, iteration);
break;
case SDLK_DOWN:
fractale(screen, pixel, localisation, font, x, y+=0.2/zoom, zoom, iteration);
break;
default:
break;
}
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_WHEELUP)
fractale(screen, pixel, localisation, font, x, y, zoom += zoom /2, iteration);
else if (event.button.button == SDL_BUTTON_WHEELDOWN)
fractale(screen, pixel, localisation, font, x, y, zoom -= zoom /2, iteration);
break;
}
}
SDL_SaveBMP(screen, "Mandelbrot.bmp");
TTF_CloseFont(font);
TTF_Quit();
SDL_FreeSurface(pixel);
SDL_FreeSurface(localisation);
SDL_Quit();
return EXIT_SUCCESS;
}
void fractale (SDL_Surface *screen, SDL_Surface *pixel, SDL_Surface *localisation, TTF_Font *font,
double x, double y, double zoom, int iteration){
int i, j, n;
double zNa, zNb, copie, zModule2, a, b;
char coordonnees[256] = {0};
SDL_Color couleur = {255, 255, 255};
SDL_Rect position;
for (i = -screen->w / 2; i < screen ->w / 2; i++){
position.x = i + screen->w / 2;
a = 4 * i / ((double)screen->w * zoom) + x;
for (j = -screen->h /2; j < screen->h /2; j++){
n = zNa = zNb = 0;
position.y = j + screen->h / 2;
b = 4 * j / ((double)screen->h * zoom) + y;
if (( -5 < i && i < 5 && j == 0 ) || ( -5 < j && j < 5 && i == 0 ))
SDL_FillRect (pixel, NULL, SDL_MapRGB(pixel->format, 255, 255, 255));
else {
do {
n ++;
copie = zNa;
zNa=zNa*zNa-zNb*zNb+a;
zNb=2*copie*zNb+b;
zModule2=zNa*zNa+zNb*zNb;
}
while (n < iteration && zModule2 <= 4);
if ( n == iteration)
SDL_FillRect (pixel, NULL, SDL_MapRGB(pixel->format, 0, 0, 0));
else
SDL_FillRect (pixel, NULL, SDL_MapRGB(pixel->format, 64*n/iteration, 255*n/iteration, 0));
}
SDL_BlitSurface(pixel, NULL, screen, &position);
}
}
position.x = 10;
position.y = 10;
sprintf(coordonnees, "(%.4f; %.4f)", x, -y);
localisation=TTF_RenderText_Solid(font, coordonnees, couleur);
SDL_BlitSurface(localisation, NULL, screen, &position);
SDL_Flip(screen);
return;
}
[/codebox]
And my CUDA program :
[codebox]#include “cutil_inline.h”
#include <shrUtils.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <cuda.h>
#include <conio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 640
#define SCREEN_BPP 32
#define XBLOCK_SIZE 16
#define YBLOCK_SIZE 16
#define MY_MAPRGB(r,g,b) ((b) + ((g) << 8) + (® << 16))
global void mandelbrot(float *pixelColor, double x, double y, double zoom, int iteration) {
int i = 0, j = 0, n = 0;
double zNa = 0, zNb = 0, copie = 0, zModule2 = 0, constA = 0, constB = 0;
// Thread index
const int tx = threadIdx.x;
const int ty = threadIdx.y;
// Block index
const int bx = blockIdx.x;
const int by = blockIdx.y;
int pt = blockDim.x * blockIdx.x + threadIdx.x;
const int screenX = tx + bx * XBLOCK_SIZE;
const int screenY = ty + by * YBLOCK_SIZE;
__syncthreads();
for (i = -screenX / 2; i < screenX / 2; i++){
x = i + screenX / 2;
constA = 4 * i / ((double)screenX * zoom) + x;
for (j = -screenY /2; j < screenY /2; j++){
n = zNa = zNb = 0;
y = j + screenY / 2;
constB = 4 * j / ((double)screenY * zoom) + y;
if (( -5 < i && i < 5 && j == 0 ) || ( -5 < j && j < 5 && i == 0 ))
pixelColor[pt] = MY_MAPRGB(255, 255, 255);
else {
do {
n ++;
copie = zNa;
zNa=zNa*zNa-zNb*zNb+constA;
zNb=2*copie*zNb+constB;
zModule2=zNa*zNa+zNb*zNb;
}
while (n < iteration && zModule2 <= 4);
if ( n == iteration)
pixelColor[pt] = MY_MAPRGB(0, 0, 0);
else
pixelColor[pt] = MY_MAPRGB(64 *n / iteration, 255 * n / iteration, 255);
}
}
}
x = 10;
y = 10;
__syncthreads();
}
int main( int argc, char** argv){
double zoom = 1, x = 0, y = 0;
int iteration = 80;
int dimA = SCREEN_WIDTH * SCREEN_HEIGHT;
char coordonnees[256] = {0};
int numThreadsPerBlock = 256;
int numBlocks = dimA / numThreadsPerBlock;
size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
float *pixel_h = (float*)malloc(memSize);
float *pixel_d;
cutilSafeCall( cudaMalloc((void **)&pixel_d, memSize) );
for (int i = 0; i < dimA; i++)
pixel_h[i] = 0;
cudaMemcpy( pixel_d, pixel_h, memSize, cudaMemcpyHostToDevice );
int continuer = 1;
SDL_Event event;
SDL_Surface *ecran = NULL, *localisation = NULL, *pixel = NULL;
TTF_Font *font = NULL;
SDL_Color couleur = {255, 255, 255};
SDL_Rect position;
SDL_Init(SDL_INIT_VIDEO);
TTF_Init( );
ecran = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( "Fractale de Mandelbrot", NULL );
font = TTF_OpenFont("lucon.ttf", 10 );
pixel = SDL_CreateRGBSurface(SDL_HWSURFACE, 1, 1, 32, 0, 0, 0, 0);
SDL_WarpMouse(SCREEN_HEIGHT / 2, SCREEN_WIDTH / 2);
dim3 dimGrid(numBlocks);
dim3 dimBlock(numThreadsPerBlock);
mandelbrot <<< dimGrid, dimBlock >>> (pixel_d, x, y, zoom, iteration);
cudaMemcpy( pixel_h, pixel_d, memSize, cudaMemcpyDeviceToHost );
cudaThreadSynchronize();
SDL_FillRect (pixel, NULL, Uint32(pixel_d));
SDL_BlitSurface(pixel, NULL, ecran, &position);
sprintf(coordonnees, "(%.4f; %.4f)", x, -y);
localisation=TTF_RenderText_Solid(font, coordonnees, couleur);
SDL_BlitSurface(localisation, NULL, ecran, &position);
SDL_Flip(ecran);
while (continuer)
{
SDL_WaitEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE:
continuer = 0;
break;
case SDLK_KP5:
iteration +=30;
break;
case SDLK_KP2:
iteration -=30;
break;
case SDLK_KP_PLUS:
zoom += zoom / 2;
break;
case SDLK_KP_MINUS:
zoom -= zoom / 2;
break;
case SDLK_RIGHT:
x += 0.2 / zoom;
break;
case SDLK_LEFT:
x -= 0.2 / zoom;
break;
case SDLK_UP:
y -= 0.2 / zoom;
break;
case SDLK_DOWN:
y += 0.2 / zoom;
break;
default:
break;
}
case SDL_MOUSEBUTTONUP:
if (event.button.button == SDL_BUTTON_WHEELUP)
zoom += zoom / 2;
else if (event.button.button == SDL_BUTTON_WHEELDOWN)
zoom -= zoom / 2;
break;
}
mandelbrot <<< dimGrid, dimBlock >>> (pixel_d, x, y, zoom, iteration);
cudaMemcpy( pixel_h, pixel_d, memSize, cudaMemcpyDeviceToHost );
cudaThreadSynchronize();
sprintf(coordonnees, "(%.4f; %.4f)", x, -y);
localisation=TTF_RenderText_Solid(font, coordonnees, couleur);
SDL_BlitSurface(localisation, NULL, ecran, &position);
SDL_Flip(ecran);
}
SDL_SaveBMP (ecran, "mandelbrot.bmp");
// Libération mémoire et exit
cudaFree(pixel_d);
free(pixel_h);
TTF_CloseFont(font);
TTF_Quit();
SDL_FreeSurface(ecran);
SDL_Quit();
return EXIT_SUCCESS;
}
[/codebox]
Thanks a lot ! :)