1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //  This software is distributed WITHOUT ANY WARRANTY; without even
6 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
7 //  PURPOSE.  See the above copyright notice for more information.
8 //
9 //  Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 //  Copyright 2014 UT-Battelle, LLC.
11 //  Copyright 2014 Los Alamos National Security.
12 //
13 //  Under the terms of Contract DE-NA0003525 with NTESS,
14 //  the U.S. Government retains certain rights in this software.
15 //
16 //  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
17 //  Laboratory (LANL), the U.S. Government retains certain rights in
18 //  this software.
19 //============================================================================
20 
21 #include <vtkm/cont/tbb/internal/DeviceAdapterAlgorithmTBB.h>
22 
23 namespace vtkm
24 {
25 namespace cont
26 {
27 
ScheduleTask(vtkm::exec::tbb::internal::TaskTiling1D & functor,vtkm::Id size)28 void DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::ScheduleTask(
29   vtkm::exec::tbb::internal::TaskTiling1D& functor,
30   vtkm::Id size)
31 {
32   const vtkm::Id MESSAGE_SIZE = 1024;
33   char errorString[MESSAGE_SIZE];
34   errorString[0] = '\0';
35   vtkm::exec::internal::ErrorMessageBuffer errorMessage(errorString, MESSAGE_SIZE);
36   functor.SetErrorMessageBuffer(errorMessage);
37 
38   ::tbb::blocked_range<vtkm::Id> range(0, size, tbb::TBB_GRAIN_SIZE);
39 
40   ::tbb::parallel_for(
41     range, [&](const ::tbb::blocked_range<vtkm::Id>& r) { functor(r.begin(), r.end()); });
42 
43   if (errorMessage.IsErrorRaised())
44   {
45     throw vtkm::cont::ErrorExecution(errorString);
46   }
47 }
48 
ScheduleTask(vtkm::exec::tbb::internal::TaskTiling3D & functor,vtkm::Id3 size)49 void DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagTBB>::ScheduleTask(
50   vtkm::exec::tbb::internal::TaskTiling3D& functor,
51   vtkm::Id3 size)
52 {
53   static constexpr vtkm::UInt32 TBB_GRAIN_SIZE_3D[3] = { 1, 4, 256 };
54   const vtkm::Id MESSAGE_SIZE = 1024;
55   char errorString[MESSAGE_SIZE];
56   errorString[0] = '\0';
57   vtkm::exec::internal::ErrorMessageBuffer errorMessage(errorString, MESSAGE_SIZE);
58   functor.SetErrorMessageBuffer(errorMessage);
59 
60   //memory is generally setup in a way that iterating the first range
61   //in the tightest loop has the best cache coherence.
62   ::tbb::blocked_range3d<vtkm::Id> range(0,
63                                          size[2],
64                                          TBB_GRAIN_SIZE_3D[0],
65                                          0,
66                                          size[1],
67                                          TBB_GRAIN_SIZE_3D[1],
68                                          0,
69                                          size[0],
70                                          TBB_GRAIN_SIZE_3D[2]);
71   ::tbb::parallel_for(range, [&](const ::tbb::blocked_range3d<vtkm::Id>& r) {
72     for (vtkm::Id k = r.pages().begin(); k != r.pages().end(); ++k)
73     {
74       for (vtkm::Id j = r.rows().begin(); j != r.rows().end(); ++j)
75       {
76         const vtkm::Id start = r.cols().begin();
77         const vtkm::Id end = r.cols().end();
78         functor(start, end, j, k);
79       }
80     }
81   });
82 
83   if (errorMessage.IsErrorRaised())
84   {
85     throw vtkm::cont::ErrorExecution(errorString);
86   }
87 }
88 }
89 }
90