Parallel Programming - Start OpenMP Version
[matches/honours.git] / course / semester2 / pprog / assignment1 / openmp / nbody.c
diff --git a/course/semester2/pprog/assignment1/openmp/nbody.c b/course/semester2/pprog/assignment1/openmp/nbody.c
new file mode 100644 (file)
index 0000000..6998892
--- /dev/null
@@ -0,0 +1,107 @@
+/**
+ * @file nbody.c
+ * @purpose OpenMP version of N-Body simulator, implementation
+ * @author Sam Moore (20503628) - 2012
+ */
+
+#include "nbody.h"
+#include "../single-thread/nbody.c" // Include original code
+#include "graphics.h" // For Graphics_Run function only
+
+/**
+ * @function Simulation_Run
+ * @purpose Start the simulation
+ * @param argc, argv - Passed to Graphics_Run if needed, otherwise unused
+ */
+void Simulation_Run(int argc, char ** argv)
+{      
+       omp_set_nested(1);
+       if (omp_get_nested() != 1)
+       {
+               fprintf(stderr, "Couldn't set nested parallelism, I kind of need that\n");
+               exit(EXIT_FAILURE);
+       }       
+               
+
+       if (options.num_threads == 0)
+               options.num_threads = omp_get_max_threads();
+
+       if (options.draw_graphics)
+               omp_set_num_threads(2);
+       else
+               omp_set_num_threads(1);
+
+
+               
+
+       #pragma omp parallel sections
+       {
+               
+               #pragma omp section
+               {
+                       omp_set_num_threads(options.num_threads);
+                       while (true)
+                       {
+                               
+                               if (runstate != RUN) break; //Check whether the main thread wants to exit
+                               
+                               if (ExitCondition())
+                               {
+                                       break;
+                               }                               
+
+
+                               if (options.draw_graphics == false && options.verbosity != 0 
+                                       && universe.steps % options.verbosity == 1)
+                               {
+                                       DisplayStatistics();
+                               }
+                               
+                                               
+                               Compute();
+                       }
+               }
+
+               #pragma omp section
+               {
+                       if (options.draw_graphics)
+                               Graphics_Run(argc, argv);
+                       printf("Got to bit after Graphics_Run()\n");
+               }
+
+       }
+}
+
+/**
+ * @function Compute
+ * @purpose Compute a single step, multithreaded using OpenMP
+ */
+void Compute(void)
+{
+       //printf("There are %d threads working and %d available\n", omp_get_num_threads(), omp_get_max_threads());
+       //return;
+       unsigned n_per_thread = (universe.N) / options.num_threads;
+       unsigned remainder = (universe.N) % options.num_threads;
+       #pragma omp parallel for
+       for (unsigned i = 0; i < options.num_threads; ++i)
+       {
+               //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
+               System s;
+               s.body = universe.body + (i * n_per_thread);
+               s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
+               System_Forces(&s, &universe);
+       }
+
+       #pragma omp parallel for
+       for (unsigned i = 0; i < options.num_threads; ++i)
+       {
+               //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
+               System s;
+               s.body = universe.body + (i * n_per_thread);
+               s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
+               System_Positions(&s);
+       }
+
+       universe.steps += 1;
+
+}

UCC git Repository :: git.ucc.asn.au