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 // Support for GUI display for Polygon overlay demo
18 
19 #define VIDEO_WINMAIN_ARGS
20 #include <iostream>
21 
22 #include "oneapi/tbb/tick_count.h"
23 
24 #include "common/utility/get_default_num_threads.hpp"
25 
26 #include "polyover.hpp"
27 #include "polymain.hpp"
28 #include "pover_video.hpp"
29 #ifndef _WIN32
30 #include <sys/time.h>
31 #include <unistd.h>
32 
rt_sleep(int msec)33 void rt_sleep(int msec) {
34     usleep(msec * 1000);
35 }
36 
37 #else //_WIN32
38 
39 #undef OLDUNIXTIME
40 #undef STDTIME
41 
42 #include <windows.h>
43 
rt_sleep(int msec)44 void rt_sleep(int msec) {
45     Sleep(msec);
46 }
47 
48 #endif /*  _WIN32  */
49 
g_next_frame()50 bool g_next_frame() {
51     if (++n_next_frame_calls >= frame_skips) { // the data race here is benign
52         n_next_frame_calls = 0;
53         return gVideo->next_frame();
54     }
55     return gVideo->running;
56 }
57 
g_last_frame()58 bool g_last_frame() {
59     if (n_next_frame_calls)
60         return gVideo->next_frame();
61     return gVideo->running;
62 }
63 
initializeVideo(int argc,char * argv[])64 bool initializeVideo(int argc, char *argv[]) {
65     //pover_video *l_video = new pover_video();
66     //gVideo = l_video;
67     gVideo->init_console(); // don't check return code.
68     gVideo->title = g_windowTitle;
69     g_useGraphics = gVideo->init_window(g_xwinsize, g_ywinsize);
70     return true;
71 }
72 
on_process()73 void pover_video::on_process() {
74     oneapi::tbb::tick_count t0, t1;
75     double naiveParallelTime, domainSplitParallelTime;
76     // create map1  These could be done in parallel, if the pseudorandom number generator were re-seeded.
77     GenerateMap(
78         &gPolymap1, gMapXSize, gMapYSize, gNPolygons, /*red*/ 255, /*green*/ 0, /*blue*/ 127);
79     // create map2
80     GenerateMap(
81         &gPolymap2, gMapXSize, gMapYSize, gNPolygons, /*red*/ 0, /*green*/ 255, /*blue*/ 127);
82     //
83     // Draw source maps
84     gDrawXOffset = map1XLoc;
85     gDrawYOffset = map1YLoc;
86     for (int i = 0; i < int(gPolymap1->size()); i++) {
87         (*gPolymap1)[i].drawPoly();
88     }
89     gDrawXOffset = map2XLoc;
90     gDrawYOffset = map2YLoc;
91     for (int i = 0; i < int(gPolymap2->size()); i++) {
92         (*gPolymap2)[i].drawPoly();
93     }
94     gDoDraw = true;
95 
96     // run serial map generation
97     gDrawXOffset = maprXLoc;
98     gDrawYOffset = maprYLoc;
99     {
100         RPolygon *xp =
101             new RPolygon(0, 0, gMapXSize - 1, gMapYSize - 1, 0, 0, 0); // Clear the output space
102         delete xp;
103         t0 = oneapi::tbb::tick_count::now();
104         SerialOverlayMaps(&gResultMap, gPolymap1, gPolymap2);
105         t1 = oneapi::tbb::tick_count::now();
106         std::cout << "Serial overlay took " << (t1 - t0).seconds() * 1000 << " msec"
107                   << "\n";
108         gSerialTime = (t1 - t0).seconds() * 1000;
109 #if _DEBUG
110         CheckPolygonMap(gResultMap);
111         // keep the map for comparison purposes.
112 #else
113         delete gResultMap;
114 #endif
115         if (gCsvFile.is_open()) {
116             gCsvFile << "Serial Time," << gSerialTime << "\n";
117             gCsvFile << "Threads,";
118             if (gThreadsLow == THREADS_UNSET || gThreadsLow == utility::get_default_num_threads()) {
119                 gCsvFile << "Threads,Automatic";
120             }
121             else {
122                 for (int i = gThreadsLow; i <= gThreadsHigh; i++) {
123                     gCsvFile << i;
124                     if (i < gThreadsHigh)
125                         gCsvFile << ",";
126                 }
127             }
128             gCsvFile << "\n";
129         }
130         if (gIsGraphicalVersion)
131             rt_sleep(2000);
132     }
133     // run naive parallel map generation
134     {
135         Polygon_map_t *resultMap;
136         if (gCsvFile.is_open()) {
137             gCsvFile << "Naive Time";
138         }
139         NaiveParallelOverlay(resultMap, *gPolymap1, *gPolymap2);
140         delete resultMap;
141         if (gIsGraphicalVersion)
142             rt_sleep(2000);
143     }
144     // run split map generation
145     {
146         Polygon_map_t *resultMap;
147         if (gCsvFile.is_open()) {
148             gCsvFile << "Split Time";
149         }
150         SplitParallelOverlay(&resultMap, gPolymap1, gPolymap2);
151         delete resultMap;
152         if (gIsGraphicalVersion)
153             rt_sleep(2000);
154     }
155     // split, accumulating into concurrent vector
156     {
157         concurrent_Polygon_map_t *cresultMap;
158         if (gCsvFile.is_open()) {
159             gCsvFile << "Split CV time";
160         }
161         SplitParallelOverlayCV(&cresultMap, gPolymap1, gPolymap2);
162         delete cresultMap;
163         if (gIsGraphicalVersion)
164             rt_sleep(2000);
165     }
166     // split, accumulating into ETS
167     {
168         ETS_Polygon_map_t *cresultMap;
169         if (gCsvFile.is_open()) {
170             gCsvFile << "Split ETS time";
171         }
172         SplitParallelOverlayETS(&cresultMap, gPolymap1, gPolymap2);
173         delete cresultMap;
174         if (gIsGraphicalVersion)
175             rt_sleep(2000);
176     }
177     if (gIsGraphicalVersion)
178         rt_sleep(8000);
179     delete gPolymap1;
180     delete gPolymap2;
181 #if _DEBUG
182     delete gResultMap;
183 #endif
184 }
185