SkelCL
SkelCL is a high level multi GPU skeleton library developed at the university of Münster, Germany.
 All Classes Namespaces Files Functions Variables Typedefs Groups
Distributions.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2011-2012 The SkelCL Team as listed in CREDITS.txt *
3  * http://skelcl.uni-muenster.de *
4  * *
5  * This file is part of SkelCL. *
6  * SkelCL is available under multiple licenses. *
7  * The different licenses are subject to terms and condition as provided *
8  * in the files specifying the license. See "LICENSE.txt" for details *
9  * *
10  *****************************************************************************
11  * *
12  * SkelCL is free software: you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation, either version 3 of the License, or *
15  * (at your option) any later version. See "LICENSE-gpl.txt" for details. *
16  * *
17  * SkelCL is distributed in the hope that it will be useful, *
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
20  * GNU General Public License for more details. *
21  * *
22  *****************************************************************************
23  * *
24  * For non-commercial academic use see the license specified in the file *
25  * "LICENSE-academic.txt". *
26  * *
27  *****************************************************************************
28  * *
29  * If you are interested in other licensing models, including a commercial- *
30  * license, please contact the author at michel.steuwer@uni-muenster.de *
31  * *
32  *****************************************************************************/
33 
39 
40 #ifndef DISTRIBUTIONS_H_
41 #define DISTRIBUTIONS_H_
42 
43 // include all distributions
44 
45 #include "detail/Distribution.h"
46 #include "detail/BlockDistribution.h"
47 #include "detail/OLDistribution.h"
48 #include "detail/CopyDistribution.h"
49 #include "detail/SingleDistribution.h"
50 
51 namespace skelcl {
52 
55 namespace detail { class Device; }
57 
64 namespace distribution {
65 
66 // to prevent template argument deduction (i.e. template arguments have to be
67 // specified manually)
70 template <typename T>
71 struct identity {
72  typedef T type;
73 };
75 
92 template <template <typename> class C, typename T>
93 std::unique_ptr<skelcl::detail::Distribution<C<T>>>
94  Block( const C<T>& c )
95 {
96  (void)c;
97  return std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
98  new skelcl::detail::BlockDistribution<C<T>>() );
99 }
100 
113 template <template <typename> class C, typename T>
114 void setBlock( const C<T>& c)
115 {
116  c.setDistribution( std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
117  new skelcl::detail::BlockDistribution<C<T>>() ) );
118 }
119 
120 
136 template <template <typename> class C, typename T>
137 std::unique_ptr<skelcl::detail::Distribution<C<T>>>
138  OL( const C<T>& c )
139 {
140  (void)c;
141  return std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
142  new skelcl::detail::OLDistribution<C<T>>() );
143 }
144 
157 template <template <typename> class C, typename T>
158 void setOL( const C<T>& c)
159 {
160  c.setDistribution( std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
161  new skelcl::detail::OLDistribution<C<T>>() ) );
162 }
163 
184 template <template <typename> class C, typename T>
185 std::unique_ptr<skelcl::detail::Distribution<C<T>>>
186  Copy( const C<T>& c,
187  typename identity<std::function<T(const T&, const T&)>>::type
188  combineFunc = nullptr )
189 {
190  (void)c;
191  return std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
192  new skelcl::detail::CopyDistribution<C<T>>(
193  detail::globalDeviceList, combineFunc ) );
194 }
195 
212 template <template <typename> class C, typename T>
213 void setCopy( const C<T>& c,
214  std::function<T(const T&, const T&)> combineFunc = nullptr)
215 {
216  c.setDistribution( std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
217  new skelcl::detail::CopyDistribution<C<T>>(
218  detail::globalDeviceList, combineFunc ) ) );
219 }
220 
237 template <template <typename> class C, typename T>
238 std::unique_ptr<skelcl::detail::Distribution<C<T>>>
239  Single( const C<T>& c )
240 {
241  (void)c;
242  return std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
243  new skelcl::detail::SingleDistribution<C<T>>() );
244 }
245 
263 template <template <typename> class C, typename T>
264 std::unique_ptr<skelcl::detail::Distribution<C<T>>>
265  Single( const C<T>& c,
266  const std::shared_ptr<skelcl::detail::Device>& device )
267 {
268  (void)c;
269  return std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
270  new skelcl::detail::SingleDistribution<C<T>>(device) );
271 }
272 
285 template <template <typename> class C, typename T>
286 void setSingle( const C<T>& c )
287 {
288  c.setDistribution( std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
289  new skelcl::detail::SingleDistribution<C<T>>() ) );
290 }
291 
305 template <template <typename> class C, typename T>
306 void setSingle( const C<T>& c,
307  const std::shared_ptr<skelcl::detail::Device>& device )
308 {
309  c.setDistribution( std::unique_ptr<skelcl::detail::Distribution<C<T>>>(
310  new skelcl::detail::SingleDistribution<C<T>>(device) ) );
311 }
312 
313 } // namespace distribution
314 
315 
318 namespace detail {
319 
320 // provide function to clone arbitrary distribution while changing the
321 // template argument
322 
323 #if 0
324 // This solution does not work in visual studio, but enforces, that OutT and
325 // InT are of the same container type ...
326 template <typename T, typename U, template <typename> class C>
327 std::unique_ptr<Distribution<C<T>>>
328  cloneAndConvert(const Distribution<C<U>>& dist)
329 {
330  // block distribution
331  auto block = dynamic_cast<const BlockDistribution<C<U>>*>(&dist);
332  if (block != nullptr) {
333  return std::unique_ptr<Distribution<C<T>>>(
334  new BlockDistribution<C<T>>(*block) );
335  }
336 
337  // copy distribution
338  auto copy = dynamic_cast<const CopyDistribution<C<U>>*>(&dist);
339  if (copy != nullptr) {
340  return std::unique_ptr<Distribution<C<T>>>(
341  new CopyDistribution<C<T>>(*copy) );
342  }
343 
344  // single distribution
345  auto single = dynamic_cast<const SingleDistribution<C<U>>*>(&dist);
346  if (single != nullptr) {
347  return std::unique_ptr<Distribution<C<T>>>(
348  new SingleDistribution<C<T>>(*single) );
349  }
350 
351  // overlap distribution
352  auto ol = dynamic_cast<const OLDistribution<C<U>>*>(&dist);
353  if (ol != nullptr) {
354  return std::unique_ptr<Distribution<C<T>>>(
355  new OLDistribution<C<T>>(*ol) );
356  }
357 
358  // default distribution
359  return std::unique_ptr<Distribution<C<T>>>(
360  new Distribution<C<T>>(dist) );
361 }
362 #else
363 // This solution works in visual studio, but does not enforce, that OutT and
364 // InT are of the same container type ...
365 template <typename OutT, typename InT>
366 std::unique_ptr<Distribution<OutT>>
367  cloneAndConvert(const Distribution<InT>& dist)
368 {
369  // block distribution
370  auto block = dynamic_cast<const BlockDistribution<InT>*>(&dist);
371  if (block != nullptr) {
372  return std::unique_ptr<Distribution<OutT>>(
373  new BlockDistribution<OutT>(*block));
374  }
375 
376  // copy distribution
377  auto copy = dynamic_cast<const CopyDistribution<InT>*>(&dist);
378  if (copy != nullptr) {
379  return std::unique_ptr<Distribution<OutT>>(
380  new CopyDistribution<OutT>(*copy));
381  }
382 
383  // single distribution
384  auto single = dynamic_cast<const SingleDistribution<InT>*>(&dist);
385  if (single != nullptr) {
386  return std::unique_ptr<Distribution<OutT>>(
387  new SingleDistribution<OutT>(*single));
388  }
389 
390  // overlap distribution
391  auto ol = dynamic_cast<const OLDistribution<InT>*>(&dist);
392  if (ol != nullptr) {
393  return std::unique_ptr<Distribution<OutT>>(
394  new OLDistribution<OutT>(*ol));
395  }
396 
397  // default distribution
398  return std::unique_ptr<Distribution<OutT>>(
399  new Distribution<OutT>(dist));
400 }
401 #endif
402 
403 } // namespace detail
405 
406 } // namespace skelcl
407 
408 #endif // DISTRIBUTIONS_H_
409 
void setSingle(const C< T > &c)
This function sets the distribution of the given container to the SingleDistribution using the defaul...
std::unique_ptr< skelcl::detail::Distribution< C< T > > > OL(const C< T > &c)
Factory function to create an OverlapDistribution with the types of the given container.
void setOL(const C< T > &c)
This function sets the distribution of the given container to the OverlapDistribution.
SKELCL_DLL detail::DeviceID device(size_t dID)
Creates an OpenCL device ID to be used as parameter of the init(detail::PlatformID, detail::DeviceID) function.
Definition: SkelCL.cpp:76
std::unique_ptr< skelcl::detail::Distribution< C< T > > > Block(const C< T > &c)
Factory function to create a BlockDistribution with the types of the given container.
Definition: Distributions.h:94
void setBlock(const C< T > &c)
This function sets the distribution of the given container to the BlockDistribution.
std::unique_ptr< skelcl::detail::Distribution< C< T > > > Copy(const C< T > &c, typename identity< std::function< T(const T &, const T &)>>::type combineFunc=nullptr)
Factory function to create a CopyDistribution with the types of the given container.
void setCopy(const C< T > &c, std::function< T(const T &, const T &)> combineFunc=nullptr)
This function sets the distribution of the given container to the CopyDistribution.
std::unique_ptr< skelcl::detail::Distribution< C< T > > > Single(const C< T > &c)
Factory function to create a SingleDistribution with the types of the given container and for the def...