Parallel Programming - Start OpenMP Version
[matches/honours.git] / course / semester2 / pprog / assignment1 / openmp / nbody.c
1 /**
2  * @file nbody.c
3  * @purpose OpenMP version of N-Body simulator, implementation
4  * @author Sam Moore (20503628) - 2012
5  */
6
7 #include "nbody.h"
8 #include "../single-thread/nbody.c" // Include original code
9 #include "graphics.h" // For Graphics_Run function only
10
11 /**
12  * @function Simulation_Run
13  * @purpose Start the simulation
14  * @param argc, argv - Passed to Graphics_Run if needed, otherwise unused
15  */
16 void Simulation_Run(int argc, char ** argv)
17 {       
18         omp_set_nested(1);
19         if (omp_get_nested() != 1)
20         {
21                 fprintf(stderr, "Couldn't set nested parallelism, I kind of need that\n");
22                 exit(EXIT_FAILURE);
23         }       
24                 
25
26         if (options.num_threads == 0)
27                 options.num_threads = omp_get_max_threads();
28
29         if (options.draw_graphics)
30                 omp_set_num_threads(2);
31         else
32                 omp_set_num_threads(1);
33
34
35                 
36
37         #pragma omp parallel sections
38         {
39                 
40                 #pragma omp section
41                 {
42                         omp_set_num_threads(options.num_threads);
43                         while (true)
44                         {
45                                 
46                                 if (runstate != RUN) break; //Check whether the main thread wants to exit
47                                 
48                                 if (ExitCondition())
49                                 {
50                                         break;
51                                 }                               
52
53
54                                 if (options.draw_graphics == false && options.verbosity != 0 
55                                         && universe.steps % options.verbosity == 1)
56                                 {
57                                         DisplayStatistics();
58                                 }
59                                 
60                                                 
61                                 Compute();
62                         }
63                 }
64
65                 #pragma omp section
66                 {
67                         if (options.draw_graphics)
68                                 Graphics_Run(argc, argv);
69                         printf("Got to bit after Graphics_Run()\n");
70                 }
71
72         }
73 }
74
75 /**
76  * @function Compute
77  * @purpose Compute a single step, multithreaded using OpenMP
78  */
79 void Compute(void)
80 {
81         //printf("There are %d threads working and %d available\n", omp_get_num_threads(), omp_get_max_threads());
82         //return;
83         unsigned n_per_thread = (universe.N) / options.num_threads;
84         unsigned remainder = (universe.N) % options.num_threads;
85         #pragma omp parallel for
86         for (unsigned i = 0; i < options.num_threads; ++i)
87         {
88                 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
89                 System s;
90                 s.body = universe.body + (i * n_per_thread);
91                 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
92                 System_Forces(&s, &universe);
93         }
94
95         #pragma omp parallel for
96         for (unsigned i = 0; i < options.num_threads; ++i)
97         {
98                 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
99                 System s;
100                 s.body = universe.body + (i * n_per_thread);
101                 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
102                 System_Positions(&s);
103         }
104
105         universe.steps += 1;
106
107 }

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