Skip to content
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

Add workaround to parallel merge in TBB backend not to use input iterators default constructor #1346

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions include/oneapi/dpl/pstl/omp/parallel_merge.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ namespace dpl
namespace __omp_backend
{

template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
typename _Compare, typename _LeafMerge>
void
__make_parallel_merge_leaf_tasks(_RandomAccessIterator1 __xm, _RandomAccessIterator2 __ym, _RandomAccessIterator1 __xs,
_RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
_RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge);

template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
typename _Compare, typename _LeafMerge>
void
Expand All @@ -39,20 +46,29 @@ __parallel_merge_body(std::size_t __size_x, std::size_t __size_y, _RandomAccessI
return;
}

_RandomAccessIterator1 __xm;
_RandomAccessIterator2 __ym;

if (__size_x < __size_y)
{
__ym = __ys + (__size_y / 2);
__xm = std::upper_bound(__xs, __xe, *__ym, __comp);
_RandomAccessIterator2 __ym = __ys + (__size_y / 2);
__make_parallel_merge_leaf_tasks(::std::upper_bound(__xs, __xe, *__ym, __comp),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recently, we came to conclusion that we should not write :: operator before std:: in new code, at least.

__ym, __xs, __xe, __ys, __ye, __zs,
__comp, __leaf_merge);
}
else
{
__xm = __xs + (__size_x / 2);
__ym = std::lower_bound(__ys, __ye, *__xm, __comp);
_RandomAccessIterator1 __xm = __xs + (__size_x / 2);
__make_parallel_merge_leaf_tasks(__xm, ::std::lower_bound(__ys, __ye, *__xm, __comp),
__xs, __xe, __ys, __ye, __zs,
__comp, __leaf_merge);
}
}

template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
typename _Compare, typename _LeafMerge>
void
__make_parallel_merge_leaf_tasks(_RandomAccessIterator1 __xm, _RandomAccessIterator2 __ym, _RandomAccessIterator1 __xs,
_RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys, _RandomAccessIterator2 __ye,
_RandomAccessIterator3 __zs, _Compare __comp, _LeafMerge __leaf_merge)
{
auto __zm = __zs + (__xm - __xs) + (__ym - __ys);

_PSTL_PRAGMA(omp task untied mergeable default(none)
Expand Down
25 changes: 17 additions & 8 deletions include/oneapi/dpl/pstl/parallel_backend_tbb.h
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,9 @@ class __merge_func_static
_Compare _M_comp;
_LeafMerge _M_leaf_merge;

void
__make_and_spawn_child_task(__task* __self, _RandomAccessIterator1 __xm, _RandomAccessIterator2 __ym);

public:
__merge_func_static(_RandomAccessIterator1 __xs, _RandomAccessIterator1 __xe, _RandomAccessIterator2 __ys,
_RandomAccessIterator2 __ye, _RandomAccessIterator3 __zs, _Compare __comp,
Expand Down Expand Up @@ -1248,27 +1251,33 @@ operator()(__task* __self)
return nullptr;
}

_RandomAccessIterator1 __xm;
_RandomAccessIterator2 __ym;
if (_M_xe - _M_xs < _M_ye - _M_ys)
{
__ym = _M_ys + (_M_ye - _M_ys) / 2;
__xm = ::std::upper_bound(_M_xs, _M_xe, *__ym, _M_comp);
_RandomAccessIterator2 __ym = _M_ys + (_M_ye - _M_ys) / 2;
__make_and_spawn_child_task(__self, ::std::upper_bound(_M_xs, _M_xe, *__ym, _M_comp), __ym);
}
else
{
__xm = _M_xs + (_M_xe - _M_xs) / 2;
__ym = ::std::lower_bound(_M_ys, _M_ye, *__xm, _M_comp);
_RandomAccessIterator1 __xm = _M_xs + (_M_xe - _M_xs) / 2;
__make_and_spawn_child_task(__self, __xm, ::std::lower_bound(_M_ys, _M_ye, *__xm, _M_comp));
}

return __self;
}

template <typename _RandomAccessIterator1, typename _RandomAccessIterator2, typename _RandomAccessIterator3,
typename __M_Compare, typename _LeafMerge>
void
__merge_func_static<_RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator3, __M_Compare, _LeafMerge>::
__make_and_spawn_child_task(__task* __self, _RandomAccessIterator1 __xm, _RandomAccessIterator2 __ym)
{
const _RandomAccessIterator3 __zm = _M_zs + ((__xm - _M_xs) + (__ym - _M_ys));
auto __right = __self->make_additional_child_of(
__self->parent(), __merge_func_static(__xm, _M_xe, __ym, _M_ye, __zm, _M_comp, _M_leaf_merge));
__self->spawn(__right);
__self->recycle_as_continuation();
_M_xe = __xm;
_M_ye = __ym;

return __self;
}

template <class _ExecutionPolicy, typename _RandomAccessIterator1, typename _RandomAccessIterator2,
Expand Down
Loading