1 //============================================================================
2 //  Copyright (c) Kitware, Inc.
3 //  All rights reserved.
4 //  See LICENSE.txt for details.
5 //
6 //  This software is distributed WITHOUT ANY WARRANTY; without even
7 //  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 //  PURPOSE.  See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_exec_arg_OutputIndex_h
11 #define vtk_m_exec_arg_OutputIndex_h
12 
13 #include <vtkm/exec/arg/ExecutionSignatureTagBase.h>
14 #include <vtkm/exec/arg/Fetch.h>
15 
16 namespace vtkm
17 {
18 namespace exec
19 {
20 namespace arg
21 {
22 
23 /// \brief Aspect tag to use for getting the work index.
24 ///
25 /// The \c AspectTagOutputIndex aspect tag causes the \c Fetch class to ignore
26 /// whatever data is in the associated execution object and return the index
27 /// of the output element.
28 ///
29 struct AspectTagOutputIndex
30 {
31 };
32 
33 /// \brief The \c ExecutionSignature tag to use to get the output index
34 ///
35 /// When a worklet is dispatched, it broken into pieces defined by the output
36 /// domain and scheduled on independent threads. This tag in the \c
37 /// ExecutionSignature passes the index of the output element that the work
38 /// thread is currently working on. When a worklet has a scatter associated
39 /// with it, the output and output indices can be different. \c WorkletBase
40 /// contains a typedef that points to this class.
41 ///
42 struct OutputIndex : vtkm::exec::arg::ExecutionSignatureTagBase
43 {
44   // The index does not really matter because the fetch is going to ignore it.
45   // However, it still has to point to a valid parameter in the
46   // ControlSignature because the templating is going to grab a fetch tag
47   // whether we use it or not. 1 should be guaranteed to be valid since you
48   // need at least one argument for the output domain.
49   static constexpr vtkm::IdComponent INDEX = 1;
50   using AspectTag = vtkm::exec::arg::AspectTagOutputIndex;
51 };
52 
53 template <typename FetchTag, typename ExecObjectType>
54 struct Fetch<FetchTag, vtkm::exec::arg::AspectTagOutputIndex, ExecObjectType>
55 {
56   using ValueType = vtkm::Id;
57 
58   template <typename ThreadIndicesType>
59   VTKM_EXEC vtkm::Id Load(const ThreadIndicesType& indices, const ExecObjectType&) const
60   {
61     return indices.GetOutputIndex();
62   }
63 
64   template <typename ThreadIndicesType>
65   VTKM_EXEC void Store(const ThreadIndicesType&, const ExecObjectType&, const ValueType&) const
66   {
67     // Store is a no-op.
68   }
69 };
70 }
71 }
72 } // namespace vtkm::exec::arg
73 
74 #endif //vtk_m_exec_arg_OutputIndex_h
75