Committing TBB 2019 Update 9 source code
[platform/upstream/tbb.git] / examples / parallel_for / game_of_life / src / Game_of_life.cpp
1 /*
2     Copyright (c) 2005-2019 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     Game_of_life.cpp : 
19                       main project file.
20 */
21 #include "Board.h"
22 #include "Form1.h"
23 #include "../../../common/utility/get_default_num_threads.h"
24
25 #define WIN32_LEAN_AND_MEAN
26
27 #ifndef _CONSOLE
28 #include <windows.h>
29 #else
30 #include <iostream>
31 #include <sstream>
32 #include <time.h>
33 #include "Evolution.h"
34
35 #define BOARD_SQUARE_SIZE 2
36
37 int low;                            //! lower range limit of threads
38 int high;                           //! high range limit of threads
39 double execution_time;              //! time for game of life iterations
40 #endif
41
42 Board::Board(int width, int height, int squareSize, LabelPtr counter)
43 : m_width(width), m_height(height), m_squareSize(squareSize), m_counter(counter)
44 {
45 #ifndef _CONSOLE
46     InitializeComponent();
47     DoubleBuffered = true;
48
49     this->Width = m_squareSize*width;
50     this->Height = m_squareSize*height;
51 #endif
52     m_matrix = new Matrix();
53     m_matrix->width = width;
54     m_matrix->height = height;
55     m_matrix->data = new char[width*height];
56     memset(m_matrix->data, 0, width*height);
57 #ifndef _CONSOLE
58     m_occupiedBrush = gcnew SolidBrush(Color::Black);
59     m_freeBrush = gcnew SolidBrush(Color::LightGray);
60     
61     m_graphics = CreateGraphics();
62     m_bmp = gcnew Bitmap(Width, Height);
63     m_mem_dc = Graphics::FromImage(m_bmp);
64 #endif
65 }
66
67 Board::~Board()
68 {
69 #ifndef _CONSOLE
70     if (components)
71     {
72         delete components;
73     }
74 #endif
75     delete[] m_matrix->data;
76     delete m_matrix;
77 }
78
79 void Board::seed(int s)
80 {        
81     srand(s);
82     for (int j=0; j<m_height; j++)
83     {
84         for (int i=0; i<m_width; i++)
85         {        
86             int x = rand()/(int)(((unsigned)RAND_MAX + 1) / 100);
87             m_matrix->data[i+j*m_width] = x>75? 1: 0;               // 25% occupied
88         }
89     }
90 #ifndef _CONSOLE
91     Invalidate();
92 #endif
93 }
94
95 void Board::seed( const BoardPtr src )
96 {        
97             memcpy(m_matrix->data, src->m_matrix->data, m_height*m_width);
98 #ifndef _CONSOLE
99     Invalidate();
100 #endif
101 }
102
103 #ifndef _CONSOLE
104 void Board::draw(Graphics^ g)
105 {
106     m_mem_dc->FillRectangle(m_freeBrush, Drawing::Rectangle(0, 0, m_width*m_squareSize, m_height*m_squareSize));
107     for (int j=0; j<m_height; j++)
108     {
109         for (int i=0; i<m_width; i++)
110         {    
111             if ( m_matrix->data[i+j*m_width] )
112             {
113                 m_mem_dc->FillRectangle(m_occupiedBrush, Drawing::Rectangle(i*m_squareSize, j*m_squareSize, m_squareSize, m_squareSize));
114             }
115         }
116     }
117     g->DrawImage(m_bmp, 0, 0);
118 }
119
120 void Board::OnPaint(PaintEventArgs^ e)
121 {
122     draw(e->Graphics);
123 }
124
125 [STAThreadAttribute]
126 int main(array<System::String ^> ^args)
127 {
128     // Enabling Windows XP visual effects before any controls are created
129     Application::EnableVisualStyles();
130     Application::SetCompatibleTextRenderingDefault(false); 
131
132     // Create the main window and run it
133     Application::Run(gcnew Form1());
134     return 0;
135 }
136 #else
137
138 //! Print usage of this program
139 void PrintUsage() 
140 {
141     printf("Usage: gol [M[:N] -t execution_time]\nM and N are a range of numbers of threads to be used.\nexecution_time is a time (in sec) for execution game_of_life iterations\n");
142     printf("Default values:\nM:\t\tautomatic\nN:\t\tM\nexecution_time:\t10\n");
143 }
144
145 //! Parse command line
146 bool ParseCommandLine(int argc, char * argv []) 
147 {
148     char* s = argv[1];
149     char* end;
150     //! command line without parameters
151     if(argc == 1)
152     {
153         low = utility::get_default_num_threads();
154         high = low;
155         execution_time = 5;
156         return true;
157     }
158     //! command line with parameters
159     if(argc != 4)
160     {
161         PrintUsage();
162         return false;
163     }
164     if(std::string("-t") != argv[argc-2])
165     //! process M[:N] parameter
166     high = strtol(s,&end,0);
167     low = strtol(s,&end,0);
168     switch( *end ) 
169     {
170         case ':': 
171             high = strtol(end+1,0,0); 
172             break;
173         case '\0':
174             break;
175         default:
176             PrintUsage();
177             return false;
178     }
179     if (high < low)
180     {
181         std::cout << "Set correct range. Current range: " << low << ":" << high << std::endl;
182         PrintUsage();
183         return false;
184
185     }
186     //! process execution_time parameter
187     execution_time = strtol(argv[argc-1],&end,0);
188     return true;
189 }
190
191 int main( int argc, char* argv[] ) 
192 {
193     if(!ParseCommandLine( argc, argv ))
194         return 1;
195     SequentialEvolution* m_seq;
196     ParallelEvolution* m_par;
197     Board* m_board1;
198     Board* m_board2; 
199     int* count = NULL;
200    
201     int boardWidth = 300;
202     int boardHeight = 300;
203
204     m_board1 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);
205     m_board2 = new Board(boardWidth, boardHeight, BOARD_SQUARE_SIZE, count);
206
207     time_t now = time(NULL);
208     printf("Generate Game of life board\n");
209     m_board1->seed((int)now);
210     m_board2->seed(m_board1);
211
212     m_seq = new SequentialEvolution(m_board1->m_matrix, m_board1);
213     m_seq->Run(execution_time, 1);
214     delete m_seq;
215
216     m_par = new ParallelEvolution(m_board2->m_matrix, m_board2);
217     for( int p = low; p <= high; ++p ) 
218     {
219         m_par->Run(execution_time, p);
220     }
221     delete m_par;
222
223     delete m_board1;
224     delete m_board2;
225     return 0;
226 }
227 #endif