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  /// This method will return true if the code referenced by the context has
193  /// been deleted (see @clearAllFunctions()). If you've cached a
194  /// CVEX_Context, then this can be used to see if it's still valid.
195  bool isValid() const;
196 
197  /// Add possible input parameters to the function. These are parameters
198  /// whose values are overridden by values you pass in. If the user's VEX
199  /// function has these parameters the C++ code should assign the values
200  /// after calling load(), but before calling run().
201  ///
202  /// Calling this version of addInput() allows you to defer computing the
203  /// value of the variable until you know whether it will actually be used
204  /// by the VEX function.
205  bool addInput(const UT_StringHolder &name,
206  CVEX_Type type, bool varying);
207 
208  /// If you know the value beforehand, you can add the symbol and it's
209  /// value at the same time.
210  /// Note: The data is referenced, not copied, so keep it live until after
211  /// run() has been called.
212  bool addInput(const UT_StringHolder &name,
213  CVEX_Type type,
214  void *data, int array_size);
215 
216  /// Adds a constant input. You should still maintain the reference
217  /// but the data may be constant folded into the assemble, so the
218  /// values *must* be set ahead of time and possibly will not update
219  /// if you change the original.
220  bool addConstantInput(const UT_StringHolder &name,
221  CVEX_Type type,
222  void *data, int array_size);
223  bool addConstantInput(const UT_StringHolder &name, CVEX_StringArray &strings);
224 
225  /// Add an "string <name>" input. An array length of 1 makes the variable
226  /// uniform.
227  /// Note: The strings are referenced, not copied, so keep it live until
228  /// after run() has been called.
229  bool addInput(const UT_StringHolder &name, CVEX_StringArray &strings);
230 
231  /// Add a required output. If no required output is specified, all
232  /// exports/outputs are computed.
233  /// Note: Due to the varying/uniform state of an output depending
234  /// significantly on the inputs' varying/uniform state -- and operations
235  /// performed -- then, unlike addInput, no storage can be allocated until
236  /// after load.
237  /// Note: If no storage is allocated, the output is still computed but
238  /// the result is thrown away.
239  bool addRequiredOutput(const UT_StringHolder &name, CVEX_Type type);
240 
241  /// Checks if the VEX function by the given name already exists.
242  bool hasFunction(const UT_StringRef &name) const;
243 
244  /// Load the definition of the VEX function.
245  /// Usually VEX functions are loaded from compiled VEX code stored
246  /// in files on the search path. But, callers can use this method to
247  /// define a VEX function from the stream.
248  /// The module name can be optionally overriden with a name argument (if
249  /// it's NULL, the name in the stream is used implicitly).
250  /// The final name of the module is returned in actual_name (if not NULL).
251  /// If override_old is true, if the old function by that name is found,
252  /// then it will be overriden and updated with the new one.
253  bool preloadFile(UT_IStream &is, const char *name,
254  UT_String *actual_name, bool override_old);
255 
256  /// Loads the given file. Instead of registering the loaded
257  /// function in the global function table, returns it as a CVEX_Function
258  CVEX_Function preloadFunction(UT_IStream &is);
259 
260  /// Loads the functin form the global function table.
261  CVEX_Function preloadGlobalFunction(const char *funcname);
262 
263  /// Load the VEX function.
264  /// Inputs must be specified @b before this function is called. After
265  /// loading, the input list will have flags set telling you whether the
266  /// input parameter is used. At this point, you should set the data for
267  /// all used inputs.
268  ///
269  /// The list of outputs will also be defined, meaning that you can figure
270  /// out what's going to be written by the VEX function.
271  bool load(int argc, const char *const argv[]);
272 
273  /// With load function we already have pre-loaded the CVEX_Function
274  /// so the argv[0] is ignored.
275  bool loadFunction(CVEX_Function function, int argc, const char *const argv[]);
276 
277  /// Quick test to see if the function has been loaded.
278  bool isLoaded() const;
279 
280  /// The list of input parameters to the function. It's possible that
281  /// these values may be shared between the input and output lists.
282  CVEX_ValueListT<PREC> &getInputList() { return myInputs; }
283  const CVEX_ValueListT<PREC> &getInputList() const { return myInputs; }
284 
285  /// Find an input by name/type.
286  const CVEX_ValueT<PREC> *findInput(const UT_StringRef &name, CVEX_Type type) const
287  { return myInputs.getValue(name, type); }
289  { return myInputs.getValue(name, type); }
290 
291  /// Find an input by name.
292  const CVEX_ValueT<PREC> *findInput(const UT_StringRef &name) const
293  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
295  { return myInputs.getValue(name, CVEX_TYPE_INVALID); }
296 
297  /// The list of output parameters from the function. After the function
298  /// has been run, the output parameters will have their values written to
299  /// by VEX.
300  ///
301  /// If the output has not had CVEX_Value::setData() called, then the data
302  /// will have been written to internal storage and can be retrieved calling
303  /// CVEX_Value::getData().
304  const CVEX_ValueListT<PREC> &getOutputList() const { return myOutputs; }
305  CVEX_ValueListT<PREC> &getOutputList() { return myOutputs; }
306 
307  /// Find an output by name/type.
308  const CVEX_ValueT<PREC> *findOutput(const UT_StringRef &name, CVEX_Type type) const
309  { return myOutputs.getValue(name, type); }
311  { return myOutputs.getValue(name, type); }
312 
313  /// Find and output by name.
314  const CVEX_ValueT<PREC> *findOutput(const UT_StringRef &name) const
315  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
317  { return myOutputs.getValue(name, CVEX_TYPE_INVALID); }
318 
319  /// Initializes the values array with the defaults of the given parameter.
320  /// Leaves values empty if it can't find the parameter.
321  void getParameterDefaults(const UT_StringRef &name,
322  CVEX_Type ctype,
323  UT_DoubleArray &values) const;
324 
325  /// Run the VEX function given a list of input variables and a list of
326  /// output parameters. Each input/output parameter under your control
327  /// should have an array size of either 1 or at least the array_size given
328  /// to the run() method. It's possible to run on fewer array elements
329  /// than have been allocated, but an error will be returned if there are
330  /// input parameters which don't have enough allocation.
331  ///
332  /// Pass in true for interruptable when running from within Houdini.
333  ///
334  /// The run() function may be called multiple times, provided that the
335  /// input parameters don't change. So, if you need to evaluate the data
336  /// in chunks, you can do this by re-initializing the input parameter data
337  /// between calls to run(). However, you should not change the
338  /// uniform/varying state of any input parameters without doing a re-load
339  /// of the VEX function.
340  /// @param array_size The size of varying arrays. All varying arrays must
341  /// be this size.
342  /// @param interruptable If true, VEX will check the state of the
343  /// UT_Interrupt. This should be enabled when called from within
344  /// Houdini. If interruptable is false, then the user will @b not be
345  /// able to break out of endless loops in VEX. It's better to leave it
346  /// true if you are unsure.
347  /// @param rundata Data that matches the precision PREC.
348  bool run(int array_size, bool interruptable,
349  CVEX_RunData *rundata = nullptr);
350 
351  /// If load() or run() return false, this will return the error that
352  /// triggered the CVEX failure. Note that this is distinct from errors
353  // and warnings occurring when running VEX.
354  const char *getLastError() const { return myError; }
355 
356  /// If load() or run() failed or reported warnings, these methods will
357  /// return the errors reported by VEX.
358  /// {
359  const UT_String &getVexErrors() const;
360  const UT_String &getVexWarnings() const;
361  /// }
362 
363  /// Clear the errors reported by getVexErrors() / getVexWarnings().
364  void clearVexErrors();
365 
366  /// Add Constant Integer 32 Arrays
367  bool addConstantInput(const UT_StringHolder &name, UT_PackedArrayOfArrays<VEXint<PREC> > &intdata);
368 
369 private:
370  struct cvex_BoundValue
371  {
372  cvex_BoundValue()
373  : myValue(nullptr)
374  , myBindPtr(nullptr)
375  , myStoragePtr(nullptr)
376  {}
377  CVEX_ValueT<PREC>*myValue;
378  void *myBindPtr;
379  void *myStoragePtr;
380  };
381 
382  bool validateValue(const CVEX_ValueT<PREC> &value,
383  VEX_Instance<PREC> &state, int nproc);
384  void copyBoundData(cvex_BoundValue &bound,
385  VEX_Instance<PREC> &state,
386  int start, int nproc);
387  bool bindValues(UT_Array<cvex_BoundValue> &bound_vals,
388  VEX_Instance<PREC> &state, int nproc);
389  void extractStrings(CVEX_ValueT<PREC> &value,
390  VEX_Instance<PREC> &state,
391  int start, int nproc);
392  void extractArrays(CVEX_ValueT<PREC> &value,
393  VEX_Instance<PREC> &state,
394  int start, int nproc);
395  void extractUniform(CVEX_ValueT<PREC> &value,
396  VEX_Instance<PREC> &state);
397 
398  bool loadPrivate(const VEX_AssemblePtr &as,
399  int argc, const char *const argv[]);
400 
401  CVEX_ValueListT<PREC> myInputs;
402  CVEX_ValueListT<PREC> myOutputs;
404  UT_String myError;
405 
406 
407  UT_Array<cvex_BoundValue> myBoundVals;
408 
409  UT_Array<VEXint<PREC>*> &getTempI() { myTempI.clear(); return myTempI; }
410  UT_Array<VEXfloat<PREC>*> &getTempF() { myTempF.clear(); return myTempF; }
411 
412  UT_Array<VEXfloat<PREC>*> myTempF;
413  UT_Array<VEXint<PREC>*> myTempI;
414 };
415 
417 
420 
421 #endif
const char * getLastError() const
Definition: CVEX_Context.h:354
CVEX_ValueListT< PREC > & getInputList()
Definition: CVEX_Context.h:282
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:292
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
const CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name, CVEX_Type type) const
Find an output by name/type.
Definition: CVEX_Context.h:308
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:294
const CVEX_ValueT< PREC > * findOutput(const UT_StringRef &name) const
Find and output by name.
Definition: CVEX_Context.h:314
List of input or output values for a CVEX_Context.
A class representing a VEX value.
Definition: CVEX_Value.h:53
UT_OpCaller * getOpCaller() const
Access to the OP_Caller.
Definition: CVEX_Context.h:77
const CVEX_ValueListT< PREC > & getInputList() const
Definition: CVEX_Context.h:283
void setGeoCommandQueue(VEX_GeoCommandQueue< PREC > *geocmd)
Sets the command queue for this context.
Definition: CVEX_Context.h:114
int64 exint
Definition: SYS_Types.h:120
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:286
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:25
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:316
CVEX_ValueListT< PREC > & getOutputList()
Definition: CVEX_Context.h:305
void setTimeDependent(bool v)
Definition: CVEX_Context.h:144
double fpreal
Definition: SYS_Types.h:276
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:310
A class holding a VEX function.
Definition: CVEX_Function.h:30
const CVEX_ValueListT< PREC > & getOutputList() const
Definition: CVEX_Context.h:304
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:47
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:288
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:519
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