Created
July 19, 2016 19:24
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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