Shadowrun: Awakened 29 September 2011 - Build 871
convex_hull.h
Go to the documentation of this file.
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.

GNU Lesser General Public License 3 Sourceforge.net