diff options
| author | JP Appel <jeanpierre.appel01@gmail.com> | 2024-04-24 22:42:26 -0400 |
|---|---|---|
| committer | JP Appel <jeanpierre.appel01@gmail.com> | 2024-04-24 22:42:26 -0400 |
| commit | 787878d6273e4da9572db3d52d841382b02aa210 (patch) | |
| tree | 93a7f7d299fb2adef65090bcfd8ed2872f5e4009 /src | |
| parent | 59cfd01f60c9b5dd7f1a61da80e05dff587792f3 (diff) | |
updated grid serialiation and deserialization
Diffstat (limited to 'src')
| -rw-r--r-- | src/fractals.c | 33 | ||||
| -rw-r--r-- | src/fractals.h | 12 | ||||
| -rw-r--r-- | src/grids.c | 71 | ||||
| -rw-r--r-- | src/grids.h | 5 | ||||
| -rw-r--r-- | src/serial-fractals.c | 18 | ||||
| -rw-r--r-- | src/shared-fractals.c | 18 |
6 files changed, 87 insertions, 70 deletions
diff --git a/src/fractals.c b/src/fractals.c index 556cdb1..1c0c4ea 100644 --- a/src/fractals.c +++ b/src/fractals.c @@ -40,9 +40,8 @@ int main(const int argc, char *argv[]) { CBASE im_upper_right = 2; CBASE magnification = 1; bool verbose = false; - bool print = false; //TODO: allocate adequate size buffer - bool output_to_file = false; + bool output_to_file = true; char* output_filename = "fractal.grid"; // TODO: have output format option @@ -57,7 +56,6 @@ int main(const int argc, char *argv[]) { {"upper-right", required_argument, NULL, 'u'}, {"magnification", required_argument, NULL, 'z'}, {"output", required_argument, NULL, 'o'}, - {"print", no_argument, NULL, 'p'}, {"verbose", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {0, 0, 0, 0} // Termination element @@ -65,7 +63,7 @@ int main(const int argc, char *argv[]) { //parse command line arguments int opt; - while((opt = getopt_long(argc, argv, "i:x:y:l:u:z:o:pvh", long_options, NULL)) != -1){ + while((opt = getopt_long(argc, argv, "i:x:y:l:u:z:o:vh", long_options, NULL)) != -1){ switch(opt){ case 'i': iterations = strtoull(optarg, NULL, 10); @@ -84,11 +82,9 @@ int main(const int argc, char *argv[]) { break; case 'o': //TODO: check if can write to location + output_to_file = true; //TODO: break; - case 'p': - print = true; - break; case 'z': sscanf(optarg, CFORMAT, &magnification); if(magnification <= 0){ @@ -113,7 +109,7 @@ int main(const int argc, char *argv[]) { //const CBASE complex upper_right = re_upper_right + im_upper_right * I; const complex_t upper_right = { .re=re_upper_right, .im=im_upper_right}; - grid_t* grid = create_grid(x_res, y_res, lower_left, upper_right); + grid_t* grid = create_grid(x_res, y_res, iterations, lower_left, upper_right); if(!grid) return 1; @@ -136,22 +132,22 @@ int main(const int argc, char *argv[]) { enum fractal f = JULIA; switch(f){ case MANDELBROT: - mandelbrot_grid(grid, iterations); + mandelbrot_grid(grid); break; case TRICORN: - tricorn_grid(grid, iterations); + tricorn_grid(grid); break; case MULTIBROT: - multibrot_grid(grid, iterations, degree); + multibrot_grid(grid, degree); break; case MULTICORN: - multicorn_grid(grid, iterations, degree); + multicorn_grid(grid, degree); break; case BURNING_SHIP: - burning_ship_grid(grid, iterations); + burning_ship_grid(grid); break; case JULIA: - julia_grid(grid, iterations, constant, radius); + julia_grid(grid, constant, radius); break; default: fprintf(stderr, "Unrecognized fractal\n"); @@ -159,15 +155,18 @@ int main(const int argc, char *argv[]) { } if(verbose)print_grid_info(grid); - if(print)print_grid(grid, iterations); //write grid to file if(output_to_file){ FILE* write_file = fopen("test.grid", "wb"); - write_grid(write_file , grid); + int err = write_grid(write_file , grid); + if(err == GRID_WRITE_ERROR){ + fprintf(stderr, "Error writing occured while writting to file %s\n", output_filename); + } fclose(write_file); } - // + + free_grid(grid); // //attempt to read grid from file // FILE* read_file = fopen("test2.grid", "rb"); // grid_t* grid2 = read_grid(read_file); diff --git a/src/fractals.h b/src/fractals.h index 9c8be71..2262d82 100644 --- a/src/fractals.h +++ b/src/fractals.h @@ -17,19 +17,19 @@ enum fractal { }; size_t mandelbrot(const CBASE complex z0, const size_t max_iterations); -void mandelbrot_grid(grid_t* grid, const size_t max_iterations); +void mandelbrot_grid(grid_t* grid); size_t tricorn(const CBASE complex z0, const size_t max_iterations); -void tricorn_grid(grid_t* grid, const size_t max_iterations); +void tricorn_grid(grid_t* grid); size_t burning_ship(const CBASE complex z0, const size_t max_iterations); -void burning_ship_grid(grid_t* grid, const size_t max_iterations); +void burning_ship_grid(grid_t* grid); size_t multibrot(const CBASE complex z0, const size_t max_iterations, const double d); -void multibrot_grid(grid_t* grid, const size_t max_iterations, const double d); +void multibrot_grid(grid_t* grid, const double d); size_t multicorn(const CBASE complex z0, const size_t max_iterations, const double d); -void multicorn_grid(grid_t* grid, const size_t max_iterations, const double d); +void multicorn_grid(grid_t* grid, const double d); size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_iterations, const double R); -void julia_grid(grid_t* grid, const size_t max_iterations, const complex_t c, const double R); +void julia_grid(grid_t* grid, const complex_t c, const double R); diff --git a/src/grids.c b/src/grids.c index f3c5c17..2bb87e6 100644 --- a/src/grids.c +++ b/src/grids.c @@ -2,6 +2,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <setjmp.h> #include "grids.h" static inline bool equal_complex_t(const complex_t z1, const complex_t z2){ @@ -11,7 +12,7 @@ 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, complex_t lower_left, complex_t upper_right){ +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){ if(x <= 0 || y <= 0) return NULL; const size_t size = x * y; @@ -32,6 +33,7 @@ grid_t* create_grid(const size_t x, const size_t y, complex_t lower_left, comple .x = x, .y = y, .size = x*y, + .max_iterations = max_iterations, .lower_left = lower_left, .upper_right = upper_right, .data = data @@ -55,7 +57,7 @@ void set_grid(grid_t* grid, const size_t val){ grid_t* copy_grid(const grid_t* grid){ if(!grid || !grid->data) return NULL; - grid_t* grid_copy = create_grid(grid->x, grid->y, grid->lower_left, grid->upper_right); + grid_t* grid_copy = create_grid(grid->x, grid->y, grid->max_iterations, grid->lower_left, grid->upper_right); if(!grid_copy) return NULL; memcpy(grid_copy->data, grid->data, grid->size); @@ -84,7 +86,8 @@ bool grid_equal(const grid_t* grid1_p, const grid_t* grid2_p){ const bool lowers_equal = equal_complex_t(grid1.lower_left, grid2.lower_left); const bool uppers_equal = equal_complex_t(grid1.upper_right, grid2.upper_right); const bool dimensions_equal = grid1.x == grid2.x && grid1.y == grid2.y; - return lowers_equal && uppers_equal && dimensions_equal && memcmp(grid1.data, grid2.data, grid1.size) == 0; + return lowers_equal && uppers_equal && grid1.max_iterations == grid2.max_iterations && + dimensions_equal && memcmp(grid1.data, grid2.data, grid1.size) == 0; } /* @@ -136,6 +139,7 @@ CBASE complex grid_to_complex(const grid_t* grid_p, const size_t index) { * Resets all grid values to 0 */ void zoom_grid(grid_t* restrict grid, const CBASE magnification){ + //FIXME: not impelemnted correctly set_grid(grid, 0); // const CBASE complex upper_right = grid->upper_right; const complex_t upper_right = grid->upper_right; @@ -172,8 +176,9 @@ void zoom_grid(grid_t* restrict grid, const CBASE magnification){ * The .grid format is a binary file format * The first 3 bytes of the file are a magic number defined in grids.h * The next 16 bytes are the grid dimensions (x then y) - * The next 2 bytes are the size of a grid point in bytes - * Following are bytes are the bounding of the complex region (lower_left then upper_right) + * The next 8 bytes is the max_iterations + * The next 8 bytes are the size of a grid point in bytes + * The next 2*precision bytes are the lower left and upper right corners * The rest of the file is the data for the grid, which should be exactly x*y*8 bytes */ int write_grid(FILE* restrict file, const grid_t *grid){ @@ -185,16 +190,16 @@ int write_grid(FILE* restrict file, const grid_t *grid){ magic_num[0] = 0xA6; magic_num[1] = 0x00; magic_num[2] = 0x5E; - // for(size_t i = 0; i < 3; i++){ - // magic_num[i] = (GRID_MAGIC_NUMBER >> (2*i)) & 0xFF; - // } + const size_t precision = sizeof(complex_t); if(fwrite(magic_num, 1, 3, file) != 3) return GRID_WRITE_ERROR; if(fwrite(&grid->x, sizeof(size_t), 1, file) != 1 || fwrite(&grid->y, sizeof(size_t), 1, file) != 1 || - fwrite(&grid->lower_left, sizeof(CBASE complex), 1, file) != 1 || - fwrite(&grid->upper_right, sizeof(CBASE complex), 1, file) != 1){ + fwrite(&grid->max_iterations, sizeof(size_t), 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; } @@ -214,9 +219,11 @@ void print_grid_info(const grid_t* grid){ return; } + printf("Precision\t%zu\n", sizeof(CBASE)); 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("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); @@ -226,9 +233,10 @@ void print_grid_info(const grid_t* grid){ /* * Attempts an ASCII print of the grid */ -void print_grid(const grid_t* grid, const size_t iterations){ +void print_grid(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; //TODO: set values in output buffer rather than multiple printf calls @@ -276,6 +284,8 @@ grid_t* read_grid(FILE* restrict file){ unsigned char magic_num[3]; size_t read_count = fread(magic_num, 1, 3, file); + jmp_buf file_read_error; + if(read_count != 3){ perror("Error reading file\n"); return NULL; @@ -285,38 +295,33 @@ grid_t* read_grid(FILE* restrict file){ return NULL; } - size_t x = 0; - size_t y = 0; - read_count = fread(&x, sizeof(size_t), 1, file); - if(read_count != 1){ + if(setjmp(file_read_error)){ perror("Error reading file\n"); return NULL; } - read_count = fread(&y, sizeof(size_t), 1, file); - if(read_count != 1){ - perror("Error reading file\n"); - return NULL; + + size_t x = 0; + size_t y = 0; + size_t 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(&precision, sizeof(size_t), 1, file) != 1){ longjmp(file_read_error, 1) ; } + + if(precision != sizeof(complex_t)){ + fprintf(stderr, "File's precisions does not match programs: %zu != %zu\n", precision, sizeof(complex_t)); + longjmp(file_read_error, 1); } - //FIXME: this will read correctly now complex_t lower_left; complex_t upper_right; - // CBASE complex lower_left = 0; - // CBASE complex upper_right = 0; - read_count = fread(&lower_left, sizeof(CBASE complex), 1, file); - if(read_count != 1){ - perror("Error reading file\n"); - return NULL; - } - read_count = fread(&upper_right, sizeof(CBASE complex), 1, file); - if(read_count != 1){ - perror("Error reading file\n"); - return NULL; - } + if(fread(&lower_left, sizeof(complex_t), 1, file) != 1){ longjmp(file_read_error, 1); } + if(fread(&upper_right, sizeof(complex_t), 1, file) != 1){ longjmp(file_read_error, 1); } //TODO: look into mmaping the file to data, offseting by the bounding and resolution information // this would likely require an alloc_grid function, similar to jeff's implementation in hw03 - grid_t* grid = create_grid(x, y, lower_left, upper_right); + grid_t* grid = create_grid(x, y, max_iterations, lower_left, upper_right); if(!grid){ return NULL; } diff --git a/src/grids.h b/src/grids.h index a66114c..37e5538 100644 --- a/src/grids.h +++ b/src/grids.h @@ -22,12 +22,13 @@ typedef struct { size_t x; size_t y; size_t size; + size_t max_iterations; complex_t lower_left; complex_t upper_right; size_t* data; } grid_t; -grid_t* create_grid(const size_t x, const size_t y, complex_t lower_left, complex_t upper_right); +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* copy_grid(const grid_t* grid); void free_grid(grid_t* grid); @@ -38,6 +39,6 @@ CBASE complex grid_to_complex(const grid_t* grid, const size_t index); void zoom_grid(grid_t* grid, const CBASE magnification); void print_grid_info(const grid_t* grid); -void print_grid(const grid_t* grid, const size_t iterations); +void print_grid(const grid_t* grid); int write_grid(FILE* file, const grid_t* grid); grid_t* read_grid(FILE* file); diff --git a/src/serial-fractals.c b/src/serial-fractals.c index f02f1a3..72fb205 100644 --- a/src/serial-fractals.c +++ b/src/serial-fractals.c @@ -22,8 +22,9 @@ size_t mandelbrot(const CBASE complex z0, const size_t max_iterations) { /* * Fills a grid with mandelbrot values */ -void mandelbrot_grid(grid_t* grid, const size_t max_iterations){ +void mandelbrot_grid(grid_t* grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; for(size_t i = 0; i < size; i++){ @@ -49,8 +50,9 @@ size_t tricorn(const CBASE complex z0, const size_t max_iterations){ /* * Fills a grid with tricorn values */ -void tricorn_grid(grid_t* grid, const size_t max_iterations){ +void tricorn_grid(grid_t* grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; for(size_t i = 0; i < size; i++){ @@ -78,8 +80,9 @@ size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { /* * Fills a grid with burning_ship values */ -void burning_ship_grid(grid_t* grid, const size_t max_iterations){ +void burning_ship_grid(grid_t* grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; for(size_t i = 0; i < size; i++){ @@ -106,8 +109,9 @@ size_t multibrot(const CBASE complex z0, const size_t max_iterations, const doub /* * Fills a grid with multibrot values */ -void multibrot_grid(grid_t* grid, const size_t max_iterations, const double d){ +void multibrot_grid(grid_t* grid, const double d){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; for(size_t i = 0; i < size; i ++){ data[i] = multibrot(grid_to_complex(grid, i), max_iterations, d); @@ -132,8 +136,9 @@ size_t multicorn(const CBASE complex z0, const size_t max_iterations, const doub /* * Fills a grid with multicorn values */ -void multicorn_grid(grid_t* grid, const size_t max_iterations, const double d){ +void multicorn_grid(grid_t* grid, const double d){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; for(size_t i = 0; i < size; i ++){ data[i] = multicorn(grid_to_complex(grid, i), max_iterations, d); @@ -157,8 +162,9 @@ size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_ite return iteration; } -void julia_grid(grid_t* grid, const size_t max_iterations, const complex_t constant, const double R){ +void julia_grid(grid_t* grid, const complex_t constant, const double R){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; const CBASE complex c = constant.re + constant.im * I; size_t* data = grid->data; for(size_t i = 0; i <size; i++){ diff --git a/src/shared-fractals.c b/src/shared-fractals.c index 6cf08e1..836d271 100644 --- a/src/shared-fractals.c +++ b/src/shared-fractals.c @@ -24,8 +24,9 @@ size_t mandelbrot(const CBASE complex z0, const size_t max_iterations){ /* * Fills a grid with mandelbrot values */ -void mandelbrot_grid(grid_t* restrict grid, const size_t max_iterations){ +void mandelbrot_grid(grid_t* restrict grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) @@ -52,8 +53,9 @@ size_t tricorn(const CBASE complex z0, const size_t max_iterations){ /* * Fills a grid with tricorn values */ -void tricorn_grid(grid_t* grid, const size_t max_iterations){ +void tricorn_grid(grid_t* grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) @@ -82,8 +84,9 @@ size_t burning_ship(const CBASE complex z0, const size_t max_iterations) { /* * Fills a grid with burning_ship values */ -void burning_ship_grid(grid_t* grid, const size_t max_iterations){ +void burning_ship_grid(grid_t* grid){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations) schedule(dynamic) @@ -110,8 +113,9 @@ size_t multibrot(const CBASE complex z0, const size_t max_iterations, const doub /* * Fills a grid with multibrot values */ -void multibrot_grid(grid_t* restrict grid, const size_t max_iterations, const double d){ +void multibrot_grid(grid_t* restrict grid, const double d){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations, d) schedule(dynamic) @@ -138,8 +142,9 @@ size_t multicorn(const CBASE complex z0, const size_t max_iterations, const doub /* * Fills a grid with multicorn values */ -void multicorn_grid(grid_t* grid, const size_t max_iterations, const double d){ +void multicorn_grid(grid_t* grid, const double d){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; size_t* 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 ++){ @@ -165,8 +170,9 @@ size_t julia(const CBASE complex z0, const CBASE complex c, const size_t max_ite return iteration; } -void julia_grid(grid_t* restrict grid, const size_t max_iterations, const complex_t constant, const double R){ +void julia_grid(grid_t* restrict grid, const complex_t constant, const double R){ const size_t size = grid->size; + const size_t max_iterations = grid->max_iterations; const CBASE complex c = constant.re + constant.im * I; size_t* data = grid->data; #pragma omp parallel for default(none) shared(data, size, grid, max_iterations, c, R) schedule(dynamic) |
