1 /*
2     Copyright (c) 2005-2021 Intel Corporation
3 
4     Licensed under the Apache License, Version 2.0 (the "License");
5     you may not use this file except in compliance with the License.
6     You may obtain a copy of the License at
7 
8         http://www.apache.org/licenses/LICENSE-2.0
9 
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15 */
16 
17 /**
18     Evolution.h: Header file for evolution classes; evolution classes do
19     looped evolution of patterns in a defined 2 dimensional space
20 **/
21 
22 #ifndef TBB_examples_game_of_life_evolution_H
23 #define TBB_examples_game_of_life_evolution_H
24 
25 #include <cstring>
26 #include <cstdlib>
27 #include <cstdio>
28 
29 #include "oneapi/tbb/blocked_range.h"
30 #include "oneapi/tbb/parallel_for.h"
31 #include "oneapi/tbb/tick_count.h"
32 #include "oneapi/tbb/global_control.h"
33 
34 #include "Board.hpp"
35 
36 typedef unsigned int Int32;
37 
38 void UpdateState(Matrix* m_matrix, char* dest, int begin, int end);
39 
40 /**
41     class Evolution - base class for SequentialEvolution and ParallelEvolution
42 **/
43 class Evolution {
44 public:
Evolution(Matrix * m,BoardPtr board)45     Evolution(Matrix* m, //! beginning matrix including initial pattern
46               BoardPtr board //! the board to update
47               )
48             : m_matrix(m),
49               m_board(board),
50               m_size(m_matrix->height * m_matrix->width),
51               m_done(false) {
52         //! allocate memory for second matrix data block
53         m_dest = new char[m_size];
54         is_paused = false;
55     }
56 
~Evolution()57     virtual ~Evolution() {
58         delete[] m_dest;
59     }
60 
61     //! Run() - begins looped evolution
62     virtual void Run(double execution_time, int nthread) = 0;
63 
64     //! Quit() - tell the thread to terminate
Quit()65     virtual void Quit() {
66         m_done = true;
67     }
68 
69     //! Step() - performs a single evolutionary generation computation on the game matrix
70     virtual void Step() = 0;
71 
72     //! SetPause() - change condition of variable is_paused
SetPause(bool condition)73     virtual void SetPause(bool condition) {
74         if (condition == true)
75             is_paused = true;
76         else
77             is_paused = false;
78     }
79 
80 protected:
81     /**
82         UpdateMatrix() - moves the previous destination data to the source
83         data block and zeros out destination.
84     **/
85     void UpdateMatrix();
86 
87 protected:
88     Matrix* m_matrix; //! Pointer to initial matrix
89     char* m_dest; //! Pointer to calculation destination data
90     BoardPtr m_board; //! The game board to update
91     int m_size; //! size of the matrix data block
92     volatile bool m_done; //! a flag used to terminate the thread
93     Int32 m_nIteration; //! current calculation cycle index
94     volatile bool is_paused; //! is needed to perform next iteration
95 
96     //! Calculation time of the sequential version (since the start), seconds.
97     /**
98         This member is updated by the sequential version and read by parallel,
99         so no synchronization is necessary.
100     **/
101     double m_serial_time;
102 };
103 
104 /**
105     class SequentialEvolution - derived from Evolution - calculate life generations serially
106 **/
107 class SequentialEvolution : public Evolution {
108 public:
SequentialEvolution(Matrix * m,BoardPtr board)109     SequentialEvolution(Matrix* m, BoardPtr board) : Evolution(m, board) {}
110     virtual void Run(double execution_time, int nthread);
111     virtual void Step();
112 };
113 
114 /**
115     class ParallelEvolution - derived from Evolution - calculate life generations
116     in parallel using oneTBB
117 **/
118 class ParallelEvolution : public Evolution {
119 public:
ParallelEvolution(Matrix * m,BoardPtr board)120     ParallelEvolution(Matrix* m, BoardPtr board) : Evolution(m, board), m_parallel_time(0) {
121         // instantiate a global_control object and save a pointer to it
122         m_pGlobControl = nullptr;
123     }
124 
~ParallelEvolution()125     ~ParallelEvolution() {
126         //! delete global_control object
127         delete m_pGlobControl;
128         m_pGlobControl = nullptr;
129     }
130     virtual void Run(double execution_time, int nthread);
131     virtual void Step();
132 
133 private:
134     oneapi::tbb::global_control* m_pGlobControl;
135 
136     double m_parallel_time;
137 };
138 
139 #endif /* TBB_examples_game_of_life_evolution_H */
140