]> https://gitweb.dealii.org/ - dealii.git/blob
f7945d850e8806fb21cac3f38cea81baf4490912
[dealii.git] /
1 /*
2     Copyright 2005-2013 Intel Corporation.  All Rights Reserved.
3
4     This file is part of Threading Building Blocks.
5
6     Threading Building Blocks is free software; you can redistribute it
7     and/or modify it under the terms of the GNU General Public License
8     version 2 as published by the Free Software Foundation.
9
10     Threading Building Blocks is distributed in the hope that it will be
11     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
12     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with Threading Building Blocks; if not, write to the Free Software
17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
19     As a special exception, you may use this file as part of a free software
20     library without restriction.  Specifically, if other files instantiate
21     templates or use macros or inline functions from this file, or you compile
22     this file and link it with other files to produce an executable, this
23     file does not by itself cause the resulting executable to be covered by
24     the GNU General Public License.  This exception does not however
25     invalidate any other reasons why the executable file might be covered by
26     the GNU General Public License.
27 */
28
29 #if __TBB_MIC_OFFLOAD
30 #pragma offload_attribute (push,target(mic))
31 #endif // __TBB_MIC_OFFLOAD
32
33 #include <iostream>
34 #include <string>
35 #include <algorithm>
36
37 #include "tbb/parallel_for.h"
38 #include "tbb/blocked_range.h"
39 #include "tbb/tick_count.h"
40
41 #if __TBB_MIC_OFFLOAD
42 #pragma offload_attribute (pop)
43
44 class __declspec(target(mic)) SubStringFinder;
45 #endif // __TBB_MIC_OFFLOAD
46
47 using namespace tbb;
48 using namespace std;
49 static const size_t N = 22;
50
51 void SerialSubStringFinder ( const string &str, size_t *max_array, size_t *pos_array) {
52  for ( size_t i = 0; i < str.size(); ++i ) {
53    size_t max_size = 0, max_pos = 0;
54    for (size_t j = 0; j < str.size(); ++j)
55     if (j != i) {
56      size_t limit = str.size()-( i > j ? i : j );
57      for (size_t k = 0; k < limit; ++k) {
58       if (str[i + k] != str[j + k]) break;
59       if (k > max_size) {
60        max_size = k;
61        max_pos = j;
62       }
63      }
64     }
65    max_array[i] = max_size;
66    pos_array[i] = max_pos;
67   }
68 }
69
70 class SubStringFinder {
71  const string str;
72  size_t *max_array;
73  size_t *pos_array;
74  public:
75  void operator() ( const blocked_range<size_t>& r ) const {
76   for ( size_t i = r.begin(); i != r.end(); ++i ) {
77    size_t max_size = 0, max_pos = 0;
78    for (size_t j = 0; j < str.size(); ++j) 
79     if (j != i) {
80      size_t limit = str.size()-( i > j ? i : j );
81      for (size_t k = 0; k < limit; ++k) {
82       if (str[i + k] != str[j + k]) break;
83       if (k > max_size) {
84        max_size = k;
85        max_pos = j;
86       }
87      }
88     }
89    max_array[i] = max_size;
90    pos_array[i] = max_pos;
91   }
92  }
93  SubStringFinder(string &s, size_t *m, size_t *p) : 
94   str(s), max_array(m), pos_array(p) { }
95 };
96
97 int main(int argc, char *argv[]) {
98  
99
100  string str[N] = { string("a"), string("b") };
101  for (size_t i = 2; i < N; ++i) str[i] = str[i-1]+str[i-2];
102  string &to_scan = str[N-1]; 
103  size_t num_elem = to_scan.size();
104
105  size_t *max = new size_t[num_elem];
106  size_t *max2 = new size_t[num_elem];
107  size_t *pos = new size_t[num_elem];
108  size_t *pos2 = new size_t[num_elem];
109  cout << " Done building string." << endl;
110
111  
112  tick_count serial_t0 = tick_count::now();
113  SerialSubStringFinder(to_scan, max2, pos2);
114  tick_count serial_t1 = tick_count::now();
115  cout << " Done with serial version." << endl;
116
117  tick_count parallel_t0 = tick_count::now();
118  parallel_for(blocked_range<size_t>(0, num_elem, 100),
119        SubStringFinder( to_scan, max, pos ) );
120  tick_count parallel_t1 = tick_count::now();
121  cout << " Done with parallel version." << endl;
122
123  for (size_t i = 0; i < num_elem; ++i) {
124    if (max[i] != max2[i] || pos[i] != pos2[i]) {
125      cout << "ERROR: Serial and Parallel Results are Different!" << endl;
126    }
127  }
128  cout << " Done validating results." << endl;
129
130  cout << "Serial version ran in " << (serial_t1 - serial_t0).seconds() << " seconds" << endl
131            << "Parallel version ran in " <<  (parallel_t1 - parallel_t0).seconds() << " seconds" << endl
132            << "Resulting in a speedup of " << (serial_t1 - serial_t0).seconds() / (parallel_t1 - parallel_t0).seconds() << endl;
133
134 #if __TBB_MIC_OFFLOAD
135  // Do offloadable version. Do the timing on host.
136  size_t *max3 = new size_t[num_elem];
137  size_t *pos3 = new size_t[num_elem];
138  tick_count parallel_tt0 = tick_count::now();
139  const char* to_scan_str = to_scan.c_str();  // Offload the string as a char array.
140  #pragma offload target(mic) in(num_elem) in(to_scan_str:length(num_elem)) out(max3,pos3:length(num_elem))
141  {
142  string to_scan(to_scan_str, num_elem);      // Reconstruct the string in offloadable region.
143                                              // Suboptimal performance because of making a copy from to_scan_str at creating to_scan.
144  parallel_for(blocked_range<size_t>(0, num_elem, 100),
145        SubStringFinder( to_scan, max3, pos3 ) );
146  }
147  tick_count parallel_tt1 = tick_count::now();
148  cout << " Done with offloadable version." << endl;
149
150  // Do validation of offloadable results on host.
151  for (size_t i = 0; i < num_elem; ++i) {
152    if (max3[i] != max2[i] || pos3[i] != pos2[i]) {
153      cout << "ERROR: Serial and Offloadable Results are Different!" << endl;
154    }
155  }
156  cout << " Done validating offloadable results." << endl;
157
158  cout << "Offloadable version ran in " <<  (parallel_tt1 - parallel_tt0).seconds() << " seconds" << endl
159            << "Resulting in a speedup of " << (serial_t1 - serial_t0).seconds() / (parallel_tt1 - parallel_tt0).seconds() << " of offloadable version" << endl;
160
161  delete[] max3;
162  delete[] pos3;
163 #endif // __TBB_MIC_OFFLOAD
164
165  delete[] max;
166  delete[] pos;
167  delete[] max2;
168  delete[] pos2;
169  return 0;
170 }
171

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.