Skip to content

Commit

Permalink
Merge pull request #1336 from proberts-cinesite/PrimitiveBoundUsePara…
Browse files Browse the repository at this point in the history
…llelReduce

Primitive : Use tbb parallel_reduce to accelerate bounds compute
  • Loading branch information
johnhaddon authored Mar 2, 2023
2 parents 97754ec + 0953512 commit 1e2ecfb
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 23 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
10.4.x.x (relative to 10.4.5.0)
========

Improvements
------------

- PointsPrimitive, Primitive : Accelerated bounds computation using `tbb::parallel_reduce`.

Fixes
-----

Expand Down
60 changes: 41 additions & 19 deletions src/IECoreScene/PointsPrimitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
#include "IECore/MurmurHash.h"
#include "IECore/SimpleTypedData.h"

#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

using namespace std;
using namespace Imath;
using namespace IECore;
Expand Down Expand Up @@ -193,26 +196,45 @@ Imath::Box3f PointsPrimitive::bound() const
// Compute the bounding box from the gathered data.

Box3f result;
for( size_t i = 0; i < count; ++i )
{
float r = constantWidth * *width / 2.0f;
width += widthStep;
if( aspectRatio )
{
// Type is patch - the diagonal will be
// longer than either the width or the
// height, so derive a new radius from that.
float hh = r; // half the height
if( *aspectRatio != 0.0f )
using RangeType = tbb::blocked_range< const V3f* >;
tbb::this_task_arena::isolate( [ =, & result ]{
tbb::task_group_context taskGroupContext( tbb::task_group_context::isolated );
result = tbb::parallel_reduce( RangeType( p, p + count, 1000 ), Imath::Box3f(),
[ = ]( const RangeType& range, const Imath::Box3f& value ) -> Imath::Box3f
{
hh /= *aspectRatio;
}
r = sqrtf( r * r + hh * hh );
aspectRatio += aspectRatioStep;
}
result.extendBy( Box3f( *p - V3f( r ), *p + V3f( r ) ) );
p++;
}
Imath::Box3f b( value );
const size_t offset = range.begin() - p;
const float* wIt = offset * widthStep + width;
const float* aIt = offset * aspectRatioStep + aspectRatio;
for( const V3f& pos : range )
{
float r = constantWidth * ( *wIt ) / 2.0f;
wIt += widthStep;
if( aspectRatio )
{
// Type is patch - the diagonal will be
// longer than either the width or the
// height, so derive a new radius from that.
float hh = r; // half the height
if( ( *aIt ) != 0.0f )
{
hh /= ( *aIt );
}
r = sqrtf( r * r + hh * hh );
aIt += aspectRatioStep;
}
b.extendBy( Box3f( pos - V3f( r ), pos + V3f( r ) ) );
}
return b;
},
[]( const Imath::Box3f& lhs, const Imath::Box3f& rhs ) -> Imath::Box3f
{
Imath::Box3f b( lhs );
b.extendBy( rhs );
return b;
},
taskGroupContext );
} );

return result;
}
Expand Down
28 changes: 24 additions & 4 deletions src/IECoreScene/Primitive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@

#include "boost/algorithm/string.hpp"

#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>

#include <cassert>

using namespace IECore;
Expand Down Expand Up @@ -78,10 +81,27 @@ Imath::Box3f Primitive::bound() const
if( p )
{
const vector<V3f> &pp = p->readable();
for( size_t i=0; i<pp.size(); i++ )
{
result.extendBy( pp[i] );
}
using RangeType = tbb::blocked_range< const V3f* >;
tbb::this_task_arena::isolate( [ & result, & pp ]{
tbb::task_group_context taskGroupContext( tbb::task_group_context::isolated );
result = tbb::parallel_reduce( RangeType( pp.data(), pp.data() + pp.size(), 1000 ), Imath::Box3f(),
[]( const RangeType& range, const Imath::Box3f& value ) -> Imath::Box3f
{
Imath::Box3f b( value );
for( const V3f& pos : range )
{
b.extendBy( pos );
}
return b;
},
[]( const Imath::Box3f& lhs, const Imath::Box3f& rhs ) -> Imath::Box3f
{
Imath::Box3f b( lhs );
b.extendBy( rhs );
return b;
},
taskGroupContext );
} );
}
}
return result;
Expand Down

0 comments on commit 1e2ecfb

Please sign in to comment.