src/sn-evolution.c: Added pthread support for (local) parallelization.
[sort-networks.git] / src / sn-evolution.c
index e319660..b6c37b4 100644 (file)
@@ -1,3 +1,24 @@
+/**
+ * collectd - src/sn-evolution.c
+ * Copyright (C) 2008  Florian octo Forster
+ *
+ * This program 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; only version 2 of the License is applicable.
+ *
+ * This program 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
 #define _ISOC99_SOURCE
 #define _POSIX_C_SOURCE 200112L
 
 #include <assert.h>
 #include <limits.h>
 
+#include <pthread.h>
+
 #include "sn_network.h"
 #include "sn_population.h"
+#include "sn_random.h"
 
 /* Yes, this is ugly, but the GNU libc doesn't export it with the above flags.
  * */
@@ -39,32 +63,6 @@ static void sigint_handler (int signal)
   do_loop++;
 } /* void sigint_handler */
 
-static int init_random (void)
-{
-  int fd;
-  unsigned int r;
-
-  fd = open ("/dev/random", O_RDONLY);
-  if (fd < 0)
-  {
-    perror ("open");
-    return (-1);
-  }
-
-  read (fd, (void *) &r, sizeof (r));
-  close (fd);
-
-  srand (r);
-
-  return (0);
-} /* int init_random */
-
-static int bounded_random (int upper_bound)
-{
-  double r = ((double) rand ()) / ((double) RAND_MAX);
-  return ((int) (r * upper_bound));
-}
-
 static void exit_usage (const char *name)
 {
   printf ("Usage: %s [options]\n"
@@ -255,8 +253,8 @@ static int create_offspring (void)
     int pos;
     enum sn_network_cut_dir_e dir;
 
-    pos = bounded_random (SN_NETWORK_INPUT_NUM (n));
-    dir = (bounded_random (2) == 0) ? DIR_MIN : DIR_MAX;
+    pos = sn_bounded_random (0, SN_NETWORK_INPUT_NUM (n) - 1);
+    dir = (sn_bounded_random (0, 1) == 0) ? DIR_MIN : DIR_MAX;
 
     assert ((pos >= 0) && (pos < SN_NETWORK_INPUT_NUM (n)));
 
@@ -275,25 +273,62 @@ static int create_offspring (void)
   return (0);
 } /* int create_offspring */
 
-static int start_evolution (void)
+static void *evolution_thread (void *arg)
 {
-  uint64_t i;
-
   while (do_loop == 0)
   {
     create_offspring ();
-
+    /* XXX: Not synchronized! */
     iteration_counter++;
-    i = iteration_counter;
+  }
 
-#if 0
-    if ((stats_interval > 0) && ((i % stats_interval) == 0))
-      population_print_stats (i);
-#endif
+  return ((void *) 0);
+} /* int start_evolution */
+
+static int evolution_start (int threads_num)
+{
+  pthread_t threads[threads_num]; /* C99 ftw! */
+  int i;
+
+  for (i = 0; i < threads_num; i++)
+  {
+    int status;
+
+    status = pthread_create (&threads[i], /* attr = */ NULL,
+       evolution_thread, /* arg = */ NULL);
+    if (status != 0)
+    {
+      fprintf (stderr, "evolution_start: pthread_create[%i] failed "
+         "with status %i.\n",
+         i, status);
+      threads[i] = 0;
+    }
+  }
+
+  while (do_loop == 0)
+  {
+    int status;
+    
+    status = sleep (1);
+    if (status == 0)
+    {
+      int best_rating;
+      i = iteration_counter;
+
+      best_rating = sn_population_best_rating (population);
+      printf ("After approximately %i iterations: Currently best rating: %i\n", i, best_rating);
+    }
+  }
+
+  for (i = 0; i < threads_num; i++)
+  {
+    if (threads[i] == 0)
+      continue;
+    pthread_join (threads[i], /* value_ptr = */ NULL);
   }
 
   return (0);
-} /* int start_evolution */
+} /* int evolution_start */
 
 int main (int argc, char **argv)
 {
@@ -303,8 +338,6 @@ int main (int argc, char **argv)
   if (initial_input_file == NULL)
     exit_usage (argv[0]);
 
-  init_random ();
-
   memset (&sigint_action, '\0', sizeof (sigint_action));
   sigint_action.sa_handler = sigint_handler;
   sigaction (SIGINT, &sigint_action, NULL);
@@ -339,9 +372,10 @@ int main (int argc, char **argv)
       "=======================\n",
       initial_input_file, inputs_num, max_population_size);
 
-  start_evolution ();
+  evolution_start (3);
 
-  printf ("Exiting after %llu iterations.\n", iteration_counter);
+  printf ("Exiting after %llu iterations.\n",
+      (unsigned long long) iteration_counter);
 
   {
     sn_network_t *n;