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