Parallel Programming - Trivial
[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                         //printf("Left compute loop\n");
64                 }
65
66                 #pragma omp section
67                 {
68                         if (options.draw_graphics)
69                                 Graphics_Run(argc, argv);
70                         //printf("Got to bit after Graphics_Run()\n");
71                 }
72
73         }
74 }
75
76 /**
77  * @function Compute
78  * @purpose Compute a single step, multithreaded using OpenMP
79  */
80 void Compute(void)
81 {
82         //printf("There are %d threads working and %d available\n", omp_get_num_threads(), omp_get_max_threads());
83         //return;
84         unsigned n_per_thread = (universe.N) / options.num_threads;
85         unsigned remainder = (universe.N) % options.num_threads;
86         #pragma omp parallel for
87         for (unsigned i = 0; i < options.num_threads; ++i)
88         {
89                 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
90                 System s;
91                 s.body = universe.body + (i * n_per_thread);
92                 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
93                 System_Forces(&s, &universe);
94         }
95
96         #pragma omp parallel for
97         for (unsigned i = 0; i < options.num_threads; ++i)
98         {
99                 //printf("Thread %d executes iteration %u\n", omp_get_thread_num(), i);
100                 System s;
101                 s.body = universe.body + (i * n_per_thread);
102                 s.N = (i == options.num_threads - 1) ? n_per_thread : n_per_thread + remainder;
103                 System_Positions(&s);
104         }
105
106         universe.steps += 1;
107
108 }

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