-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VRT Pixel Functions: Add function to evaluate arbitrary expression #11209
base: master
Are you sure you want to change the base?
Conversation
That's super cool, and so compact as an integration! Any hints on the performance ? In particular it would be cool if exprtk could use SIMD to vectorize computations, but I'm probably asking too much. Regarding performance, I'd suspect the biggest issue to be the GDALCopyWords() done for each pixel. Creating a temporary array with all the double values and copying in one-go to the output data type would certainly be beneficial (this remark applies to existing pixel functions). Can exptrtk can be used with non-double variables ? (in case that would make things faster for integer only computations) Thinking out loud: for ultimate performance, we should probabl use some LLVM-based solution where the expression would be just-in-time compiled to the target architecture, a bit like numba does. |
#define exprtk_disable_rtl_io_file | ||
#define exprtk_disable_rtl_vecops | ||
#define exprtk_disable_string_capabilities | ||
#include <exprtk.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the following to avoid namespace collisions in case GDAL is integrated with another software also using exprtk?
#include <exprtk.hpp> | |
#define exprtk gdal_exprtk | |
#include <exprtk.hpp> |
Haven't looked into this yet. In particular, comparing to Python would be interesting.
Maybe they could be rewritten as templates...
The docs note "Support for various numeric types (float, double, long double, MPFR/GMP)"
I also came across mathpresso that does something along these lines. |
@rouault A limitation of the pixel function integration is that we can only output a single band. exprtk would happily accept an expression like On performance, I've done basic tests like summing up a 24-band netCDF. Performance is roughly equivalent to Python with
and numpy:
|
It accepts only a single (potentially multiband) input dataset. That said the Input can be a VRTDataset, so you can assemble several single-band datasets as a virtual multiple one. Hard to tell which way is the preferred one. Would having it available in both VRTDerivedRasterBand and VRTProcessedDataset be overkill ? Having it available in VRTDerivedRasterBand makes it probably easier/intutive to write formulas that are different per output-band, even if exprtk allows to return a tuple. |
Not necessarily. I'll look into
On the other hand, this requires repeating all of the |
that's true |
What does this PR do?
Adds a C++ pixel function called "expression" that can evaluate an arbitrary expression (or indeed, a mini-program) using the exprtk library. This is a single MIT-licensed header that is easily integrated into GDAL. It appears to be quite widely used. However, given that a major purpose of this is to extend the utility of VRT to users that don't want to allow functions defined in Python (possibly because of security concerns), I'm a little uncomfortable with the scope of expressions allowed by this library. Some of these, such as file I/O, can be disabled (and I've done so.)
I've also looked at:
I need to do more work to investigate details such as nodata handling, but wanted to share the concept sooner rather than later.
An alternative implementation would expose
exprtk
as an additional pixel function language alongside Python, instead of hooking into the existing C++ pixel function machinery.An example VRT that is allowed is: