OpenVDB 13.0.1
Loading...
Searching...
No Matches
VolumeExecutable.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/// @file compiler/VolumeExecutable.h
5///
6/// @authors Nick Avramoussis, Francisco Gochez, Richard Jones
7///
8/// @brief The VolumeExecutable, produced by the OpenVDB AX Compiler for
9/// execution over Numerical OpenVDB Grids.
10///
11
12#ifndef OPENVDB_AX_COMPILER_VOLUME_EXECUTABLE_HAS_BEEN_INCLUDED
13#define OPENVDB_AX_COMPILER_VOLUME_EXECUTABLE_HAS_BEEN_INCLUDED
14
15#include "CustomData.h"
16#include "AttributeRegistry.h"
17#include "AttributeBindings.h"
18
19#include <openvdb/version.h>
20#include <openvdb/Grid.h>
21
22#include <llvm/Config/llvm-config.h>
23
24#include <unordered_map>
25
26struct TestVolumeExecutableAcc;
27
28/// @cond OPENVDB_DOCS_INTERNAL
29namespace llvm {
30class ExecutionEngine;
31class LLVMContext;
32namespace orc {
33class LLJIT;
34}
35}
36/// @endcond
37
38namespace openvdb {
40namespace OPENVDB_VERSION_NAME {
41namespace ax {
42
43class Compiler;
44
45/// @brief Object that encapsulates compiled AX code which can be executed on a
46/// collection of VDB volume grids. Executables are created by the compiler
47/// and hold the final immutable JIT compiled function and context.
48/// @details The VolumeExecutable is returned from the ax::Compiler when
49/// compiling AX code for volume execution. The class represents a typical AX
50/// executable object; immutable except for execution settings and implements
51/// 'execute' functions which can be called multiple times for arbitrary sets
52/// of inputs. The intended usage of these executables is to configure their
53/// runtime arguments and then call VolumeExecutable::execute with your VDBs.
54/// For example:
55/// @code
56/// VolumeExecutable::Ptr exe = compiler.compile<VolumeExecutable>("@a += 1");
57/// exe->setTreeExecutionLevel(0); // only process leaf nodes
58/// exe->setValueIterator(VolumeExecutable::IterType::ALL); // process all values
59/// exe->execute(vdbs); // run on a set of vdbs
60/// exe->execute(grid); // run on a single vdb
61/// @endcode
62///
63/// The Volume executable is initialised with specific configurable settings:
64/// - Iteration Level: min=0, max=RootNode::Level.
65/// By default, processes the entire VDB tree hierarchy.
66/// @sa setTreeExecutionLevel
67/// - Iteration Type: ON
68/// By default, processes ACTIVE values.
69/// @sa setValueIterator
70/// - Active Tile Streaming: ON, OFF or AUTO depending on AX code.
71/// By default, if AX detects that the AX program may produce unique
72/// values for leaf level voxels that would otherwise comprise a
73/// given active tile, this setting is set to ON or AUTO. Otherwise it is
74/// set to OFF.
75/// @sa setActiveTileStreaming
76/// - Grain sizes: 1:32
77/// The default grain sizes passed to the tbb partitioner for leaf level
78/// processing and active tile processing.
79/// @sa setGrainSize
80/// @sa setActiveTileStreamingGrainSize
81/// - AttributeBindings: None
82/// Whether to indriect any AX accesses to different grid names.
83/// @sa setAttributeBindings
84///
85/// For more in depth information, see the @ref vdbaxcompilerexe documentation.
87{
88public:
89 using Ptr = std::shared_ptr<VolumeExecutable>;
91
92 /// @brief Copy constructor. Shares the LLVM constructs but deep copies the
93 /// settings. Multiple copies of an executor can be used at the same time
94 /// safely.
96
97 ////////////////////////////////////////////////////////
98
99 ///@{
100 /// @brief Run this volume executable binary on target volumes.
101 /// @details This method reads from the stored settings on the executable
102 /// to determine certain behaviour and runs the JIT compiled function
103 /// across every valid VDB value. Topology may be changed, deleted or
104 /// created.
105 ///
106 /// This method is thread safe; it can be run concurrently from the same
107 /// VolumeExecutable instance on different inputs.
108 ///
109 /// @param grids The VDB Volumes to process
110 void execute(openvdb::GridPtrVec& grids) const;
111 void execute(openvdb::GridBase& grids) const;
112 ///@}
113
114 ////////////////////////////////////////////////////////
115
116 /// @brief Set the behaviour when missing grids are accessed. Default
117 /// behaviour is true, which creates them with default transforms and
118 /// background values
119 /// @param flag Enables or disables the creation of missing attributes
120 void setCreateMissing(const bool flag);
121 /// @return Whether this executable will generate new grids.
122 bool getCreateMissing() const;
123
124 /// @brief Set the execution level for this executable. This controls what
125 /// nodes are processed when execute is called. Possible values depend on
126 /// the OpenVDB configuration in use, however a value of 0 will always
127 /// correspond to the lowest level (leaf-level). By default, the min
128 /// level is zero (LeafNodeType::LEVEL) and the max level is the root
129 /// node's level (RootNodeType::LEVEL). In other words, the default
130 /// execution level settings process the whole of the tree.
131 /// @note A value larger that the number of levels in the tree (i.e. larger
132 /// than the root node's level) will cause this method to throw a runtime
133 /// error.
134 /// @param min The minimum tree execution level to set
135 /// @param max The maximum tree execution level to set
136 void setTreeExecutionLevel(const Index min, const Index max);
137 /// @param level The tree execution level to set. Calls setTreeExecutionLevel
138 /// with min and max arguments as level.
139 void setTreeExecutionLevel(const Index level);
140 /// @brief Get the tree execution levels.
141 /// @param min The minimum tree execution level
142 /// @param max The maximum tree execution level
143 void getTreeExecutionLevel(Index& min, Index& max) const;
144
145 /// @brief The streaming type of active tiles during execution.
146 /// @param ON active tiles are temporarily densified (converted to leaf
147 /// level voxels) on an "as needed" basis and the subsequent voxel
148 /// values are processed. The temporarily densified node is added to the
149 /// tree only if a non constant voxel buffer is produced. Otherwise a
150 /// child tile may be created or the original tile's value may simply be
151 /// modified.
152 /// @param OFF tile topologies are left unchanged and their single value is
153 /// processed.
154 /// @param AUTO the volume executable analyzes the compiled kernel and
155 /// attempts to determine if expansion of active tiles would lead to
156 /// different, non-constant values in the respective voxels. This is
157 /// done on a per grid basis; ultimately each execution will be set to
158 /// ON or OFF. This option will always fall back to ON if there is any
159 /// chance the kernel may produce child nodes
160 ///
161 /// @note The volume executable always runs an AUTO check on creation and
162 /// will set itself to ON (if all grids always need child nodes), OFF (if
163 /// grids never need child nodes) or remains as AUTO (if this depends on
164 /// which grid is being processed).
165 ///
166 /// @details When an AX kernel is run over coarser levels of the tree (i.e.
167 /// not leaf voxels), it is often desirable to densify these areas into
168 /// unique voxels such that they can each receive a unique value. For
169 /// example, consider the following AX code which assigns a vector volume
170 /// to the world space position of each voxel:
171 /// @code
172 /// v@v = getvoxelpws();
173 /// @endcode
174 /// Active tiles hold a single value but comprise an area greater than
175 /// that of a single voxel. As the above kernel varies with respect to
176 /// a nodes position, we'd need to replace these tiles with leaf voxels
177 /// to get unique per node values. The stream flag is initialised to ON
178 /// in this case.
179 ///
180 /// This behaviour, however, is not always desirable .i.e:
181 /// @code
182 /// v@v = {1,2,3};
183 /// @endcode
184 /// In this instance, all values within a volume receive the same value
185 /// and are not dependent on any spatially or iteratively varying
186 /// metrics. The stream flag is set to OFF.
187 ///
188 /// The AUTO flag is set in cases where the runtime access pattern of the
189 /// inputs determines streaming:
190 /// @code
191 /// f@density = f@mask;
192 /// f@mask = 0;
193 /// @endcode
194 /// In this instance, the runtime topology and values of \@mask determines
195 /// whether child topology needs to be created in \@density, but \@mask
196 /// itself does not need streaming. Streaming will be set to ON for
197 /// density but OFF for mask.
198 ///
199 /// @note This behaviour is only applied to active tiles. If the value
200 /// iterator is set to OFF, this option is ignored.
201 /// @warning This option can generate large amounts of leaf level voxels.
202 /// It is recommended to use a good concurrent memory allocator (such as
203 /// jemalloc) for the best performance.
204 enum class Streaming { ON, OFF, AUTO };
205 /// @brief Controls the behaviour of expansion of active tiles.
206 /// @param s The behaviour to set
208 /// @return The current stream behaviour.
210 /// @return The current stream behaviour for a particular grid. This is
211 /// either ON or OFF.
212 /// @param name The name of the grid to query
213 /// @param type The grids type
214 Streaming getActiveTileStreaming(const std::string& name,
215 const ast::tokens::CoreType& type) const;
216
217 enum class IterType { ON, OFF, ALL };
218 /// @brief Set the value iterator type to use with this executable. Options
219 /// are ON, OFF, ALL. Default is ON.
220 /// @param iter The value iterator type to set
221 void setValueIterator(const IterType& iter);
222 /// @return The current value iterator type
224
225 ///@{
226 /// @brief Set the threading grain sizes used when iterating over nodes
227 /// in a VDB.
228 /// @details Two grain sizes are provided, the first of which (g1) is used
229 /// to determine the chunk size of nodes which are not being streamed (see
230 /// setActiveTileStream). Leaf node execution always uses this grain size.
231 /// The default value for g1 is 1 which is typically appropriate for most
232 /// AX kernels.
233 /// The second grain size is used when streaming execution over active
234 /// tiles in a VDB. This execution model differs significantly from
235 /// typical leaf node execution due to the potential for substantially
236 /// more memory to be allocated. The default value is 32, which works well
237 /// for the default configuration of OpenVDB. If streaming is disabled,
238 /// this value has no effect.
239 /// @note Setting g1 or g2 to zero has the effect of disabling
240 /// multi-threading for the respective node executions. Setting both to
241 /// zero will disable all multi-threading performed by the execute method.
242 void setGrainSize(const size_t g1);
243 void setActiveTileStreamingGrainSize(const size_t g2);
244 /// @return The current g1 grain size
245 /// @sa setGrainSize
246 size_t getGrainSize() const;
247 /// @return The current g2 grain size
248 /// @sa setActiveTileStreamingGrainSize
250 ///@}
251
252 /// @brief Set attribute bindings.
253 /// @param bindings A map of attribute bindings to expected names on
254 /// the geometry to be executed over. By default the AX attributes will be
255 /// bound to volumes of the same name. Supplying bindings
256 /// for a subset of the attributes will leave the others unchanged.
257 /// AX attributes can only bind to a single volume and vice versa.
258 /// However, in a single set call these can be swapped e.g. a -> b and b -> a.
259 /// When bindings are overriden through subsequent calls to this function,
260 /// any dangling volumes will be automatically bound by name.
261 /// To reset these bindings call get function and create a target set of bindings
262 /// for each attribute of name -> name.
264 /// @return The current attribute bindings map
266
267 ////////////////////////////////////////////////////////
268
269 // foward declaration of settings for this executable
270 template <bool> struct Settings;
271
272 /// @brief Command Line Interface handling for the VolumeExecutable.
273 /// @details This class wraps the logic for converting commands specific
274 /// to the VolumeExecutable to the internal Settings. Subsequent
275 /// executables can be initialized from the CLI object that gets created.
277 {
281 static CLI create(size_t argc, const char* argv[], bool* used=nullptr);
282 static void usage(std::ostream& os, const bool verbose);
283 private:
284 friend class VolumeExecutable;
285 CLI();
286 std::unique_ptr<Settings<true>> mSettings;
287 };
288
289 /// @brief Intialize the Settings of this executables from the CLI object
290 /// @param cli The CLI object
291 /// @{
292 void setSettingsFromCLI(const CLI& cli);
293 /// @}
294
295 ////////////////////////////////////////////////////////
296
297 /// @return The tree execution level.
298 OPENVDB_DEPRECATED_MESSAGE("Use getTreeExecutionLevel(Index&, Index&)")
300
301private:
302 friend class Compiler;
303 friend struct ::TestVolumeExecutableAcc;
304
305 /// @brief Constructor, expected to be invoked by the compiler. Should not
306 /// be invoked directly.
307 /// @param context Shared pointer to an llvm:LLVMContext associated with the
308 /// execution engine
309 /// @param engine Shared pointer to an llvm::ExecutionEngine used to build
310 /// functions. Context should be the associated LLVMContext
311 /// @param accessRegistry Registry of volumes accessed by AX code
312 /// @param customData Custom data which will be shared by this executable.
313 /// It can be used to retrieve external data from within the AX code
314 /// @param functions A map of function names to physical memory addresses
315 /// which were built by llvm using engine
316 /// @param tree The AST linked to this executable. The AST is not stored
317 /// after compilation but can be used during construction of the exe to
318 /// infer some pre/post processing optimisations.
320#if LLVM_VERSION_MAJOR <= 15
321 const std::shared_ptr<const llvm::LLVMContext>& context,
322 const std::shared_ptr<const llvm::ExecutionEngine>& engine,
323#else
324 const std::shared_ptr<const llvm::orc::LLJIT>& mExecutionEngine,
325#endif
326 const AttributeRegistry::ConstPtr& accessRegistry,
327 const CustomData::ConstPtr& customData,
328 const std::unordered_map<std::string, uint64_t>& functions,
329 const ast::Tree& tree);
330
331private:
332#if LLVM_VERSION_MAJOR <= 15
333 // The Context and ExecutionEngine must exist _only_ for object lifetime
334 // management. The ExecutionEngine must be destroyed before the Context
335 const std::shared_ptr<const llvm::LLVMContext> mContext;
336 const std::shared_ptr<const llvm::ExecutionEngine> mExecutionEngine;
337#else
338 const std::shared_ptr<const llvm::orc::LLJIT> mExecutionEngine;
339#endif
340 const AttributeRegistry::ConstPtr mAttributeRegistry;
341 const CustomData::ConstPtr mCustomData;
342 const std::unordered_map<std::string, uint64_t> mFunctionAddresses;
343 std::unique_ptr<Settings<false>> mSettings;
344};
345
346} // namespace ax
347} // namespace OPENVDB_VERSION_NAME
348} // namespace openvdb
349
350#endif // OPENVDB_AX_COMPILER_VOLUME_EXECUTABLE_HAS_BEEN_INCLUDED
351
The Attribute Bindings class is used by the compiled Executables to handle the mapping of AX Attribut...
These classes contain lists of expected attributes and volumes which are populated by compiler during...
Access to the CustomData class which can provide custom user user data to the OpenVDB AX Compiler.
#define OPENVDB_AX_API
Definition Platform.h:312
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:171
Abstract base class for typed grids.
Definition Grid.h:78
This class wraps an interface for a map of attribute bindings. These map attributes in AX code to con...
Definition AttributeBindings.h:37
std::shared_ptr< const AttributeRegistry > ConstPtr
Definition AttributeRegistry.h:43
std::shared_ptr< const CustomData > ConstPtr
Definition CustomData.h:38
friend struct ::TestVolumeExecutableAcc
Definition VolumeExecutable.h:303
void setActiveTileStreamingGrainSize(const size_t g2)
Set the threading grain sizes used when iterating over nodes in a VDB.
void setCreateMissing(const bool flag)
Set the behaviour when missing grids are accessed. Default behaviour is true, which creates them with...
const AttributeBindings & getAttributeBindings() const
void execute(openvdb::GridBase &grids) const
Run this volume executable binary on target volumes.
friend class Compiler
Definition VolumeExecutable.h:302
void getTreeExecutionLevel(Index &min, Index &max) const
Get the tree execution levels.
Streaming getActiveTileStreaming() const
std::shared_ptr< VolumeExecutable > Ptr
Definition VolumeExecutable.h:89
void setValueIterator(const IterType &iter)
Set the value iterator type to use with this executable. Options are ON, OFF, ALL....
void setActiveTileStreaming(const Streaming &s)
Controls the behaviour of expansion of active tiles.
void setGrainSize(const size_t g1)
Set the threading grain sizes used when iterating over nodes in a VDB.
Streaming getActiveTileStreaming(const std::string &name, const ast::tokens::CoreType &type) const
void setTreeExecutionLevel(const Index min, const Index max)
Set the execution level for this executable. This controls what nodes are processed when execute is c...
void setSettingsFromCLI(const CLI &cli)
Intialize the Settings of this executables from the CLI object.
Streaming
The streaming type of active tiles during execution.
Definition VolumeExecutable.h:204
@ OFF
Definition VolumeExecutable.h:204
@ ON
Definition VolumeExecutable.h:204
@ AUTO
Definition VolumeExecutable.h:204
void setTreeExecutionLevel(const Index level)
IterType
Definition VolumeExecutable.h:217
@ ALL
Definition VolumeExecutable.h:217
void execute(openvdb::GridPtrVec &grids) const
Run this volume executable binary on target volumes.
void setAttributeBindings(const AttributeBindings &bindings)
Set attribute bindings.
size_t getActiveTileStreamingGrainSize() const
VolumeExecutable(const VolumeExecutable &other)
Copy constructor. Shares the LLVM constructs but deep copies the settings. Multiple copies of an exec...
CoreType
Definition Tokens.h:32
Definition PointDataGrid.h:170
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
Index32 Index
Definition Types.h:34
Definition Exceptions.h:13
Command Line Interface handling for the VolumeExecutable.
Definition VolumeExecutable.h:277
friend class VolumeExecutable
Definition VolumeExecutable.h:284
static void usage(std::ostream &os, const bool verbose)
static CLI create(size_t argc, const char *argv[], bool *used=nullptr)
Definition VolumeExecutable.h:270
A Tree is the highest concrete (non-abstract) node in the entire AX AST hierarchy....
Definition AST.h:563
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218