Pre-Review: Op Collapsing


Jeremy Selan <jeremy...@...>
 

I have some development under progress, not yet ready for review, but I thought it may interest people:
https://github.com/imageworks/OpenColorIO/pull/218

During processor creation, this branch adds an internal optimization pass that makes for more efficient color processing.
https://github.com/jeremyselan/OpenColorIO/blob/opt/src/core/OpOptimizers.cpp

But the most interesting consequence is that this allows for transforms which were not previously possible:

Say you have 2 colorspaces: A and B.  Both of these these colorspaces apply the same 3D lut, but B then also applies an additional matrix.

Previously, it would not have been possible to compute the processor to go directly from A to B because an inverse 3d lut is needed.
old op chain:   LUT3D (inv) -> LUT3D (forward) -> matrix

However, the new optimizer will detect that the same 3dlut is being applied in a row in both an inverse and forward direction, and they will cancel out! (This works even if the nesting is deep.)

new op chain: matrix

Remaining tasks:
- substantially more unit tests
- matrix concatenation.

-- Jeremy



Malcolm Humphreys <malcolmh...@...>
 

This is looking cool!

I would be tempted to try and move some this into the base Op interface, mostly so in the future we can support plugin op optimisation if needed (moving truelight out as a plugin say).

maybe something like:
bool Op::isSameType(const OpRcPtr & op)
bool Op::isInverse(const OpRcPtr & op)
bool Op::combinable(const OpRcPtr & op)
OpRcPtr Op::combine(const OpRcPtr & op)

.malcolm


On 03/02/2012, at 11:14 PM, Jeremy Selan wrote:

I have some development under progress, not yet ready for review, but I thought it may interest people:
https://github.com/imageworks/OpenColorIO/pull/218

During processor creation, this branch adds an internal optimization pass that makes for more efficient color processing.
https://github.com/jeremyselan/OpenColorIO/blob/opt/src/core/OpOptimizers.cpp

But the most interesting consequence is that this allows for transforms which were not previously possible:

Say you have 2 colorspaces: A and B.  Both of these these colorspaces apply the same 3D lut, but B then also applies an additional matrix.

Previously, it would not have been possible to compute the processor to go directly from A to B because an inverse 3d lut is needed.
old op chain:   LUT3D (inv) -> LUT3D (forward) -> matrix

However, the new optimizer will detect that the same 3dlut is being applied in a row in both an inverse and forward direction, and they will cancel out! (This works even if the nesting is deep.)

new op chain: matrix

Remaining tasks:
- substantially more unit tests
- matrix concatenation.

-- Jeremy




Jeremy Selan <jeremy...@...>
 

Yah, I looked into this implementation approach originally but didn't want to add too many virtuals before I knew exactly what was needed.  But now that I see what fcns are actually being used, I'm fine with moving the functions that everyone implements (isSameType, isInverse) to the base.

In terms of future plugin support, I think that's a side issue anyways as this API is currently internal, and can be refactored in any way that proves needed going forward.

-- Jeremy

On Sat, Feb 4, 2012 at 4:57 AM, Malcolm Humphreys <malcolmh...@...> wrote:

This is looking cool!

I would be tempted to try and move some this into the base Op interface, mostly so in the future we can support plugin op optimisation if needed (moving truelight out as a plugin say).

maybe something like:
bool Op::isSameType(const OpRcPtr & op)
bool Op::isInverse(const OpRcPtr & op)
bool Op::combinable(const OpRcPtr & op)
OpRcPtr Op::combine(const OpRcPtr & op)

.malcolm

On 03/02/2012, at 11:14 PM, Jeremy Selan wrote:

I have some development under progress, not yet ready for review, but I thought it may interest people:
https://github.com/imageworks/OpenColorIO/pull/218

During processor creation, this branch adds an internal optimization pass that makes for more efficient color processing.
https://github.com/jeremyselan/OpenColorIO/blob/opt/src/core/OpOptimizers.cpp

But the most interesting consequence is that this allows for transforms which were not previously possible:

Say you have 2 colorspaces: A and B.  Both of these these colorspaces apply the same 3D lut, but B then also applies an additional matrix.

Previously, it would not have been possible to compute the processor to go directly from A to B because an inverse 3d lut is needed.
old op chain:   LUT3D (inv) -> LUT3D (forward) -> matrix

However, the new optimizer will detect that the same 3dlut is being applied in a row in both an inverse and forward direction, and they will cancel out! (This works even if the nesting is deep.)

new op chain: matrix

Remaining tasks:
- substantially more unit tests
- matrix concatenation.

-- Jeremy





Jeremy Selan <jeremy...@...>
 

This is now ready for a real pull-request:

Internal image-procesing ops now go through a simple optimization framework as part of Processor creation. In this first code pass, ops that are exact inverses of their neighbors cancel out and are removed.


As far as I know, this code is good to go.  The matrix collapsing is not in yet, but I dont want to sit on what I've got thus far any longer.

-- Jeremy