numeric-linalg

Educational material on the SciPy implementation of numerical linear algebra algorithms

Commit
2cb315bb8b2232b3d13c8abbc9bb411d290664de
Parent
5dbee0ecb42c812b89bb8a3697de5e77c9f365a8
Author
Pablo <pablo-pie@riseup.net>
Date

Refactored the progress-bar library

Diffstat

2 files changed, 27 insertions, 20 deletions

Status File Name N° Changes Insertions Deletions
Modified getrf/benchmark/main.c 16 10 6
Modified getrf/benchmark/progress-bar.h 31 17 14
diff --git a/getrf/benchmark/main.c b/getrf/benchmark/main.c
@@ -9,18 +9,22 @@
 #include <string.h>
 #include <errno.h>
 
+#include "progress-bar.h"
 #include "config.h"
 
 #define HISTOGRAM_SIZE              (MAX_N/STEP)
 #define CLOCKS_PER_MILLIS           (CLOCKS_PER_SEC/1000)
 #define LOGISTICS_INITIAL_CONDITION (-800.)
 
-#define PROGRESS_BAR_TOTAL HISTOGRAM_SIZE
-#include "progress-bar.h"
-
 uint32_t histogram[HISTOGRAM_SIZE];
 void (*getrf)(int *m, int *n, double *A, int *lda, int *ipiv, int *info);
 
+ProgressBar progress = {
+  .total = HISTOGRAM_SIZE,
+  .count = 0,
+  .mutex = PTHREAD_MUTEX_INITIALIZER,
+};
+
 // .data is a pointer because it should be allocated in the heap
 // (.data DOES NOT fit in the stack 🤡)
 typedef struct {
@@ -72,7 +76,7 @@ void *thread_benchmark(void *arg)
     uint32_t duration = thread_run_benchmark(thread, n);
 
     histogram[(n - 1)/STEP] = duration;
-    progress_bar_inc();
+    progress_bar_inc(&progress);
   }
 
   return NULL;
@@ -83,7 +87,7 @@ Benchmarker benchmarker_new(double *ref_data)
   Benchmarker bench = {0};
 
   // This array will live for the entire duration of the program,
-  // so we might as well leack it 🤡
+  // so we might as well leak it 🤡
   double *data = malloc(sizeof(double)*MAX_N*MAX_N*N_THREADS);
   if (data == NULL) {
     fprintf(stderr, "ERROR: Buy more RAM!\n");
@@ -139,7 +143,7 @@ int main(int argc, char **argv)
   printf("INFO: Initializing random input data... ");
 
   // This array will live for the entire duration of the program,
-  // so we might as well leack it 🤡
+  // so we might as well leak it 🤡
   double *ref_data = malloc(sizeof(double)*MAX_N*MAX_N);
   if (ref_data == NULL) {
     fprintf(stderr, "ERROR: Buy more RAM!\n");
diff --git a/getrf/benchmark/progress-bar.h b/getrf/benchmark/progress-bar.h
@@ -7,30 +7,33 @@
 
 #define PROGRESS_BAR_LENGTH 50
 
-size_t progress_last_printed_count = 0;
-size_t progress_count = 0;
-pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void progress_bar_inc(void)
+/*
+ * A thread-safe self-printing progress bar
+ */
+typedef struct {
+  size_t          total;
+  size_t          count;
+  pthread_mutex_t mutex;
+} ProgressBar;
+
+void progress_bar_inc(ProgressBar *p)
 {
-  pthread_mutex_lock(&progress_mutex);
+  pthread_mutex_lock(&p->mutex);
 
-  progress_count++;
-  size_t filled_length = (PROGRESS_BAR_LENGTH*progress_count)/PROGRESS_BAR_TOTAL;
+  p->count++;
+  size_t filled_length = (PROGRESS_BAR_LENGTH*p->count)/p->total;
   size_t empty_length = PROGRESS_BAR_LENGTH - filled_length;
 
   printf("\r[");
   for (size_t i = 0; i < filled_length; i++) printf("=");
   for (size_t i = 0; i < empty_length; i++)  printf(" ");
 
-  size_t percent = (100 * progress_count) / PROGRESS_BAR_TOTAL;
-  if (percent == 100) printf("] %3zu%%\n", percent);
-  else printf("] %3zu%%", percent);
-
-  progress_last_printed_count = progress_count;
+  size_t percent = (100*p->count)/p->total;
+  printf("] %3zu%%", percent);
+  if (percent == 100) printf("\n");
 
   fflush(stdout);
-  pthread_mutex_unlock(&progress_mutex);
+  pthread_mutex_unlock(&p->mutex);
 }
 
 #endif // PROGRESS_BAR_H_