HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CVEX_Context.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: CVEX_Context.h ( CVEX Library, C++)
7  *
8  * COMMENTS: C++ interface to VEX. This class defines a parameter to the
9  * VEX function.
10  */
11 
12 #ifndef __CVEX_Context__
13 #define __CVEX_Context__
14 
15 #include "CVEX_API.h"
16 #include "CVEX_Function.h"
17 #include "CVEX_ValueList.h"
18 #include "CVEX_Transform.h"
19 #include <VEX/VEX_PodTypes.h>
20 #include <UT/UT_NonCopyable.h>
21 #include <UT/UT_UniquePtr.h>
22 
23 template <VEX_Precision PREC> class cvex_RunData;
24 class UT_OpCaller;
25 template <VEX_Precision PREC> class VEX_AutoInstance;
26 template <VEX_Precision PREC> class VEX_AutoFoldedCode;
27 template <VEX_Precision PREC> class VEX_Instance;
28 class VEX_GeoInputs;
29 template <VEX_Precision PREC> class VEX_GeoCommandQueue;
30 class VEX_ChannelCache;
31 class VEX_FileCache;
32 
33 /// @brief Per-run data for CVEX execution
34 ///
35 /// This class is used to set and retrieve data specific to an individual
36 /// execution run using CVEX_Context::run().
37 template <VEX_Precision PREC>
39 {
40 public:
41  CVEX_RunDataT();
42  ~CVEX_RunDataT();
43 
44  /// Resets the run data for re-use.
45  void clear();
46 
47  /// Set the evaluation time. This is what will be used by op: references
48  /// triggered by VEX commands like volumesample. If not set, the current
49  /// channel time is used instead (if an OP_Director is available).
51  {
52  myTimeSpecified = true;
53  myTransform.setTime(time);
54  }
55 
56  /// Sets the operator working directory. This is used by ch()
57  /// style vex functions to determine where the relative path for
58  /// path resolution should be.
59  /// Use OP_Node::getUniqueId() to pass this in.
60  void setCWDNodeId(int id)
61  {
62  myTransform.setCwdId(id);
63  }
64  /// Sets the operator working directory in the graph proxy,
65  /// this is the same as CWDNodeId for direct proxies, but avoids
66  /// code that assumes that from being confused.
67  void setGraphCWDNodeId(int id)
68  {
69  myTransform.setGraphCwdId(id);
70  }
71  /// The world id is the node which defines the transform space for the CWD.
72  /// If it's not defined the object containing the CWD will be used (or the
73  /// CWD if it's not part of an object network)
74  void setWorldNodeId(int id)
75  {
76  myTransform.setWorldId(id);
77  }
78 
79  /// Sets the OP callback. This is used to setup dependencies on any
80  /// referenced op: expressions. Can be applied to the context at any time.
81  void setOpCaller(UT_OpCaller *caller)
82  {
83  myTransform.setOpCaller(caller);
84  }
85 
86  /// Access to the OP_Caller
87  UT_OpCaller *getOpCaller() const { return myTransform.opCaller(); }
88 
89  /// Sets the OP graph proxy. This is used to look up nodes to allow
90  /// inspection of other nodes within a compiled graph without hitting
91  /// OP_Node. This is thus used when the directGraphProxy isn't being
92  /// used, such as in an Invoke Graph of a geometry network.
93  void setOpGraphProxy(const UT_OpGraphProxy *graph)
94  {
95  myTransform.setOpGraphProxy(graph);
96  }
97 
98  /// Access to the OP_GraphProxy
100  { return myTransform.opGraphProxy(); }
101 
102  /// Returns true when, after running the CVEX_Context, a ch() function
103  /// reported that it was time dependent.
104  bool isTimeDependent() const { return myTimeDependent; }
105 
106  /// Set flag indicating whether there are any time samples involved.
108  {
109  myTimeSampleEncountered = v;
110  }
111 
112  /// Returns true when, after running the CVEX_Context, a usd_attrib()
113  /// function reported that it has some time samples (values at time codes).
115  {
116  return myTimeSampleEncountered;
117  }
118 
119  /// Sets the geo input callback for controlling how opinput: references
120  /// are handled
121  void setGeoInputs(const VEX_GeoInputs *geo)
122  {
123  myGeoInputs = geo;
124  }
125  const VEX_GeoInputs *getGeoInputs() const { return myGeoInputs; }
126 
127  /// Sets the proc id array. Owned by the caller. Must be at least
128  /// the length of your size.
129  void setProcId(exint *procid)
130  {
131  myProcId = procid;
132  }
133  const exint *getProcId() const { return myProcId; }
134 
135  /// Sets the command queue for this context
137  {
138  myGeoCommandQueue = geocmd;
139  }
141  {
142  return myGeoCommandQueue;
143  }
144 
145  VEX_ChannelCache *getChannelCache() { return myChannelCache; }
146 
147  VEX_FileCache* getFileCache() { return myFileCache; }
148 
149  /// Every VEX function has a transform context associated with it. This
150  /// transform context is used by VEX functions like ptransform() to provide
151  /// ways to transform to other spaces (like "space:world" or
152  /// "space:object"). This method allows you to modify the transform
153  /// context of this shader.
154  CVEX_Transform &getTransform() { return myTransform; }
155 
156  /// @{
157  /// Accessors
158  bool timeSpecified() const { return myTimeSpecified; }
159  bool timeDependent() const { return myTimeDependent; }
160  int cwdId() const { return myTransform.cwdId(); }
161  int worldId() const { return myTransform.worldId();}
162  fpreal time() const { return myTransform.time(); }
163  /// @}
164  /// Set as time dependent flag
165  void setTimeDependent(bool v) { myTimeDependent = v; }
166 
167  /// Get the cached VEX_Instance, which can be reused for multiple runs
168  /// until clear() is called.
169  /// This ensures that local word data (e.g. geometry bindings) remain the
170  /// same between runs.
171  VEX_Instance<PREC> *getOrCreateInstance(
172  const VEX_AssemblePtr &assemble,
174 
175 private:
176  CVEX_Transform myTransform;
177  const VEX_GeoInputs *myGeoInputs;
178  VEX_GeoCommandQueue<PREC> *myGeoCommandQueue;
179  exint *myProcId;
180  bool myTimeSpecified;
181  bool myTimeDependent;
182  bool myTimeSampleEncountered;
183  VEX_ChannelCache *myChannelCache;
184  VEX_FileCache *myFileCache;
185 
186  // The VEX_AutoInstance depends on the lifetime of the VEX_Assemble and
187  // VEX_AutoFoldedCode.
188  VEX_AssemblePtr myAssemble;
191 };
192 
194 
197 
198 /// These methods return the meta count and unique id of the global
199 /// cvex function cache. This isn't for this particular context, thus
200 /// is static. If these change, all your contexts allocated before
201 /// will be invalid.
204 
206 {
207  PROBE_ERROR, // Shader hasn't been loaded or there were errors
208  NOT_ASSIGNED, // Variable is not assigned any value
209  CONSTANT_0, // Variable is always set to 0
210  CONSTANT_1, // Variable is always set to 1
211  CONSTANT_VALUE, // Variable is a constant value (not 0 or 1)
212  NOT_CONSTANT, // Variable is not-constant
213 };
214 
215 /// @brief Call VEX from C++
216 ///
217 /// The CVEX_Context class provides the main interface to let C++ code call VEX
218 /// to perform computations. This allows users to modify algorithms by
219 /// performing computations in VEX.
220 /// - VEX automatically takes advantage of SSE
221 /// - VEX can perform run-time optimization
222 template <VEX_Precision PREC>
224 {
225 public:
226  CVEX_ContextT();
227  ~CVEX_ContextT();
228 
229  /// clearing the context will allow you to set up the input and output
230  /// parameters again.
231  /// @note load() must be called again before you can run the VEX code.
232  void clear();
233 
234  /// calling clearAllFunctions() will force all CVEX object code to be
235  /// flushed out of memory and to be reloaded. Be cautioned that this may
236  /// have side-effects, and should only be called at a safe time.
237  /// @note This will also cause *all* functions to be cleared (see clear()).
238  static void clearAllFunctions();
239 
240  /// Removes the given function from the CVEX context.
241  static void clearFunction(const UT_StringRef &fn_name);
242 
243  /// This method will return true if the code referenced by the context has
244  /// been deleted (see @clearAllFunctions()). If you've cached a
245  /// CVEX_Context, then this can be used to see if it's still valid.
246  bool isValid() const;
247 
248  /// Add possible input parameters to the function. These are parameters
249  /// whose values are overridden by values you pass in. If the user's VEX
250  /// function has these parameters the C++ code should assign the values
251  /// after calling load(), but before calling run().
252  ///
253  /// Calling this version of addInput() allows you to defer computing the
254  /// value of the variable until you know whether it will actually be used
255  /// by the VEX function.
256  bool addInput(const UT_StringHolder &name,
257  CVEX_Type type, bool varying);
258 
259  /// If you know the value beforehand, you can add the symbol and it's
260  /// value at the same time.
261  /// Note: The data is referenced, not copied, so keep it live until after
262  /// run() has been called.
263  bool addInput(const UT_StringHolder &name,
264  CVEX_Type type,
265  void *data, int array_size);
266 
267  /// Adds a constant input. You should still maintain the reference
268  /// but the data may be constant folded into the assemble, so the
269  /// values *must* be set ahead of time and possibly will not update
270  /// if you change the original.
271  bool addConstantInput(const UT_StringHolder &name,
272  CVEX_Type type,
273  void *data, int array_size);
274  bool addConstantInput(const UT_StringHolder &name, CVEX_StringArray &strings);
275 
276  /// Add an "string <name>" input. An array length of 1 makes the variable
277  /// uniform.
278  /// Note: The strings are referenced, not copied, so keep it live until
279  /// after run() has been called.
280  bool addInput(const UT_StringHolder &name, CVEX_StringArray &strings);
281 
282  /// Add a required output. If no required output is specified, all
283  /// exports/outputs are computed.
284  /// Note: Due to the varying/uniform state of an output depending
285  /// significantly on the inputs' varying/uniform state -- and operations
286  /// performed -- then, unlike addInput, no storage can be allocated until
287  /// after load.
288  /// Note: If no storage is allocated, the output is still computed but
289  /// the result is thrown away.
290  bool addRequiredOutput(const UT_StringHolder &name, CVEX_Type type);
291 
292  /// Checks if the VEX function by the given name already exists.
293  bool hasFunction(const UT_StringRef &name) const;
294 
295  /// Load the definition of the VEX function.
296  /// Usually VEX functions are loaded from compiled VEX code stored
297  /// in files on the search path. But, callers can use this method to
298  /// define a VEX function from the stream.
299  /// The module name can be optionally overriden with a name argument (if
300  /// it's NULL, the name in the stream is used implicitly).
301  /// The final name of the module is returned in actual_name (if not NULL).
302  /// If override_old is true, if the old function by that name is found,
303  /// then it will be overriden and updated with the new one.
304  bool preloadFile(UT_IStream &is, const char *name,
305  UT_String *actual_name, bool override_old);
306 
307  /// Loads the given file. Instead of registering the loaded
308  /// function in the global function table, returns it as a CVEX_Function
309  CVEX_Function preloadFunction(const UT_StringHolder &snippet);
310  CVEX_Function preloadFunction(UT_IStream &is);
311 
312  /// Loads the functin form the global function table.
313  CVEX_Function preloadGlobalFunction(const char *funcname);
314 
315  /// Load the VEX function.
316  /// Inputs must be specified @b before this function is called. After
317  /// loading, the input list will have flags set telling you whether the
318  /// input parameter is used. At this point, you should set the data for
319  /// all used inputs.
320  ///
321  /// The list of outputs will also be defined, meaning that you can figure
322  /// out what's going to be written by the VEX function.
323  bool load(int argc, const char *const argv[]);
324 
325  /// With load function we already have pre-loaded the CVEX_Function
326  /// so the argv[0] is ignored.
327  bool loadFunction(CVEX_Function function, int argc, const char *const argv[]);
328 
329  /// Quick test to see if the function has been loaded.
330  bool isLoaded() const;
331 
332  /// The list of input parameters to the function. It's possible that
333  /// these values may be shared between the input and output lists.
334  CVEX_ValueListT<PREC> &getInputList() { return myInputs; }
335  const CVEX_ValueListT<PREC> &getInputList() const { return myInputs; }
336 
337  /// Find an input by name/type.
338  const CVEX_ValueT<PREC> *findInput(const UT_StringRef &name, CVEX_Type type) const
339  { return myInputs.getValue(name, type); }
341  { return myInputs.getValue(name, type); }
342 
343  /// Find an input by name.
344  const CVEX_ValueT<PREC> *findInput(const UT_StringRef &name) const
345  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
347  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
348 
349  /// The list of output parameters from the function. After the function
350  /// has been run, the output parameters will have their values written to
351  /// by VEX.
352  ///
353  /// If the output has not had CVEX_Value::setData() called, then the data
354  /// will have been written to internal storage and can be retrieved calling
355  /// CVEX_Value::getData().
356  const CVEX_ValueListT<PREC> &getOutputList() const { return myOutputs; }
357  CVEX_ValueListT<PREC> &getOutputList() { return myOutputs; }
358 
359  /// Find an output by name/type.
360  const CVEX_ValueT<PREC> *findOutput(const UT_StringRef &name, CVEX_Type type) const
361  { return myOutputs.getValue(name, type); }
363  { return myOutputs.getValue(name, type); }
364 
365  /// Find and output by name.
366  const CVEX_ValueT<PREC> *findOutput(const UT_StringRef &name) const
367  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
369  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
370 
371  /// Query the assignment status of an output. This must be called after
372  /// the code has been loaded.
373  CVEX_ProbeResult probeOutput(const UT_StringRef &name,
374  CVEX_Type type) const;
375 
376  /// Initializes the values array with the defaults of the given parameter.
377  /// Leaves values empty if it can't find the parameter.
378  void getParameterDefaults(const UT_StringRef &name,
379  CVEX_Type ctype,
380  UT_DoubleArray &values) const;
381 
382  /// Run the VEX function given a list of input variables and a list of
383  /// output parameters. Each input/output parameter under your control
384  /// should have an array size of either 1 or at least the array_size given
385  /// to the run() method. It's possible to run on fewer array elements
386  /// than have been allocated, but an error will be returned if there are
387  /// input parameters which don't have enough allocation.
388  ///
389  /// Pass in true for interruptable when running from within Houdini.
390  ///
391  /// The run() function may be called multiple times, provided that the
392  /// input parameters don't change. So, if you need to evaluate the data
393  /// in chunks, you can do this by re-initializing the input parameter data
394  /// between calls to run(). However, you should not change the
395  /// uniform/varying state of any input parameters without doing a re-load
396  /// of the VEX function.
397  /// @param array_size The size of varying arrays. All varying arrays must
398  /// be this size.
399  /// @param interruptable If true, VEX will check the state of the
400  /// UT_Interrupt. This should be enabled when called from within
401  /// Houdini. If interruptable is false, then the user will @b not be
402  /// able to break out of endless loops in VEX. It's better to leave it
403  /// true if you are unsure.
404  /// @param rundata Data that matches the precision PREC.
405  bool run(int array_size, bool interruptable,
406  CVEX_RunDataT<PREC> *rundata = nullptr);
407 
408  /// If load() or run() return false, this will return the error that
409  /// triggered the CVEX failure. Note that this is distinct from errors
410  // and warnings occurring when running VEX.
411  const char *getLastError() const { return myError; }
412 
413  /// If load() or run() failed or reported warnings, these methods will
414  /// return the errors reported by VEX.
415  /// {
416  const UT_String &getVexErrors() const;
417  const UT_String &getVexWarnings() const;
418  /// }
419 
420  /// Clear the errors reported by getVexErrors() / getVexWarnings().
421  void clearVexErrors();
422 
423  /// Add Constant Integer 32 Arrays
424  bool addConstantInput(const UT_StringHolder &name, UT_PackedArrayOfArrays<VEXint<PREC> > &intdata);
425 
426 private:
427  struct cvex_BoundValue
428  {
429  cvex_BoundValue()
430  : myValue(nullptr)
431  , myBindPtr(nullptr)
432  , myStoragePtr(nullptr)
433  {}
434  CVEX_ValueT<PREC>*myValue;
435  void *myBindPtr;
436  void *myStoragePtr;
437  };
438 
439  bool validateValue(const CVEX_ValueT<PREC> &value,
440  VEX_Instance<PREC> &state, int nproc);
441  void copyBoundData(cvex_BoundValue &bound,
443  int start, int nproc);
444  bool bindValues(UT_Array<cvex_BoundValue> &bound_vals,
445  VEX_Instance<PREC> &state, int nproc);
446  void extractStrings(CVEX_ValueT<PREC> &value,
448  int start, int nproc);
449  void extractDicts(CVEX_ValueT<PREC> &value,
451  int start, int nproc);
452  void extractArrays(CVEX_ValueT<PREC> &value,
454  int start, int nproc);
455  void extractUniform(CVEX_ValueT<PREC> &value,
457 
458  bool loadPrivate(const VEX_AssemblePtr &as,
459  int argc, const char *const argv[]);
460 
461  CVEX_ValueListT<PREC> myInputs;
462  CVEX_ValueListT<PREC> myOutputs;
464  UT_String myError;
465 
466  UT_Array<cvex_BoundValue> myBoundVals;
467 
468  UT_Array<VEXint<PREC>*> &getTempI() { myTempI.clear(); return myTempI; }
469  UT_Array<VEXfloat<PREC>*> &getTempF() { myTempF.clear(); return myTempF; }
470 
471  UT_Array<VEXfloat<PREC>*> myTempF;
472  UT_Array<VEXint<PREC>*> myTempI;
473 };
474 
476 
479 
480 #endif
const char * getLastError() const
Definition: CVEX_Context.h:411
CVEX_ValueListT< PREC > & getInputList()
Definition: CVEX_Context.h:334
const VEX_GeoInputs * getGeoInputs() const
Definition: CVEX_Context.h:125
VEX_ChannelCache * getChannelCache()
Definition: CVEX_Context.h:145
fpreal time() const
Definition: CVEX_Context.h:162
VEX_FileCache * getFileCache()
Definition: CVEX_Context.h:147
GT_API const UT_StringHolder time
const GLdouble * v
Definition: glcorearb.h:837
CVEX_API exint CVEXgetGlobalContextUniqueId()
bool timeSpecified() const
Definition: CVEX_Context.h:158
GLuint start
Definition: glcorearb.h:475
GLsizei const GLfloat * value
Definition: glcorearb.h:824
const CVEX_ValueT< PREC > * findInput(const UT_StringRef &name) const
Find an input by name.
Definition: CVEX_Context.h:344
UT_OpCaller * getOpCaller() const
Access to the OP_Caller.
Definition: CVEX_Context.h:87
void setGraphCWDNodeId(int id)
Definition: CVEX_Context.h:67
void setWorldNodeId(int id)
Definition: CVEX_Context.h:74
const exint * getProcId() const
Definition: CVEX_Context.h:133
int64 exint
Definition: SYS_Types.h:125
void setGeoInputs(const VEX_GeoInputs *geo)
Definition: CVEX_Context.h:121
void setTimeDependent(bool v)
Definition: CVEX_Context.h:165
const CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name, CVEX_Type type) const
Find an output by name/type.
Definition: CVEX_Context.h:360
const UT_OpGraphProxy * getOpGraphProxy() const
Access to the OP_GraphProxy.
Definition: CVEX_Context.h:99
CVEX_ValueT< PREC > * findInput(const UT_StringRef &name)
Definition: CVEX_Context.h:346
VEX_GeoCommandQueue< PREC > * getGeoCommandQueue() const
Definition: CVEX_Context.h:140
const CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name) const
Find and output by name.
Definition: CVEX_Context.h:366
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
List of input or output values for a CVEX_Context.
A class representing a VEX value.
Definition: CVEX_Value.h:60
int cwdId() const
Definition: CVEX_Context.h:160
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
void setCWDNodeId(int id)
Definition: CVEX_Context.h:60
bool isTimeDependent() const
Definition: CVEX_Context.h:104
const CVEX_ValueListT< PREC > & getInputList() const
Definition: CVEX_Context.h:335
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
void setTimeSampleEncountered(bool v)
Set flag indicating whether there are any time samples involved.
Definition: CVEX_Context.h:107
const CVEX_ValueT< PREC > * findInput(const UT_StringRef &name, CVEX_Type type) const
Find an input by name/type.
Definition: CVEX_Context.h:338
void setTime(fpreal time)
Definition: CVEX_Context.h:50
CVEX_ProbeResult
Definition: CVEX_Context.h:205
void setProcId(exint *procid)
Definition: CVEX_Context.h:129
GLuint const GLchar * name
Definition: glcorearb.h:786
GLsizei const GLchar *const * strings
Definition: glcorearb.h:1933
CVEX_Type
The CVEX_Type enum defines the VEX types available to CVEX.
Definition: CVEX_Value.h:29
CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name)
Definition: CVEX_Context.h:368
int worldId() const
Definition: CVEX_Context.h:161
CVEX_ValueListT< PREC > & getOutputList()
Definition: CVEX_Context.h:357
CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Context.h:362
A class holding a VEX function.
Definition: CVEX_Function.h:30
void setGeoCommandQueue(VEX_GeoCommandQueue< PREC > *geocmd)
Sets the command queue for this context.
Definition: CVEX_Context.h:136
const CVEX_ValueListT< PREC > & getOutputList() const
Definition: CVEX_Context.h:356
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1602
CVEX_Transform & getTransform()
Definition: CVEX_Context.h:154
fpreal64 fpreal
Definition: SYS_Types.h:283
#define CVEX_API
Definition: CVEX_API.h:12
CVEX_ValueT< PREC > * findInput(const UT_StringRef &name, CVEX_Type type)
Definition: CVEX_Context.h:340
CVEX_EXTERN_TEMPLATE(CVEX_RunDataT< VEX_32 >)
void setOpGraphProxy(const UT_OpGraphProxy *graph)
Definition: CVEX_Context.h:93
Per-run data for CVEX execution.
Definition: CVEX_Context.h:38
typename VEX_PrecisionResolver< P >::int_type VEXint
Definition: VEX_PodTypes.h:68
bool timeDependent() const
Definition: CVEX_Context.h:159
void setOpCaller(UT_OpCaller *caller)
Definition: CVEX_Context.h:81
void clear()
Resets list to an empty list.
Definition: UT_Array.h:753
bool isTimeSampleEncountered() const
Definition: CVEX_Context.h:114
Call VEX from C++.
Definition: CVEX_Context.h:223
state
Definition: core.h:2289
Definition: format.h:1821
CVEX_API exint CVEXgetGlobalContextClearCount()