Skip to content

Instantly share code, notes, and snippets.

@dmelcer9
Created July 19, 2016 19:24
Show Gist options
  • Save dmelcer9/d3d85feaaae5512e6684b7895113bf60 to your computer and use it in GitHub Desktop.
Save dmelcer9/d3d85feaaae5512e6684b7895113bf60 to your computer and use it in GitHub Desktop.
Generates ASCII art Mandelbrot set using CUDA. Make sure to set your terminal font size as small as possible and adjust the parameters to fit your setup.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdlib.h>
//MAKE SURE TO SET TERMINAL FONT SIZE AS SMALL AS POSSIBLE
#define WIDTH 940 //In chars, adjust to screen
#define HEIGHT 220
#define MINR -2.5 // Min/max x values
#define MAXR 1.0
#define MINI -1.0 // Min/max y values
#define MAXI 1.0
#define MAXITERS 222 //Number of iterations, up to 222
//Leave this alone
#define TPB 32
#define GRIDX ((WIDTH-1)/TPB)+1
#define GRIDY ((HEIGHT-1)/TPB)+1
__global__ void mandlebrot(unsigned int* outputIters)
{
double posx = (blockIdx.x * blockDim.x) + threadIdx.x;//Get global position
double posy = (blockIdx.y * blockDim.y) + threadIdx.y;
if (posx >= WIDTH || posy >= HEIGHT) return;//Array safety
double scalex = (MAXR - MINR) / WIDTH; //Determine scaling
double scaley = (MAXI - MINI) / HEIGHT;
double addr = (scalex*posx) + MINR;
double addi = (scaley*posy) + MINI;
double rval = 0;
double ival = 0;
int iter = 0;
//While MAXITERS hasn't been reached and the magnitude is less than 2
while ((iter <= MAXITERS) && ((rval*rval) + (ival * ival) < 4)){
double newR = (rval*rval) - (ival*ival) + addr;
double newI = (2 * rval*ival) + addi;
rval = newR;
ival = newI;
iter++;
}
unsigned int outputLoc = (posy*WIDTH) + posx;//Determine output position
outputIters[outputLoc] = iter;
}
int main()
{
//Allocate device array
unsigned int* d_output;
cudaMalloc(&d_output, WIDTH*HEIGHT*sizeof(unsigned int));
dim3 gridSz(GRIDX, GRIDY);
dim3 blockSz(TPB, TPB);
//Generate set
mandlebrot<<<gridSz,blockSz>>>(d_output);
//Copy set back over
unsigned int* h_output = (unsigned int*) malloc(WIDTH*HEIGHT*sizeof(unsigned int));
cudaMemcpy(h_output, d_output, HEIGHT*WIDTH*sizeof(unsigned int), cudaMemcpyDeviceToHost);
//Print it out
for (int i = 0; i < (WIDTH*HEIGHT); i++){
printf("%c", (MAXITERS+33)-h_output[i]);
if (i%WIDTH == (WIDTH - 1)) printf("\n");
}
cudaFree(d_output);
free(h_output);
//Pause at end
getchar();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment