![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright 2005-2010 Intel Corporation. All Rights Reserved. 00003 00004 This file is part of Threading Building Blocks. 00005 00006 Threading Building Blocks is free software; you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License 00008 version 2 as published by the Free Software Foundation. 00009 00010 Threading Building Blocks is distributed in the hope that it will be 00011 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00012 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Threading Building Blocks; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 As a special exception, you may use this file as part of a free software 00020 library without restriction. Specifically, if other files instantiate 00021 templates or use macros or inline functions from this file, or you compile 00022 this file and link it with other files to produce an executable, this 00023 file does not by itself cause the resulting executable to be covered by 00024 the GNU General Public License. This exception does not however 00025 invalidate any other reasons why the executable file might be covered by 00026 the GNU General Public License. 00027 */ 00028 00029 #ifndef __CONVEX_HULL_H__ 00030 #define __CONVEX_HULL_H__ 00031 00032 #define _SCL_SECURE_NO_DEPRECATE 00033 #include <cstdlib> 00034 #include <iostream> 00035 #include <iomanip> 00036 #include <sstream> 00037 #include <vector> 00038 #include <string> 00039 #include <cstring> 00040 #include <algorithm> 00041 #include <functional> 00042 #include <assert.h> 00043 #include "tbb/tick_count.h" 00044 00045 using namespace std; 00046 00047 namespace cfg { 00048 // convex hull problem parameter defaults 00049 const long NP = 5000000; // problem size 00050 const int SNT = 1; // minimal number of threads 00051 const int ENT = 8; // maximal number of threads 00052 00053 // convex hull problem user set parameters 00054 long MAXPOINTS = NP; 00055 int NUM_THREADS_START = SNT; 00056 int NUM_THREADS_END = ENT; 00057 00058 // convex hull grain sizes for 3 subproblems. Be sure 16*GS < 512Kb 00059 const size_t GENERATE_GS = 25000; 00060 const size_t FINDEXT_GS = 25000; 00061 const size_t DIVIDE_GS = 25000; 00062 }; 00063 00064 namespace util { 00065 bool VERBOSE = false; 00066 vector<string> OUTPUT; 00067 00068 // utility functionality 00069 void ParseInputArgs(int argc, char* argv[]) { 00070 int numArgs = 1; 00071 if(argc>numArgs) { 00072 char delim = ':'; 00073 if(!strcmp(argv[numArgs], "-h")) { 00074 cout << " Program usage is:" << endl 00075 << " " << argv[0] << " [NP] [SNT" << delim << "ENT] [-v]" 00076 << endl << endl 00077 << " where:" << endl 00078 << " NP - number of points" << endl 00079 << " SNT - start with this number of threads" << endl 00080 << " ENT - end with this number of threads" << endl 00081 << " -v - turns verbose ON" << endl; 00082 exit(0); 00083 } else { 00084 while(argc>numArgs) { 00085 char* endptr; 00086 if(!strcmp(argv[numArgs], "-v")) { 00087 VERBOSE = true; 00088 } else if(!strchr(argv[numArgs], delim)) { 00089 cfg::MAXPOINTS = strtol(argv[numArgs], &endptr, 0); 00090 if(*endptr!='\0') { 00091 cout << " wrong parameter format for Number of Points" << endl; 00092 exit(1); 00093 } 00094 if(cfg::MAXPOINTS<=0) { 00095 cout 00096 << " wrong value set for Number of Points" << endl 00097 << " using default value: " << endl 00098 << " Number of Points = " << cfg::NP << endl; 00099 cfg::MAXPOINTS = cfg::NP; 00100 } 00101 } else { 00102 cfg::NUM_THREADS_START=(int)strtol(argv[numArgs], &endptr, 0); 00103 if(*endptr==delim) { 00104 cfg::NUM_THREADS_END = (int)strtol(endptr+1, &endptr, 0); 00105 } else { 00106 cout << " wrong parameter format for Number of Threads" << endl; 00107 exit(1); 00108 } 00109 if(*endptr!='\0') { 00110 cout << " wrong parameter format for Number of Threads" << endl; 00111 exit(1); 00112 } 00113 if((cfg::NUM_THREADS_START<=0) 00114 || (cfg::NUM_THREADS_END<cfg::NUM_THREADS_START)) { 00115 cout 00116 << " wrong values set for Number of Threads" << endl 00117 << " using default values: " << endl 00118 << " start NT = " << cfg::SNT << endl 00119 << " end NT = " << cfg::ENT << endl; 00120 cfg::NUM_THREADS_START=cfg::SNT; 00121 cfg::NUM_THREADS_END =cfg::ENT; 00122 } 00123 } 00124 ++numArgs; 00125 } 00126 } 00127 } 00128 } 00129 00130 template <typename T> 00131 struct point { 00132 T x; 00133 T y; 00134 point() : x(T()), y(T()) {} 00135 point(T _x, T _y) : x(_x), y(_y) {} 00136 //why do we need below line? it fails to compile with suncc 00137 //point(const point<T>& _P) : x(_P.x), y(_P.y) {} 00138 }; 00139 00140 int random(unsigned int& rseed) { 00141 #if __linux__ || __APPLE__ || __FreeBSD__ 00142 return rand_r(&rseed); 00143 #elif _WIN32 || __sun 00144 return rand(); 00145 #else 00146 #error Unknown/unsupported OS? 00147 #endif // __linux__ || __APPLE__ || __FreeBSD__ 00148 } 00149 00150 template < typename T > 00151 point<T> GenerateRNDPoint(size_t& count, unsigned int& rseed) { 00152 /* generates random points on 2D plane so that the cluster 00153 is somewhat circle shaped */ 00154 const size_t maxsize=500; 00155 T x = random(rseed)*2.0/(double)RAND_MAX - 1; 00156 T y = random(rseed)*2.0/(double)RAND_MAX - 1; 00157 T r = (x*x + y*y); 00158 if(r>1) { 00159 count++; 00160 if(count>10) { 00161 if (random(rseed)/(double)RAND_MAX > 0.5) 00162 x /= r; 00163 if (random(rseed)/(double)RAND_MAX > 0.5) 00164 y /= r; 00165 count = 0; 00166 } 00167 else { 00168 x /= r; 00169 y /= r; 00170 } 00171 } 00172 00173 x = (x+1)*0.5*maxsize; 00174 y = (y+1)*0.5*maxsize; 00175 00176 return point<T>(x,y); 00177 } 00178 00179 template <typename Index> 00180 struct edge { 00181 Index start; 00182 Index end; 00183 edge(Index _p1, Index _p2) : start(_p1), end(_p2) {}; 00184 }; 00185 00186 template <typename T> 00187 ostream& operator <<(ostream& _ostr, point<T> _p) { 00188 return _ostr << '(' << _p.x << ',' << _p.y << ')'; 00189 } 00190 00191 template <typename T> 00192 istream& operator >>(istream& _istr, point<T> _p) { 00193 return _istr >> _p.x >> _p.y; 00194 } 00195 00196 template <typename T> 00197 bool operator ==(point<T> p1, point<T> p2) { 00198 return (p1.x == p2.x && p1.y == p2.y); 00199 } 00200 00201 template <typename T> 00202 bool operator !=(point<T> p1, point<T> p2) { 00203 return !(p1 == p2); 00204 } 00205 00206 template <typename T> 00207 double cross_product(const point<T>& start, const point<T>& end1, const point<T>& end2) { 00208 return ((end1.x-start.x)*(end2.y-start.y)-(end2.x-start.x)*(end1.y-start.y)); 00209 } 00210 00211 // Timing functions are based on TBB to always obtain wall-clock time 00212 typedef tbb::tick_count my_time_t; 00213 00214 my_time_t gettime() { 00215 return tbb::tick_count::now(); 00216 } 00217 00218 double time_diff(my_time_t start, my_time_t end) { 00219 return (end-start).seconds(); 00220 } 00221 00222 void WriteResults(int nthreads, double initTime, double calcTime) { 00223 if(VERBOSE) { 00224 cout << " Step by step hull construction:" << endl; 00225 for(size_t i = 0; i < OUTPUT.size(); ++i) 00226 cout << OUTPUT[i] << endl; 00227 } 00228 00229 cout 00230 << " Number of nodes:" << cfg::MAXPOINTS 00231 << " Number of threads:" << nthreads 00232 << " Initialization time:" << setw(10) << setprecision(3) << initTime 00233 << " Calculation time:" << setw(10) << setprecision(3) << calcTime 00234 << endl; 00235 } 00236 }; 00237 00238 #endif // __CONVEX_HULL_H__
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.