diff options
| author | JP Appel <jeanpierre.appel01@gmail.com> | 2024-04-26 16:53:09 -0400 |
|---|---|---|
| committer | JP Appel <jeanpierre.appel01@gmail.com> | 2024-04-26 16:53:09 -0400 |
| commit | 3063b6ffd771f68183e76185761bcbc91110ca0b (patch) | |
| tree | 7342a10069fbaa62e6c260bd9981087709868c09 | |
| parent | aaa64e36cd5ac1cc6077d38505c645f4c316b78e (diff) | |
changed max iterations to byte to allow larger grids
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | src/cuda-fractals.cu | 84 | ||||
| -rw-r--r-- | src/fractals.c | 86 | ||||
| -rw-r--r-- | src/fractals.h | 13 | ||||
| -rw-r--r-- | src/grids.c | 24 | ||||
| -rw-r--r-- | src/grids.h | 13 | ||||
| -rw-r--r-- | src/serial-fractals.c | 48 | ||||
| -rw-r--r-- | src/shared-fractals.c | 48 |
8 files changed, 168 insertions, 151 deletions
@@ -1,6 +1,9 @@ # grid files *.grid +# analysis stuff +analysis/data/* + # Presentation Stuff build/* *.html diff --git a/src/cuda-fractals.cu b/src/cuda-fractals.cu index f6b6e6d..ef94a3f 100644 --- a/src/cuda-fractals.cu +++ b/src/cuda-fractals.cu @@ -49,9 +49,9 @@ thrust::complex<CBASE> grid_to_complex(const thrust::complex<CBASE> lower_left, } __device__ -size_t mandelbrot(const thrust::complex<CBASE> z0, const size_t max_iterations){ +byte mandelbrot(const thrust::complex<CBASE> z0, const byte max_iterations){ thrust::complex<CBASE> z = z0; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= 2 && iteration < max_iterations){ z = z*z + z0; iteration++; @@ -60,7 +60,7 @@ size_t mandelbrot(const thrust::complex<CBASE> z0, const size_t max_iterations){ } __global__ -void mandelbrot_kernel(size_t* grid_data, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void mandelbrot_kernel(byte* grid_data, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -69,9 +69,9 @@ void mandelbrot_kernel(size_t* grid_data, const size_t max_iterations, const thr } __device__ -size_t tricorn(const thrust::complex<CBASE> z0, const size_t max_iterations){ +byte tricorn(const thrust::complex<CBASE> z0, const byte max_iterations){ thrust::complex<CBASE> z = z0; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= 2 && iteration < max_iterations){ z = thrust::conj(z*z) + z0; iteration++; @@ -80,7 +80,7 @@ size_t tricorn(const thrust::complex<CBASE> z0, const size_t max_iterations){ } __global__ -void tricorn_kernel(size_t* grid_data, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void tricorn_kernel(byte* grid_data, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -89,10 +89,10 @@ void tricorn_kernel(size_t* grid_data, const size_t max_iterations, const thrust } __device__ -size_t burning_ship(const thrust::complex<CBASE> z0, const size_t max_iterations){ +byte burning_ship(const thrust::complex<CBASE> z0, const byte max_iterations){ thrust::complex<CBASE> z = z0; thrust::complex<CBASE> z_mod; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= 2 && iteration < max_iterations){ z_mod = thrust::complex<CBASE>(fabs(z.real()), fabs(z.imag())); z = z_mod * z_mod + z0; @@ -102,7 +102,7 @@ size_t burning_ship(const thrust::complex<CBASE> z0, const size_t max_iterations } __global__ -void burning_ship_kernel(size_t* grid_data, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void burning_ship_kernel(byte* grid_data, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -111,9 +111,9 @@ void burning_ship_kernel(size_t* grid_data, const size_t max_iterations, const t } __device__ -size_t multibrot(const thrust::complex<CBASE> z0, const size_t max_iterations, const double d){ +byte multibrot(const thrust::complex<CBASE> z0, const byte max_iterations, const double d){ thrust::complex<CBASE> z = z0; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= 2 && iteration < max_iterations){ z = thrust::pow(z, d) + z0; iteration++; @@ -122,7 +122,7 @@ size_t multibrot(const thrust::complex<CBASE> z0, const size_t max_iterations, c } __global__ -void multibrot_kernel(size_t* grid_data, const double degree, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void multibrot_kernel(byte* grid_data, const double degree, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -131,9 +131,9 @@ void multibrot_kernel(size_t* grid_data, const double degree, const size_t max_i } __device__ -size_t multicorn(const thrust::complex<CBASE> z0, const size_t max_iterations, const double d){ +byte multicorn(const thrust::complex<CBASE> z0, const byte max_iterations, const double d){ thrust::complex<CBASE> z = z0; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= 2 && iteration < max_iterations){ z = thrust::conj(thrust::pow(z, d)) + z0; iteration++; @@ -142,7 +142,7 @@ size_t multicorn(const thrust::complex<CBASE> z0, const size_t max_iterations, c } __global__ -void multicorn_kernel(size_t* grid_data, const double degree, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void multicorn_kernel(byte* grid_data, const double degree, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -151,9 +151,9 @@ void multicorn_kernel(size_t* grid_data, const double degree, const size_t max_i } __device__ -size_t julia(const thrust::complex<CBASE> z0, const size_t max_iterations, const thrust::complex<CBASE> c, const double R){ +byte julia(const thrust::complex<CBASE> z0, const byte max_iterations, const thrust::complex<CBASE> c, const double R){ thrust::complex<CBASE> z = z0; - size_t iteration = 0; + byte iteration = 0; while(thrust::abs(z) <= R && iteration < max_iterations){ z = z*z + c; iteration++; @@ -162,7 +162,7 @@ size_t julia(const thrust::complex<CBASE> z0, const size_t max_iterations, const } __global__ -void julia_kernel(size_t* grid_data, const thrust::complex<CBASE> constant, const double radius, const size_t max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ +void julia_kernel(byte* grid_data, const thrust::complex<CBASE> constant, const double radius, const byte max_iterations, const thrust::complex<CBASE> lower_left, const thrust::complex<CBASE> upper_right, const size_t rows, const size_t cols){ SET_ROW_COL; const auto z = grid_to_complex(lower_left, upper_right, row, col, rows, cols); @@ -175,12 +175,12 @@ void mandelbrot_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); //TODO: find good sizes dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); //dim3 grid_size(0,0); @@ -188,7 +188,7 @@ void mandelbrot_grid(grid_t* grid, const grid_gen_params* params){ mandelbrot_kernel<<<grid_size, block_size>>>(d_grid_data, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); @@ -198,18 +198,18 @@ void tricorn_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); dim3 grid_size((cols + block_size.x - 1) / block_size.x, (rows + block_size.y - 1) / block_size.y); tricorn_kernel<<<grid_size, block_size>>>(d_grid_data, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); @@ -219,18 +219,18 @@ void burning_ship_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); dim3 grid_size((cols + block_size.x - 1) / block_size.x, (rows + block_size.y - 1) / block_size.y); burning_ship_kernel<<<grid_size, block_size>>>(d_grid_data, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); @@ -240,19 +240,19 @@ void multibrot_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; const double degree = params->degree; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); dim3 grid_size((cols + block_size.x - 1) / block_size.x, (rows + block_size.y - 1) / block_size.y); multibrot_kernel<<<grid_size, block_size>>>(d_grid_data, degree, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); @@ -262,19 +262,19 @@ void multicorn_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; const double degree = params->degree; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); dim3 grid_size((cols + block_size.x - 1) / block_size.x, (rows + block_size.y - 1) / block_size.y); multicorn_kernel<<<grid_size, block_size>>>(d_grid_data, degree, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); @@ -286,18 +286,18 @@ void julia_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; const size_t rows = grid->y; const size_t cols = grid->x; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; thrust::complex<CBASE> lower_left(grid->lower_left.re, grid->lower_left.im); thrust::complex<CBASE> upper_right(grid->upper_right.re, grid->upper_right.im); - size_t* d_grid_data; - CHECK(cudaMalloc(&d_grid_data, size*sizeof(size_t))); + byte* d_grid_data; + CHECK(cudaMalloc(&d_grid_data, size*sizeof(byte))); dim3 block_size(BLOCK_SIZE_X, BLOCK_SIZE_Y); dim3 grid_size((cols + block_size.x - 1) / block_size.x, (rows + block_size.y - 1) / block_size.y); julia_kernel<<<grid_size, block_size>>>(d_grid_data, constant, radius, max_iterations, lower_left, upper_right, rows, cols); CHECK(cudaDeviceSynchronize()); - CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(size_t), cudaMemcpyDeviceToHost)); + CHECK(cudaMemcpy(grid->data, d_grid_data, size*sizeof(byte), cudaMemcpyDeviceToHost)); CHECK(cudaFree(d_grid_data)); CHECK(cudaDeviceReset()); diff --git a/src/fractals.c b/src/fractals.c index f994265..80fcc18 100644 --- a/src/fractals.c +++ b/src/fractals.c @@ -22,32 +22,32 @@ void print_usage(FILE* file, const char* program_name){ void print_help(){ printf("Options:\n" - " -i, --iterations <value> the number of iterations (default: 100)\n" - " -x, --x-res <value> the horizontal resolution (default: terminal width)\n" - " -y, --y-res <value> the vertical resolution (default: terminal height)\n" - " -l, --lower-left <value> Set the lower left corner of the fractal area (default: -2.0+-2.0i)\n" - " -u, --upper-right <value> Set the upper right corner of the fractal area (default: 2.0+2.0i)\n" - " -z, --magnification <value> Set the magnification factor (default: 1)\n" - " -d, --degree <value> Set the degree for fractals that use it (default: 1)\n" - " -c, --constant <value> Set the constant for fractals that use it (default: 0+0i)\n" - " -r, --radius <value> Set the radius for fractals that use it (default: 2)\n" - " -o, --output <filename> the output filename (default: fractal.grid)\n" - " -f, --fractal <type> the fractal type (default: mandelbrot)\n" - " supported fractals: mandelbrot, tricorn, multibrot, multicorn, burning_ship, julia\n" - " -p, --performance print performance info\n" - " -v, --verbose verbose output\n" - " -h, --help prints this help message\n" - "\ndegree is mutually exclusive with constant and radius\n" - "\nExits with a status code of 1 if the program encounters an error, exits with 2 if an argument is incorrect\n"); + " -i, --iterations <value> the number of iterations (default: 25, max 255)\n" + " -x, --x-res <value> the horizontal resolution (default: terminal width)\n" + " -y, --y-res <value> the vertical resolution (default: terminal height)\n" + " -l, --lower-left <value> Set the lower left corner of the fractal area (default: -2.0+-2.0i)\n" + " -u, --upper-right <value> Set the upper right corner of the fractal area (default: 2.0+2.0i)\n" + " -z, --magnification <value> Set the magnification factor (default: 1)\n" + " -d, --degree <value> Set the degree for fractals that use it (default: 1)\n" + " -c, --constant <value> Set the constant for fractals that use it (default: 0+0i)\n" + " -r, --radius <value> Set the radius for fractals that use it (default: 2)\n" + " -o, --output <filename> the output filename (default: fractal.grid)\n" + " -f, --fractal <type> the fractal type (default: mandelbrot)\n" + " supported fractals: mandelbrot, tricorn, multibrot, multicorn, burning_ship, julia\n" + " -p, --performance print performance info\n" + " -v, --verbose verbose output\n" + " -h, --help prints this help message\n" + "\ndegree is mutually exclusive with constant and radius\n" + "\nExits with a status code of 1 if the program encounters an error, exits with 2 if an argument is incorrect\n"); } void print_info(const char* program_name){ - #ifdef EXTENDED_PRECISION +#ifdef EXTENDED_PRECISION printf("Compiled with long double float precision\n"); - #endif - #ifndef EXTENDED_PRECISION +#endif +#ifndef EXTENDED_PRECISION printf("%s complied with double float precision\n", program_name); - #endif +#endif } double time_fractal(fractal_generator generator, grid_t* grid, grid_gen_params* params){ @@ -72,7 +72,7 @@ int main(const int argc, char *argv[]) { ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); //default values - size_t iterations = 100; + byte iterations = 25; size_t x_res = w.ws_col; size_t y_res = w.ws_row; complex_t lower_left = { .re = -2, .im = -2}; @@ -116,12 +116,20 @@ int main(const int argc, char *argv[]) { {0, 0, 0, 0} // Termination element }; + unsigned long temp; //parse command line arguments int opt; while((opt = getopt_long(argc, argv, "i:x:y:l:u:z:d:c:r:o:vphf:", long_options, NULL)) != -1){ switch(opt){ case 'i': - iterations = strtoull(optarg, NULL, 10); + temp = strtoul(optarg, NULL, 10); + if(temp > 255){ + fprintf(stderr, "Iterations above maximum, setting to 255\n"); + iterations = 255; + } + else { + iterations = temp; + } break; case 'x': x_res = strtoull(optarg, NULL, 10); @@ -256,7 +264,7 @@ int main(const int argc, char *argv[]) { if(performance){ double time = time_fractal(generator, grid, params); - printf("%s,%s,%zu,%zu,%zu," + printf("%s,%s,%hhu,%zu,%zu," CFORMAT","CFORMAT","CFORMAT","CFORMAT",%f\n", argv[0], fractal_name, iterations, x_res, y_res, lower_left.re, lower_left.im, upper_right.re, upper_right.im, time); @@ -268,22 +276,24 @@ int main(const int argc, char *argv[]) { print_grid_info(grid); } - //use "safer" versions of c string functions - //likely aren't necessary unless a user can pass non-null terminated strings as arguments, but that would likely break something up in getopt - if(output_filename[0] == '-' && strnlen(output_filename, 16) == 1){ - if(write_grid(stdout, grid) == GRID_WRITE_ERROR){ - fprintf(stderr, "Error occured while writting to file %s\n", output_filename); - } - } - else { - FILE* file = fopen(output_filename, "wb"); - if(!file){ - perror("Error occured while trying to write"); + if(!performance){ + //uses "safer" versions of c string functions + //likely aren't necessary unless a user can pass non-null terminated strings as arguments, but that would likely break something up in getopt + if(output_filename[0] == '-' && strnlen(output_filename, 16) == 1){ + if(write_grid(stdout, grid) == GRID_WRITE_ERROR){ + fprintf(stderr, "Error occured while writting to file %s\n", output_filename); + } } - else if(write_grid(file, grid) == GRID_WRITE_ERROR){ - fprintf(stderr, "Error occured while writting to file %s\n", output_filename); + else { + FILE* file = fopen(output_filename, "wb"); + if(!file){ + perror("Error occured while trying to write"); + } + else if(write_grid(file, grid) == GRID_WRITE_ERROR){ + fprintf(stderr, "Error occured while writting to file %s\n", output_filename); + } + fclose(file); } - fclose(file); } free(params); diff --git a/src/fractals.h b/src/fractals.h index 1c745d9..b31b15f 100644 --- a/src/fractals.h +++ b/src/fractals.h @@ -1,5 +1,6 @@ #pragma once +#include <stdint.h> #ifndef __NVCC__ #include <complex.h> #endif @@ -18,12 +19,12 @@ typedef union { typedef void (*fractal_generator)(grid_t* , const grid_gen_params* ); #ifndef __NVCC__ -size_t mandelbrot(const CBASE complex z0, const size_t max_iterations); -size_t tricorn(const CBASE complex z0, const size_t max_iterations); -size_t burning_ship(const CBASE complex z0, const size_t max_iterations); -size_t multibrot(const CBASE complex z0, const size_t max_iterations, const double d); -size_t multicorn(const CBASE complex z0, const size_t max_iterations, const double d); -size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_iterations, const double R); +byte mandelbrot(const CBASE complex z0, const byte max_iterations); +byte tricorn(const CBASE complex z0, const byte max_iterations); +byte burning_ship(const CBASE complex z0, const byte max_iterations); +byte multibrot(const CBASE complex z0, const byte max_iterations, const double d); +byte multicorn(const CBASE complex z0, const byte max_iterations, const double d); +byte julia(const CBASE complex z0, const CBASE complex c, const byte max_iterations, const double R); #endif #ifdef __cplusplus diff --git a/src/grids.c b/src/grids.c index 97bb894..e65ba79 100644 --- a/src/grids.c +++ b/src/grids.c @@ -12,11 +12,11 @@ static inline bool equal_complex_t(const complex_t z1, const complex_t z2){ /* * Creates a grid for storing the results of the escape algorithm */ -grid_t* create_grid(const size_t x, const size_t y, const size_t max_iterations, complex_t lower_left, complex_t upper_right){ +grid_t* create_grid(const size_t x, const size_t y, const byte max_iterations, complex_t lower_left, complex_t upper_right){ if(x <= 0 || y <= 0) return NULL; const size_t size = x * y; - size_t* data = malloc(size * sizeof(size_t)); + byte* data = malloc(size); if(!data){ fprintf(stderr, "Error allocating %zu grid points for grid\n", size); return NULL; @@ -46,7 +46,7 @@ grid_t* create_grid(const size_t x, const size_t y, const size_t max_iterations, /* * Sets all entries of a grid to the value val */ -void set_grid(grid_t* grid, const size_t val){ +void set_grid(grid_t* grid, const byte val){ if(!grid || !grid->data) return; memset(grid->data, val, grid->size); } @@ -93,7 +93,7 @@ bool grid_equal(const grid_t* grid1_p, const grid_t* grid2_p){ /* * Checks if two grids have a given maximum difference */ -bool grid_allclose(const grid_t* restrict grid1, const grid_t* restrict grid2, const size_t max_error){ +bool grid_allclose(const grid_t* restrict grid1, const grid_t* restrict grid2, const byte max_error){ if(grid1->x != grid2->x || grid1->y != grid2->y || !equal_complex_t(grid1->lower_left, grid2->lower_left) || !equal_complex_t(grid1->upper_right, grid2->upper_right)){ @@ -196,14 +196,14 @@ int write_grid(FILE* restrict file, const grid_t *grid){ if(fwrite(&grid->x, sizeof(size_t), 1, file) != 1 || fwrite(&grid->y, sizeof(size_t), 1, file) != 1 || - fwrite(&grid->max_iterations, sizeof(size_t), 1, file) != 1 || + fwrite(&grid->max_iterations, sizeof(byte), 1, file) != 1 || fwrite(&precision, sizeof(size_t), 1, file) != 1 || fwrite(&grid->lower_left, precision, 1, file) != 1 || fwrite(&grid->upper_right, precision, 1, file) != 1){ return GRID_WRITE_ERROR; } - if(fwrite(grid->data, sizeof(size_t), grid->size, file) != grid->size){ + if(fwrite(grid->data, 1, grid->size, file) != grid->size){ return GRID_WRITE_ERROR; } @@ -223,7 +223,7 @@ void print_grid_info(const grid_t* grid){ printf("x\t%zu\n", grid->x); printf("y\t%zu\n", grid->y); printf("size\t%zu\n", grid->size); - printf("Max Iterations\t%zu\n", grid->max_iterations); + printf("Max Iterations\t%hhu\n", grid->max_iterations); printf("lower_left\t"CFORMAT"+ "CFORMAT"I\n", grid->lower_left.re, grid->lower_left.im); printf("upper_right\t"CFORMAT"+ "CFORMAT"I\n", grid->upper_right.re, grid->upper_right.im); @@ -236,8 +236,8 @@ void print_grid_info(const grid_t* grid){ void print_grid(FILE* file, const grid_t* grid){ const size_t size = grid->size; const size_t x_res = grid->x; - const size_t iterations = grid->max_iterations; - const size_t* data = grid->data; + const byte iterations = grid->max_iterations; + const byte* data = grid->data; //TODO: set values in output buffer rather than multiple printf calls // the buffer needs to be larger to hold newlines @@ -306,11 +306,11 @@ grid_t* read_grid(FILE* restrict file){ size_t x = 0; size_t y = 0; - size_t max_iterations = 0; + byte max_iterations = 0; size_t precision = 0; if(fread(&x, sizeof(size_t), 1, file) != 1){ longjmp(file_read_error, 1); } if(fread(&y, sizeof(size_t), 1, file) != 1){ longjmp(file_read_error, 1); } - if(fread(&max_iterations, sizeof(size_t), 1, file) != 1){ longjmp(file_read_error, 1); } + if(fread(&max_iterations, sizeof(byte), 1, file) != 1){ longjmp(file_read_error, 1); } if(fread(&precision, sizeof(size_t), 1, file) != 1){ longjmp(file_read_error, 1) ; } if(precision != sizeof(complex_t)){ @@ -330,7 +330,7 @@ grid_t* read_grid(FILE* restrict file){ return NULL; } - read_count = fread(grid->data, sizeof(size_t), grid->size, file); + read_count = fread(grid->data, 1, grid->size, file); if(read_count != grid->size){ fprintf(stderr, "Error reading file, expected %zu grid points but only found %zu\n", grid->size, read_count); free_grid(grid); diff --git a/src/grids.h b/src/grids.h index 293ceb5..6bf96f4 100644 --- a/src/grids.h +++ b/src/grids.h @@ -20,22 +20,25 @@ typedef struct { CBASE im; } complex_t; +typedef unsigned char byte; + typedef struct { size_t x; size_t y; size_t size; - size_t max_iterations; + byte max_iterations; complex_t lower_left; complex_t upper_right; - size_t* data; + byte* data; } grid_t; -grid_t* create_grid(const size_t x, const size_t y, const size_t max_iterations, complex_t lower_left, complex_t upper_right); -void set_grid(grid_t* grid, const size_t val); +grid_t* create_grid(const size_t x, const size_t y, const byte max_iterations, complex_t lower_left, complex_t upper_right); +void set_grid(grid_t* grid, const byte val); grid_t* copy_grid(const grid_t* grid); void free_grid(grid_t* grid); bool grid_equal(const grid_t* grid1, const grid_t* grid2); -bool grid_allclose(const grid_t* grid1, const grid_t* grid2, const size_t max_error); +// not useful +bool grid_allclose(const grid_t* grid1, const grid_t* grid2, const byte max_error); #ifndef __NVCC__ CBASE complex grid_to_complex(const grid_t* grid, const size_t index); diff --git a/src/serial-fractals.c b/src/serial-fractals.c index ee55b3b..fd16b00 100644 --- a/src/serial-fractals.c +++ b/src/serial-fractals.c @@ -8,9 +8,9 @@ * if the return value is equal to max_iterations, the point lies within the mandelbrot set * This is an implementation the escape algorithm */ -size_t mandelbrot(const CBASE complex z0, const size_t max_iterations) { +byte mandelbrot(const CBASE complex z0, const byte max_iterations) { CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while (CABS(z) <= 2 && iteration < max_iterations) { z = z * z + z0; @@ -24,8 +24,8 @@ size_t mandelbrot(const CBASE complex z0, const size_t max_iterations) { */ void mandelbrot_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; for(size_t i = 0; i < size; i++){ data[i] = mandelbrot(grid_to_complex(grid, i), max_iterations); @@ -37,9 +37,9 @@ void mandelbrot_grid(grid_t* grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the tricorn set * This is nearly identical to mandelbrot, except for the complex conjugate */ -size_t tricorn(const CBASE complex z0, const size_t max_iterations){ +byte tricorn(const CBASE complex z0, const byte max_iterations){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CONJ(z * z) + z0; iteration++; @@ -52,8 +52,8 @@ size_t tricorn(const CBASE complex z0, const size_t max_iterations){ */ void tricorn_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; for(size_t i = 0; i < size; i++){ data[i] = tricorn(grid_to_complex(grid, i), max_iterations); @@ -64,10 +64,10 @@ void tricorn_grid(grid_t* grid, const grid_gen_params* params){ * Computes the number of iterations it takes for a point z0 to become unbounded * if the return value is equal to max_iterations, the point lies within the burningship set (oh no! I hope they have fire safety gear) */ -size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { +byte burning_ship(const CBASE complex z0, const byte max_iterations) { CBASE complex z = z0; CBASE complex z_mod; - size_t iteration = 0; + byte iteration = 0; while (CABS(z) <= 2 && iteration < max_iterations) { z_mod = RABS(CREAL(z)) + RABS(CIMAG(z))*I; @@ -82,8 +82,8 @@ size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { */ void burning_ship_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; for(size_t i = 0; i < size; i++){ data[i] = burning_ship(grid_to_complex(grid, i), max_iterations); @@ -95,9 +95,9 @@ void burning_ship_grid(grid_t* grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the multibrot set * This is implementation closely matches mandelbrot, but uses cpow which might degrade performance. */ -size_t multibrot(const CBASE complex z0, const size_t max_iterations, const double d){ +byte multibrot(const CBASE complex z0, const byte max_iterations, const double d){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CPOW(z, d) + z0; iteration++; @@ -112,8 +112,8 @@ size_t multibrot(const CBASE complex z0, const size_t max_iterations, const doub void multibrot_grid(grid_t* grid, const grid_gen_params* params){ const double d = params->degree; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; for(size_t i = 0; i < size; i ++){ data[i] = multibrot(grid_to_complex(grid, i), max_iterations, d); } @@ -124,9 +124,9 @@ void multibrot_grid(grid_t* grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the multicorn set * This function is to tricorn as multibrot is to mandelbrot */ -size_t multicorn(const CBASE complex z0, const size_t max_iterations, const double d){ +byte multicorn(const CBASE complex z0, const byte max_iterations, const double d){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CONJ(CPOW(z, d)) + z0; iteration++; @@ -140,8 +140,8 @@ size_t multicorn(const CBASE complex z0, const size_t max_iterations, const doub void multicorn_grid(grid_t* grid, const grid_gen_params* params){ const double d = params->degree; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; for(size_t i = 0; i < size; i ++){ data[i] = multicorn(grid_to_complex(grid, i), max_iterations, d); } @@ -153,10 +153,10 @@ void multicorn_grid(grid_t* grid, const grid_gen_params* params){ * * This behaves weirdly, needs a very small number of iterations to be visibile */ -size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_iterations, const double R){ +byte julia(const CBASE complex z0, const CBASE complex c, const byte max_iterations, const double R){ double complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) < R && iteration < max_iterations){ z = z * z + c; iteration++; @@ -168,9 +168,9 @@ void julia_grid(grid_t* grid, const grid_gen_params* params){ const complex_t constant = params->cr.constant; const double radius = params->cr.radius; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; const CBASE complex c = constant.re + constant.im * I; - size_t* data = grid->data; + byte* data = grid->data; for(size_t i = 0; i <size; i++){ data[i] = julia(grid_to_complex(grid, i), c, max_iterations, radius); } diff --git a/src/shared-fractals.c b/src/shared-fractals.c index a45d366..5e54a9a 100644 --- a/src/shared-fractals.c +++ b/src/shared-fractals.c @@ -10,9 +10,9 @@ * if the return value is equal to max_iterations, the point lies within the mandelbrot set * This should be identical to the version found in serial-fractals.c */ -size_t mandelbrot(const CBASE complex z0, const size_t max_iterations){ +byte mandelbrot(const CBASE complex z0, const byte max_iterations){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = z*z + z0; iteration++; @@ -26,8 +26,8 @@ size_t mandelbrot(const CBASE complex z0, const size_t max_iterations){ */ void mandelbrot_grid(grid_t* restrict grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) for(size_t i = 0; i < size; i++){ @@ -40,9 +40,9 @@ void mandelbrot_grid(grid_t* restrict grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the tricorn set * This is nearly identical to mandelbrot, except for the complex conjugate */ -size_t tricorn(const CBASE complex z0, const size_t max_iterations){ +byte tricorn(const CBASE complex z0, const byte max_iterations){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CONJ(z * z) + z0; iteration++; @@ -55,8 +55,8 @@ size_t tricorn(const CBASE complex z0, const size_t max_iterations){ */ void tricorn_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) for(size_t i = 0; i < size; i++){ @@ -68,10 +68,10 @@ void tricorn_grid(grid_t* grid, const grid_gen_params* params){ * Computes the number of iterations it takes for a point z0 to become unbounded * if the return value is equal to max_iterations, the point lies within the burningship set (oh no! I hope they have fire safety gear) */ -size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { +byte burning_ship(const CBASE complex z0, const byte max_iterations) { CBASE complex z = z0; CBASE complex z_mod; - size_t iteration = 0; + byte iteration = 0; while (CABS(z) <= 2 && iteration < max_iterations) { z_mod = RABS(CREAL(z)) + RABS(CIMAG(z))*I; @@ -86,8 +86,8 @@ size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { */ void burning_ship_grid(grid_t* grid, const grid_gen_params* params){ const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) for(size_t i = 0; i < size; i++){ @@ -100,9 +100,9 @@ void burning_ship_grid(grid_t* grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the multibrot set * This should be identical to the version found in serial-fractals.c */ -size_t multibrot(const CBASE complex z0, const size_t max_iterations, const double d){ +byte multibrot(const CBASE complex z0, const byte max_iterations, const double d){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CPOW(z, d) + z0; iteration++; @@ -116,8 +116,8 @@ size_t multibrot(const CBASE complex z0, const size_t max_iterations, const doub void multibrot_grid(grid_t* restrict grid, const grid_gen_params* params){ const double d = params->degree; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations, d) schedule(dynamic) for(size_t i = 0; i < size; i ++){ @@ -130,9 +130,9 @@ void multibrot_grid(grid_t* restrict grid, const grid_gen_params* params){ * if the return value is equal to max_iterations, the point lies within the multicorn set * This function is to tricorn as multibrot is to mandelbrot */ -size_t multicorn(const CBASE complex z0, const size_t max_iterations, const double d){ +byte multicorn(const CBASE complex z0, const byte max_iterations, const double d){ CBASE complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) <= 2 && iteration < max_iterations){ z = CONJ(CPOW(z, d)) + z0; iteration++; @@ -146,8 +146,8 @@ size_t multicorn(const CBASE complex z0, const size_t max_iterations, const doub void multicorn_grid(grid_t* grid, const grid_gen_params* params){ const double d = params->degree; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; - size_t* data = grid->data; + const byte max_iterations = grid->max_iterations; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations, d) schedule(dynamic) for(size_t i = 0; i < size; i ++){ data[i] = multicorn(grid_to_complex(grid, i), max_iterations, d); @@ -161,10 +161,10 @@ void multicorn_grid(grid_t* grid, const grid_gen_params* params){ * This behaves weirdly, needs a very small number of iterations to be visibile */ -size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_iterations, const double R){ +byte julia(const CBASE complex z0, const CBASE complex c, const byte max_iterations, const double R){ double complex z = z0; - size_t iteration = 0; + byte iteration = 0; while(CABS(z) < R && iteration < max_iterations){ z = z * z + c; iteration++; @@ -176,9 +176,9 @@ void julia_grid(grid_t* grid, const grid_gen_params* params){ const complex_t constant = params->cr.constant; const double radius = params->cr.radius; const size_t size = grid->size; - const size_t max_iterations = grid->max_iterations; + const byte max_iterations = grid->max_iterations; const CBASE complex c = constant.re + constant.im * I; - size_t* data = grid->data; + byte* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations, c, radius) schedule(dynamic) for(size_t i = 0; i < size; i++){ data[i] = julia(grid_to_complex(grid, i), c, max_iterations, radius); |
