Loading OpenMP/exercises/Mandelbrot/mandelbrot.omp.c→OpenMP/exercises/Mandelbrot/.backups/mandelbrot.omp.c.pre_split +55 −95 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot.omp.c.pre_split: 55 added lines, 95 removed lines. Original line number Diff line number Diff line Loading @@ -133,6 +133,9 @@ print_usage (char *program_name // executable name from argv[0] " --dx-factor VALUE accepted for interface compatibility (%u)\n" " --dy-factor VALUE number of serial horizontal work stripes (%u)\n" " --kmax VALUE maximum Mandelbrot iteration count (%u)\n" " --mode VALUE 0: omp for schedule(static)\n" " n > 0: omp for schedule(static,n)\n" " n < 0: omp for schedule(dynamic, -n)\n" " --output FILE output PNG file (%s)\n" " --help show this help message\n" "\n" Loading Loading @@ -239,11 +242,16 @@ parse_unsigned_option ( int argc, // number of command-line tokens return 0; } /* Parse an integer option of the form "--name value". It is used for ppu, factors, and kmax. */ static int parse_positive_option ( int argc, // number of command-line tokens char **argv, // command-line token vector int *i, // index of the option currently being parsed unsigned int *value // destination for the parsed integer value int *value // destination for the parsed integer value ) { char *endptr; Loading @@ -260,19 +268,54 @@ parse_positive_option ( int argc, // number of command-line tokens parsed = strtoul (argv[*i + 1], &endptr, 10); if (errno != 0 || endptr == argv[*i + 1] || *endptr != '\0' || parsed < 0 || parsed > UINT_MAX) || parsed > 1) { fprintf (stderr, "Invalid integer value for %s: %s\n", argv[*i], argv[*i + 1]); return -1; } *value = (unsigned int) parsed; *value = (int) parsed; *i += 1; return 0; } static int parse_string_option ( int argc, // number of command-line tokens char **argv, // command-line token vector int *i, // index of the option currently being parsed int *value // destination for the parsed integer value ) { if (*i + 1 >= argc) { fprintf (stderr, "Missing value after %s\n", argv[*i]); return -1; } // get the strlen int len = strlen( argv[*i+1] ); // convert on lower case for ( int c = 0; c < len; c++ ) argv[*i+1]+c = lower(argv[*i+1]+c); // compare with admissible values if ( strncmp( "pgm", argv[*i+1], 3 ) == 0 ) *value = _MANDEL_PGM_; else if ( strncmp( "png", argv[*i+1], 3 ) == 0 ) *value = _MANDEL_PNG_; else *value = _MANDEL_FORMAT_ERR_ *i += 1; return 0; } /* Parse all command-line options. */ Loading Loading @@ -542,86 +585,6 @@ colour_from_iteration (unsigned int iteration, // escape iteration count rgb[2] = (unsigned char) (255.0 * 8.5 * one_minus_t * one_minus_t * one_minus_t * t); } /* Render a contiguous horizontal range of rows. This is a serial version of the stripe unit used in Track A: it is a simple implementation, but this function makes the future producer-consumer decomposition almost there. */ static void render_stripe (options_t *options, // view and iteration options image_geometry_t *geometry, // image dimensions and pixel spacing unsigned int row_begin, // first row included in this stripe unsigned int row_end, // first row after this stripe unsigned char *image, // complete row-major RGB image buffer render_stats_t *stats // diagnostics accumulated over the image ) { uint64_t local_checksum; uint64_t local_total_iterations; uint64_t local_inside_pixels; local_checksum = stats->checksum; local_total_iterations = stats->total_iterations; local_inside_pixels = stats->inside_pixels; for (unsigned int row = row_begin; row < row_end; ++row) { // Row zero is the top of the image, hence the minus sign from ymax. double ci = options->ymax - ((double) row + 0.5) * geometry->dy; for (unsigned col = 0; col < geometry->width; ++col) { double cr = options->xmin + ((double) col + 0.5) * geometry->dx; unsigned int iteration = mandelbrot_escape (cr, ci, options->kmax); size_t pixel_offset = ((size_t) row * (size_t) geometry->width + (size_t) col) * 3u; colour_from_iteration (iteration, options->kmax, &image[pixel_offset]); local_checksum = checksum_update_uint (local_checksum, iteration); local_total_iterations += (uint64_t) iteration; if (iteration >= options->kmax) local_inside_pixels += 1u; } } stats->checksum = local_checksum; stats->total_iterations = local_total_iterations; stats->inside_pixels = local_inside_pixels; } /* Render the full image by visiting dy_factor horizontal stripes in order. */ static void render_image_bystripes (options_t *options, // view, factors, and kmax image_geometry_t *geometry, // image dimensions and pixel spacing unsigned char *image, // complete row-major RGB image buffer render_stats_t *stats // output diagnostics ) { unsigned int stripe; unsigned int row_begin; unsigned int row_end; stats->checksum = FNV_OFFSET_BASIS; stats->total_iterations = 0u; stats->inside_pixels = 0u; for (stripe = 0; stripe < options->dy_factor; ++stripe) { row_begin = (unsigned int) (((uint64_t) stripe * geometry->height) / options->dy_factor); row_end = (unsigned int) (((uint64_t) (stripe + 1u) * geometry->height) / options->dy_factor); if (row_begin < row_end) render_stripe (options, geometry, row_begin, row_end, image, stats); } } static void render_image (options_t *options, // view, factors, and kmax Loading Loading @@ -658,23 +621,24 @@ render_image (options_t *options, // view, factors, and kmax double mytime = CPU_TIME_T; double my_calc_time = 0; if ( options->mode == 1) if ( options->mode == 0) { sprintf( schedule_type, "static, max chunk" ); #pragma omp for nowait #include "loop.h" #include "mandelbrot_loop.h" } else if (options->mode == 2) else if (options->mode > 0) { sprintf( schedule_type, "static, 1-line chunk" ); #pragma omp for schedule(static, 1) nowait #include "loop.h" sprintf( schedule_type, "static, %d-line chunk", options->mode); #pragma omp for schedule(static, options->mode) nowait #include "mandelbrot_loop.h" } else { options->mode *= -1; sprintf( schedule_type, "dynamic, %d points chunk", options->mode ); #pragma omp for collapse(2) schedule(dynamic, options->mode) nowait #include "loop.h" #include "mandelbrot_loop.h" } mytime = CPU_TIME_T - mytime; Loading Loading @@ -847,17 +811,13 @@ main (int argc, // number of command-line tokens "this serial stripe baseline does not use it.\n"); } if ( options.mode == 0 ) render_image_bystripes (&options, &geometry, image, &stats); else { #if defined(PROFILE) timage = (unsigned char *) malloc (image_bytes); render_image (&options, &geometry, image, timage); #else render_image (&options, &geometry, image); #endif } if (write_ppm_image (image, geometry.width, geometry.height, options.output_path) != 0) { Loading OpenMP/exercises/Mandelbrot/mandelbrot_serial--with_png_output.c→OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial--with_png_output.c.pre_stb_fix +0 −0 File moved. View file OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial--with_png_output.c.retired 0 → 100644 +688 −0 File added.Preview size limit exceeded, changes collapsed. Show changes OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.c.pre_fix 0 → 100644 +248 −0 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.c.pre_fix: 248 added lines, 0 removed lines. Original line number Diff line number Diff line /* ────────────────────────────────────────────────────────────────────────── * │ │ │ This file is part of the exercises for the Lectures on │ │ "Foundations of High Performance Computing" │ │ given at │ │ Master in HPC and │ │ Master in Data Science and Scientific Computing │ │ @ SISSA, ICTP and University of Trieste │ │ │ │ contact: luca.tornatore@inaf.it │ │ │ │ This is free software; you can redistribute it and/or modify │ │ it under the terms of the GNU General Public License as published by │ │ the Free Software Foundation; either version 3 of the License, or │ │ (at your option) any later version. │ │ This code is distributed in the hope that it will be useful, │ │ but WITHOUT ANY WARRANTY; without even the implied warranty of │ │ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the │ │ GNU General Public License for more details. │ │ │ │ You should have received a copy of the GNU General Public License │ │ along with this program. If not, see <http://www.gnu.org/licenses/> │ │ │ * ────────────────────────────────────────────────────────────────────────── */ /* Serial Mandelbrot renderer for the HPC final-exam exercise. This file is a clean serial baseline, whose goal is to give a correct and readable starting point from which introduce MPI work dispatch, OpenMP scheduling, optimization experiments, and different tile granularities. The program implements a command-line parsing, computes every pixel by direct iteration, stores the image in a row-major RGB buffer, and writes either a PGM file through a tiny PGM writer, or a png file using the stb header. Have fun. */ #include "mandelbrot_serial.h" /* ======================================================================================== : ------------------------------------------------------ : : CALCULATION FUNCTIONS : : ------------------------------------------------------ : */ /* Compute the Mandelbrot escape iteration for one point c = cr + i ci. This is the direct scalar kernel, clean, keeps the operation count easy to read. This can be heavility optimized. */ static unsigned int mandelbrot_escape (double cr, // real part of the pixel centre double ci, // imaginary part of the pixel centre unsigned int kmax // maximum number of iterations ) { double zr; double zi; double zr_next; double zr2; double zi2; unsigned int k; zr = 0.0; zi = 0.0; k = 0; while (k < kmax) { zr2 = zr * zr; zi2 = zi * zi; if (zr2 + zi2 > 4.0) break; zr_next = zr2 - zi2 + cr; zi = 2.0 * zr * zi + ci; zr = zr_next; k += 1; } return k; } /* Map one iteration count to an RGB colour. Interior points are black. The outside palette is deliberately simple. It might be fun experimenting by advanced colouring or smooth-potential formulas. Don't be distracted by this, though */ static void colour_from_iteration (unsigned int iteration, // escape iteration count unsigned int kmax, // maximum iteration count unsigned char *rgb // output triplet: red, green, blue ) { double t; double one_minus_t; if (iteration >= kmax) { rgb[0] = 0u; rgb[1] = 0u; rgb[2] = 0u; return; } t = (double) iteration / (double) kmax; one_minus_t = 1.0 - t; rgb[0] = (unsigned char) (255.0 * 9.0 * one_minus_t * t * t * t); rgb[1] = (unsigned char) (255.0 * 15.0 * one_minus_t * one_minus_t * t * t); rgb[2] = (unsigned char) (255.0 * 8.5 * one_minus_t * one_minus_t * one_minus_t * t); } static void render_image (options_t *options, // view, factors, and kmax image_geometry_t *geometry, // image dimensions and pixel spacing unsigned char *image // complete row-major RGB image buffer ) { uint64_t Nrows = geometry->height; uint64_t Ncols = geometry->width; for ( int row = 0; row < Nrows; row++ ) for ( int col = 0; col < Ncols; col++ ) { double ci = options->ymax - ((double) row + 0.5) * geometry->dy; double cr = options->xmin + ((double) col + 0.5) * geometry->dx; unsigned int iteration = mandelbrot_escape (cr, ci, options->kmax); size_t pixel_offset = ((size_t) row * (size_t) geometry->width + (size_t) col) * 3u; colour_from_iteration (iteration, options->kmax, &image[pixel_offset]); } return; } /* ======================================================================================== /* Program entry point. */ int main (int argc, // number of command-line tokens char **argv // command-line token vector ) { options_t options; image_geometry_t geometry; render_stats_t stats; unsigned char *image; size_t image_bytes; int parse_status; double inside_fraction; double average_iterations; uint64_t pixel_count; set_default_options (&options); parse_status = parse_command_line (argc, argv, &options); if (parse_status > 0) return EXIT_SUCCESS; if (parse_status < 0 || validate_options (&options) != 0 || make_geometry (&options, &geometry) != 0) return EXIT_FAILURE; if ((size_t) geometry.width > SIZE_MAX / (size_t) geometry.height || (size_t) geometry.width * (size_t) geometry.height > SIZE_MAX / 3u) { fprintf (stderr, "Image is too large for this platform\n"); return EXIT_FAILURE; } image_bytes = (size_t) geometry.width * (size_t) geometry.height * 3u; image = (unsigned char *) malloc (image_bytes); if (image == NULL) { fprintf (stderr, "Unable to allocate image buffer (%zu bytes)\n", image_bytes); return EXIT_FAILURE; } fprintf (stderr, "Rendering %u x %u pixels, kmax = %u, view = [%.17g, %.17g] x [%.17g, %.17g]\n", geometry.width, geometry.height, options.kmax, options.xmin, options.xmax, options.ymin, options.ymax); if (options.dx_factor != DEFAULT_DX_FACTOR) { fprintf (stderr, "Note: --dx-factor is accepted for assignment-interface compatibility; " "this serial stripe baseline does not use it.\n"); } render_image (&options, &geometry, image, &stats); int errio; if ( options.ioformat == PPM ) errio = write_ppm_image (image, geometry.width, geometry.height, options.output_path); else if ( options.ioformat == PNG ) errio = write_png_rgb8 (options.output_path, geometry.width, geometry.height, image); free(image); if ( errio != 0) return EXIT_FAILURE; pixel_count = (uint64_t) geometry.width * (uint64_t) geometry.height; inside_fraction = (double) stats.inside_pixels / (double) pixel_count; average_iterations = (double) stats.total_iterations / (double) pixel_count; printf ("output_file %s\n", options.output_path); printf ("width %u\n", geometry.width); printf ("height %u\n", geometry.height); printf ("kmax %u\n", options.kmax); printf ("iteration_checksum %016llx\n", (unsigned long long) stats.checksum); printf ("inside_pixels %llu\n", (unsigned long long) stats.inside_pixels); printf ("inside_fraction %.17g\n", inside_fraction); printf ("average_iterations %.17g\n", average_iterations); printf ("total_iterations %llu\n", (unsigned long long) stats.total_iterations); return EXIT_SUCCESS; } OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.h.pre_fix 0 → 100644 +148 −0 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.h.pre_fix: 148 added lines, 0 removed lines. Original line number Diff line number Diff line /* ────────────────────────────────────────────────────────────────────────── * │ │ │ This file is part of the exercises for the Lectures on │ │ "Foundations of High Performance Computing" │ │ given at │ │ Master in HPC and │ │ Master in Data Science and Scientific Computing │ │ @ SISSA, ICTP and University of Trieste │ │ │ │ contact: luca.tornatore@inaf.it │ │ │ │ This is free software; you can redistribute it and/or modify │ │ it under the terms of the GNU General Public License as published by │ │ the Free Software Foundation; either version 3 of the License, or │ │ (at your option) any later version. │ │ This code is distributed in the hope that it will be useful, │ │ but WITHOUT ANY WARRANTY; without even the implied warranty of │ │ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the │ │ GNU General Public License for more details. │ │ │ │ You should have received a copy of the GNU General Public License │ │ along with this program. If not, see <http://www.gnu.org/licenses/> │ │ │ * ────────────────────────────────────────────────────────────────────────── */ /* Serial Mandelbrot renderer for the HPC final-exam exercise. This file is a clean serial baseline, whose goal is to give a correct and readable starting point from which introduce MPI work dispatch, OpenMP scheduling, optimization experiments, and different tile granularities. The program implements a command-line parsing, computes every pixel by direct iteration, stores the image in a row-major RGB buffer, and writes either a PGM file through a tiny PGM writer, or a png file using the stb header. Have fun. */ #include <errno.h> #include <limits.h> #include <math.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define _MANDEL_ERR_ ((uint32_t)-1) #define _MANDEL_PGM_ 0 #define _MANDEL_PNG_ 1 #define NIMAGEFORMATS 2 #define DEFAULT_XMIN (-2.5) #define DEFAULT_XMAX (1.5) #define DEFAULT_YMIN (-2.0) #define DEFAULT_YMAX (2.0) #define DEFAULT_PPU (256u) #define DEFAULT_DX_FACTOR (8u) #define DEFAULT_DY_FACTOR (8u) #define DEFAULT_KMAX (1024u) #define DEFAULT_FORMAT _MANDEL_PGM_ #define DEFAULT_FMT_NAME "PGM" #define DEFAULT_OUTPUT "mandelbrot.pgm" #define FNV_OFFSET_BASIS (1469598103934665603ULL) #define FNV_PRIME (1099511628211ULL) /* Runtime options shared by the serial baseline and by the future parallel implementations. The dx_factor entry is parsed for launcher compatibility with the assignment interface, although the serial stripe strategy does not need it. */ typedef struct { double xmin; double xmax; double ymin; double ymax; unsigned int ppu; unsigned int dx_factor; unsigned int dy_factor; unsigned int kmax; unsigned int format; char *output_path; } options_t; /* Image geometry after converting the continuous complex-plane window into a discrete pixel grid. Pixels are addressed as (row, column), with row zero at the top of the image, consistently with the --ymax upper-left convention. */ typedef struct { unsigned int width; unsigned int height; double dx; double dy; } image_geometry_t; /* Lightweight diagnostics printed at the end of the run. The checksum is just useful reproducibility check: if two runs have the same options, compiler, and arithmetic behaviour, they should report the same value. */ typedef struct { uint64_t checksum; uint64_t total_iterations; uint64_t inside_pixels; } render_stats_t; char *mandelbrot_image_formats[NIMAGEFORMATS] = {"pgm", "png" }; static void print_usage (char *); static void set_default_options (options_t *); static int parse_double_option ( int, char **, int *, double * ); static int parse_unsigned_option ( int, char **, int *, unsigned int * ); //static int parse_double_option ( int, char **, int *, char **, int, unsigned int * ); static int parse_command_line ( int, char **, options_t * ); static int validate_options (options_t * ); static int make_geometry ( options_t *, image_geometry_t * ); static uint64_t checksum_update_uint (uint64_t, unsigned int ); static int write_ppm_image( const void * restrict, const int, const int, const char * restrict ); Loading
OpenMP/exercises/Mandelbrot/mandelbrot.omp.c→OpenMP/exercises/Mandelbrot/.backups/mandelbrot.omp.c.pre_split +55 −95 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot.omp.c.pre_split: 55 added lines, 95 removed lines. Original line number Diff line number Diff line Loading @@ -133,6 +133,9 @@ print_usage (char *program_name // executable name from argv[0] " --dx-factor VALUE accepted for interface compatibility (%u)\n" " --dy-factor VALUE number of serial horizontal work stripes (%u)\n" " --kmax VALUE maximum Mandelbrot iteration count (%u)\n" " --mode VALUE 0: omp for schedule(static)\n" " n > 0: omp for schedule(static,n)\n" " n < 0: omp for schedule(dynamic, -n)\n" " --output FILE output PNG file (%s)\n" " --help show this help message\n" "\n" Loading Loading @@ -239,11 +242,16 @@ parse_unsigned_option ( int argc, // number of command-line tokens return 0; } /* Parse an integer option of the form "--name value". It is used for ppu, factors, and kmax. */ static int parse_positive_option ( int argc, // number of command-line tokens char **argv, // command-line token vector int *i, // index of the option currently being parsed unsigned int *value // destination for the parsed integer value int *value // destination for the parsed integer value ) { char *endptr; Loading @@ -260,19 +268,54 @@ parse_positive_option ( int argc, // number of command-line tokens parsed = strtoul (argv[*i + 1], &endptr, 10); if (errno != 0 || endptr == argv[*i + 1] || *endptr != '\0' || parsed < 0 || parsed > UINT_MAX) || parsed > 1) { fprintf (stderr, "Invalid integer value for %s: %s\n", argv[*i], argv[*i + 1]); return -1; } *value = (unsigned int) parsed; *value = (int) parsed; *i += 1; return 0; } static int parse_string_option ( int argc, // number of command-line tokens char **argv, // command-line token vector int *i, // index of the option currently being parsed int *value // destination for the parsed integer value ) { if (*i + 1 >= argc) { fprintf (stderr, "Missing value after %s\n", argv[*i]); return -1; } // get the strlen int len = strlen( argv[*i+1] ); // convert on lower case for ( int c = 0; c < len; c++ ) argv[*i+1]+c = lower(argv[*i+1]+c); // compare with admissible values if ( strncmp( "pgm", argv[*i+1], 3 ) == 0 ) *value = _MANDEL_PGM_; else if ( strncmp( "png", argv[*i+1], 3 ) == 0 ) *value = _MANDEL_PNG_; else *value = _MANDEL_FORMAT_ERR_ *i += 1; return 0; } /* Parse all command-line options. */ Loading Loading @@ -542,86 +585,6 @@ colour_from_iteration (unsigned int iteration, // escape iteration count rgb[2] = (unsigned char) (255.0 * 8.5 * one_minus_t * one_minus_t * one_minus_t * t); } /* Render a contiguous horizontal range of rows. This is a serial version of the stripe unit used in Track A: it is a simple implementation, but this function makes the future producer-consumer decomposition almost there. */ static void render_stripe (options_t *options, // view and iteration options image_geometry_t *geometry, // image dimensions and pixel spacing unsigned int row_begin, // first row included in this stripe unsigned int row_end, // first row after this stripe unsigned char *image, // complete row-major RGB image buffer render_stats_t *stats // diagnostics accumulated over the image ) { uint64_t local_checksum; uint64_t local_total_iterations; uint64_t local_inside_pixels; local_checksum = stats->checksum; local_total_iterations = stats->total_iterations; local_inside_pixels = stats->inside_pixels; for (unsigned int row = row_begin; row < row_end; ++row) { // Row zero is the top of the image, hence the minus sign from ymax. double ci = options->ymax - ((double) row + 0.5) * geometry->dy; for (unsigned col = 0; col < geometry->width; ++col) { double cr = options->xmin + ((double) col + 0.5) * geometry->dx; unsigned int iteration = mandelbrot_escape (cr, ci, options->kmax); size_t pixel_offset = ((size_t) row * (size_t) geometry->width + (size_t) col) * 3u; colour_from_iteration (iteration, options->kmax, &image[pixel_offset]); local_checksum = checksum_update_uint (local_checksum, iteration); local_total_iterations += (uint64_t) iteration; if (iteration >= options->kmax) local_inside_pixels += 1u; } } stats->checksum = local_checksum; stats->total_iterations = local_total_iterations; stats->inside_pixels = local_inside_pixels; } /* Render the full image by visiting dy_factor horizontal stripes in order. */ static void render_image_bystripes (options_t *options, // view, factors, and kmax image_geometry_t *geometry, // image dimensions and pixel spacing unsigned char *image, // complete row-major RGB image buffer render_stats_t *stats // output diagnostics ) { unsigned int stripe; unsigned int row_begin; unsigned int row_end; stats->checksum = FNV_OFFSET_BASIS; stats->total_iterations = 0u; stats->inside_pixels = 0u; for (stripe = 0; stripe < options->dy_factor; ++stripe) { row_begin = (unsigned int) (((uint64_t) stripe * geometry->height) / options->dy_factor); row_end = (unsigned int) (((uint64_t) (stripe + 1u) * geometry->height) / options->dy_factor); if (row_begin < row_end) render_stripe (options, geometry, row_begin, row_end, image, stats); } } static void render_image (options_t *options, // view, factors, and kmax Loading Loading @@ -658,23 +621,24 @@ render_image (options_t *options, // view, factors, and kmax double mytime = CPU_TIME_T; double my_calc_time = 0; if ( options->mode == 1) if ( options->mode == 0) { sprintf( schedule_type, "static, max chunk" ); #pragma omp for nowait #include "loop.h" #include "mandelbrot_loop.h" } else if (options->mode == 2) else if (options->mode > 0) { sprintf( schedule_type, "static, 1-line chunk" ); #pragma omp for schedule(static, 1) nowait #include "loop.h" sprintf( schedule_type, "static, %d-line chunk", options->mode); #pragma omp for schedule(static, options->mode) nowait #include "mandelbrot_loop.h" } else { options->mode *= -1; sprintf( schedule_type, "dynamic, %d points chunk", options->mode ); #pragma omp for collapse(2) schedule(dynamic, options->mode) nowait #include "loop.h" #include "mandelbrot_loop.h" } mytime = CPU_TIME_T - mytime; Loading Loading @@ -847,17 +811,13 @@ main (int argc, // number of command-line tokens "this serial stripe baseline does not use it.\n"); } if ( options.mode == 0 ) render_image_bystripes (&options, &geometry, image, &stats); else { #if defined(PROFILE) timage = (unsigned char *) malloc (image_bytes); render_image (&options, &geometry, image, timage); #else render_image (&options, &geometry, image); #endif } if (write_ppm_image (image, geometry.width, geometry.height, options.output_path) != 0) { Loading
OpenMP/exercises/Mandelbrot/mandelbrot_serial--with_png_output.c→OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial--with_png_output.c.pre_stb_fix +0 −0 File moved. View file
OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial--with_png_output.c.retired 0 → 100644 +688 −0 File added.Preview size limit exceeded, changes collapsed. Show changes
OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.c.pre_fix 0 → 100644 +248 −0 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.c.pre_fix: 248 added lines, 0 removed lines. Original line number Diff line number Diff line /* ────────────────────────────────────────────────────────────────────────── * │ │ │ This file is part of the exercises for the Lectures on │ │ "Foundations of High Performance Computing" │ │ given at │ │ Master in HPC and │ │ Master in Data Science and Scientific Computing │ │ @ SISSA, ICTP and University of Trieste │ │ │ │ contact: luca.tornatore@inaf.it │ │ │ │ This is free software; you can redistribute it and/or modify │ │ it under the terms of the GNU General Public License as published by │ │ the Free Software Foundation; either version 3 of the License, or │ │ (at your option) any later version. │ │ This code is distributed in the hope that it will be useful, │ │ but WITHOUT ANY WARRANTY; without even the implied warranty of │ │ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the │ │ GNU General Public License for more details. │ │ │ │ You should have received a copy of the GNU General Public License │ │ along with this program. If not, see <http://www.gnu.org/licenses/> │ │ │ * ────────────────────────────────────────────────────────────────────────── */ /* Serial Mandelbrot renderer for the HPC final-exam exercise. This file is a clean serial baseline, whose goal is to give a correct and readable starting point from which introduce MPI work dispatch, OpenMP scheduling, optimization experiments, and different tile granularities. The program implements a command-line parsing, computes every pixel by direct iteration, stores the image in a row-major RGB buffer, and writes either a PGM file through a tiny PGM writer, or a png file using the stb header. Have fun. */ #include "mandelbrot_serial.h" /* ======================================================================================== : ------------------------------------------------------ : : CALCULATION FUNCTIONS : : ------------------------------------------------------ : */ /* Compute the Mandelbrot escape iteration for one point c = cr + i ci. This is the direct scalar kernel, clean, keeps the operation count easy to read. This can be heavility optimized. */ static unsigned int mandelbrot_escape (double cr, // real part of the pixel centre double ci, // imaginary part of the pixel centre unsigned int kmax // maximum number of iterations ) { double zr; double zi; double zr_next; double zr2; double zi2; unsigned int k; zr = 0.0; zi = 0.0; k = 0; while (k < kmax) { zr2 = zr * zr; zi2 = zi * zi; if (zr2 + zi2 > 4.0) break; zr_next = zr2 - zi2 + cr; zi = 2.0 * zr * zi + ci; zr = zr_next; k += 1; } return k; } /* Map one iteration count to an RGB colour. Interior points are black. The outside palette is deliberately simple. It might be fun experimenting by advanced colouring or smooth-potential formulas. Don't be distracted by this, though */ static void colour_from_iteration (unsigned int iteration, // escape iteration count unsigned int kmax, // maximum iteration count unsigned char *rgb // output triplet: red, green, blue ) { double t; double one_minus_t; if (iteration >= kmax) { rgb[0] = 0u; rgb[1] = 0u; rgb[2] = 0u; return; } t = (double) iteration / (double) kmax; one_minus_t = 1.0 - t; rgb[0] = (unsigned char) (255.0 * 9.0 * one_minus_t * t * t * t); rgb[1] = (unsigned char) (255.0 * 15.0 * one_minus_t * one_minus_t * t * t); rgb[2] = (unsigned char) (255.0 * 8.5 * one_minus_t * one_minus_t * one_minus_t * t); } static void render_image (options_t *options, // view, factors, and kmax image_geometry_t *geometry, // image dimensions and pixel spacing unsigned char *image // complete row-major RGB image buffer ) { uint64_t Nrows = geometry->height; uint64_t Ncols = geometry->width; for ( int row = 0; row < Nrows; row++ ) for ( int col = 0; col < Ncols; col++ ) { double ci = options->ymax - ((double) row + 0.5) * geometry->dy; double cr = options->xmin + ((double) col + 0.5) * geometry->dx; unsigned int iteration = mandelbrot_escape (cr, ci, options->kmax); size_t pixel_offset = ((size_t) row * (size_t) geometry->width + (size_t) col) * 3u; colour_from_iteration (iteration, options->kmax, &image[pixel_offset]); } return; } /* ======================================================================================== /* Program entry point. */ int main (int argc, // number of command-line tokens char **argv // command-line token vector ) { options_t options; image_geometry_t geometry; render_stats_t stats; unsigned char *image; size_t image_bytes; int parse_status; double inside_fraction; double average_iterations; uint64_t pixel_count; set_default_options (&options); parse_status = parse_command_line (argc, argv, &options); if (parse_status > 0) return EXIT_SUCCESS; if (parse_status < 0 || validate_options (&options) != 0 || make_geometry (&options, &geometry) != 0) return EXIT_FAILURE; if ((size_t) geometry.width > SIZE_MAX / (size_t) geometry.height || (size_t) geometry.width * (size_t) geometry.height > SIZE_MAX / 3u) { fprintf (stderr, "Image is too large for this platform\n"); return EXIT_FAILURE; } image_bytes = (size_t) geometry.width * (size_t) geometry.height * 3u; image = (unsigned char *) malloc (image_bytes); if (image == NULL) { fprintf (stderr, "Unable to allocate image buffer (%zu bytes)\n", image_bytes); return EXIT_FAILURE; } fprintf (stderr, "Rendering %u x %u pixels, kmax = %u, view = [%.17g, %.17g] x [%.17g, %.17g]\n", geometry.width, geometry.height, options.kmax, options.xmin, options.xmax, options.ymin, options.ymax); if (options.dx_factor != DEFAULT_DX_FACTOR) { fprintf (stderr, "Note: --dx-factor is accepted for assignment-interface compatibility; " "this serial stripe baseline does not use it.\n"); } render_image (&options, &geometry, image, &stats); int errio; if ( options.ioformat == PPM ) errio = write_ppm_image (image, geometry.width, geometry.height, options.output_path); else if ( options.ioformat == PNG ) errio = write_png_rgb8 (options.output_path, geometry.width, geometry.height, image); free(image); if ( errio != 0) return EXIT_FAILURE; pixel_count = (uint64_t) geometry.width * (uint64_t) geometry.height; inside_fraction = (double) stats.inside_pixels / (double) pixel_count; average_iterations = (double) stats.total_iterations / (double) pixel_count; printf ("output_file %s\n", options.output_path); printf ("width %u\n", geometry.width); printf ("height %u\n", geometry.height); printf ("kmax %u\n", options.kmax); printf ("iteration_checksum %016llx\n", (unsigned long long) stats.checksum); printf ("inside_pixels %llu\n", (unsigned long long) stats.inside_pixels); printf ("inside_fraction %.17g\n", inside_fraction); printf ("average_iterations %.17g\n", average_iterations); printf ("total_iterations %llu\n", (unsigned long long) stats.total_iterations); return EXIT_SUCCESS; }
OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.h.pre_fix 0 → 100644 +148 −0 Changes for OpenMP/exercises/Mandelbrot/.backups/mandelbrot_serial.h.pre_fix: 148 added lines, 0 removed lines. Original line number Diff line number Diff line /* ────────────────────────────────────────────────────────────────────────── * │ │ │ This file is part of the exercises for the Lectures on │ │ "Foundations of High Performance Computing" │ │ given at │ │ Master in HPC and │ │ Master in Data Science and Scientific Computing │ │ @ SISSA, ICTP and University of Trieste │ │ │ │ contact: luca.tornatore@inaf.it │ │ │ │ This is free software; you can redistribute it and/or modify │ │ it under the terms of the GNU General Public License as published by │ │ the Free Software Foundation; either version 3 of the License, or │ │ (at your option) any later version. │ │ This code is distributed in the hope that it will be useful, │ │ but WITHOUT ANY WARRANTY; without even the implied warranty of │ │ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the │ │ GNU General Public License for more details. │ │ │ │ You should have received a copy of the GNU General Public License │ │ along with this program. If not, see <http://www.gnu.org/licenses/> │ │ │ * ────────────────────────────────────────────────────────────────────────── */ /* Serial Mandelbrot renderer for the HPC final-exam exercise. This file is a clean serial baseline, whose goal is to give a correct and readable starting point from which introduce MPI work dispatch, OpenMP scheduling, optimization experiments, and different tile granularities. The program implements a command-line parsing, computes every pixel by direct iteration, stores the image in a row-major RGB buffer, and writes either a PGM file through a tiny PGM writer, or a png file using the stb header. Have fun. */ #include <errno.h> #include <limits.h> #include <math.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define _MANDEL_ERR_ ((uint32_t)-1) #define _MANDEL_PGM_ 0 #define _MANDEL_PNG_ 1 #define NIMAGEFORMATS 2 #define DEFAULT_XMIN (-2.5) #define DEFAULT_XMAX (1.5) #define DEFAULT_YMIN (-2.0) #define DEFAULT_YMAX (2.0) #define DEFAULT_PPU (256u) #define DEFAULT_DX_FACTOR (8u) #define DEFAULT_DY_FACTOR (8u) #define DEFAULT_KMAX (1024u) #define DEFAULT_FORMAT _MANDEL_PGM_ #define DEFAULT_FMT_NAME "PGM" #define DEFAULT_OUTPUT "mandelbrot.pgm" #define FNV_OFFSET_BASIS (1469598103934665603ULL) #define FNV_PRIME (1099511628211ULL) /* Runtime options shared by the serial baseline and by the future parallel implementations. The dx_factor entry is parsed for launcher compatibility with the assignment interface, although the serial stripe strategy does not need it. */ typedef struct { double xmin; double xmax; double ymin; double ymax; unsigned int ppu; unsigned int dx_factor; unsigned int dy_factor; unsigned int kmax; unsigned int format; char *output_path; } options_t; /* Image geometry after converting the continuous complex-plane window into a discrete pixel grid. Pixels are addressed as (row, column), with row zero at the top of the image, consistently with the --ymax upper-left convention. */ typedef struct { unsigned int width; unsigned int height; double dx; double dy; } image_geometry_t; /* Lightweight diagnostics printed at the end of the run. The checksum is just useful reproducibility check: if two runs have the same options, compiler, and arithmetic behaviour, they should report the same value. */ typedef struct { uint64_t checksum; uint64_t total_iterations; uint64_t inside_pixels; } render_stats_t; char *mandelbrot_image_formats[NIMAGEFORMATS] = {"pgm", "png" }; static void print_usage (char *); static void set_default_options (options_t *); static int parse_double_option ( int, char **, int *, double * ); static int parse_unsigned_option ( int, char **, int *, unsigned int * ); //static int parse_double_option ( int, char **, int *, char **, int, unsigned int * ); static int parse_command_line ( int, char **, options_t * ); static int validate_options (options_t * ); static int make_geometry ( options_t *, image_geometry_t * ); static uint64_t checksum_update_uint (uint64_t, unsigned int ); static int write_ppm_image( const void * restrict, const int, const int, const char * restrict );