SeExpr
|
You can still define resolveVar() and resolveFunc() methods in your custom expression classes, but you now also have the option to use variable blocks instead. These are useful for re-using variables and managing thread evaluation. Within your custom expression class, you would skip the usual resolveVar() and resolveFunc() implementations:
class MyExpr:public SeExpr2::Expression { // These are now optional: // resolveVar() // resolveFunc() };
Here's how you might write an example function to run an expression that uses variable blocks. This example assumes you have a particle data struct p, with numParticles, numAttributes. A variable block contains variable names and types, but doesn't care what the values are.
void f(const std::string& s, MyParticleData* p, int outputDim=3){ // set up the bindings for each of the particle attributes SeExpr2::VarBlockCreator blockCreator; std::vectorTo parallelize evaluation per particle, a simple parallel_for can be used:variableHandles; std::vector attrs; for(int i=0; i numAttrs(); i++) { MyParticleAttr attr; p->getAttrInfo(i,attr); attrs.push_back(attr); int handle = blockCreator.registerVariable(attr.name, TypeVec(attr.dim)); variableHandles.push_back(handle); } // set up binding for the output int outputVariableHandle=blockCreator.registerVariable("__output", TypeVec(outputDim)); // make an expression with the appropriate bindings MyExpr e(s); e.setDesiredType(TypeVec(outputDim)); e.setVarBlockCreator(&blockCreator); if(!e.isValid()) throw std::runtime_error(e.parseError()): // create the variable block, set up pointers to data SeExpr2::VarBlock block = blockCreator.create(); for(int i=0; i numAttrs(); i++) { block.Pointer(variableHandles[i]) = p->data (attrs[i]); } std::vector outputData(p->numParticles()*outputDim); block.Pointer(outputVariableHandle)=outputData.data(); // evaluate multiple expressions at once; inlines expressions e.evalMultiple(&block, outputVariableHandle, 0, p->numParticles()); }
// evaluate multiple expressions at once, inlines expressions tbb::parallel_for(blocked_range(0,p->numParticles()),[](blocked_range r)) { VarBlock myBlock=block.clone(); //should be cheap e.evalMultiple(&myblock, outputVariableHandle, r.start, r.end); }