aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorJP Appel <jeanpierre.appel01@gmail.com>2024-04-24 22:42:26 -0400
committerJP Appel <jeanpierre.appel01@gmail.com>2024-04-24 22:42:26 -0400
commit787878d6273e4da9572db3d52d841382b02aa210 (patch)
tree93a7f7d299fb2adef65090bcfd8ed2872f5e4009
parent59cfd01f60c9b5dd7f1a61da80e05dff587792f3 (diff)
updated grid serialiation and deserialization
-rw-r--r--src/fractals.c33
-rw-r--r--src/fractals.h12
-rw-r--r--src/grids.c71
-rw-r--r--src/grids.h5
-rw-r--r--src/serial-fractals.c18
-rw-r--r--src/shared-fractals.c18
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)