This little program
----------------------
#include <numeric>
void f () {
  bool *p, *q;
  std::accumulate (p, q, 0U);
}
----------------------
counts the 'true's in the range [p,q) but this doesn't work in parallel mode, 
the compiler says that it can't resolve a function call. It should as per 
26.4.1.

In particular, the error message is this:

4.3.0/parallel/par_loop.h: In function 'Op
__gnu_parallel::for_each_template_random_access_ed(RandomAccessIterator,
RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator =
bool*, Op = __gnu_parallel::nothing, Fu =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]':
4.3.0/parallel/for_each.h:73:   instantiated from 'UserOp
__gnu_parallel::for_each_template_random_access(InputIterator, InputIterator,
UserOp, Functionality&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism)
[with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]'
4.3.0/parallel/numeric:103:   instantiated from 'T
std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter =
bool*, T = unsigned int, _BinaryOper = std::plus<bool>]'
4.3.0/parallel/numeric:83:   instantiated from 'T
std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism)
[with _IIter = bool*, T = unsigned int]'
x.cc:4:   instantiated from here
4.3.0/parallel/par_loop.h:103: error: no match for call to
'(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&,
bool)'
4.3.0/parallel/omp_loop.h: In function 'Op
__gnu_parallel::for_each_template_random_access_omp_loop(RandomAccessIterator,
RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator =
bool*, Op = __gnu_parallel::nothing, Fu =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]':
4.3.0/parallel/for_each.h:75:   instantiated from 'UserOp
__gnu_parallel::for_each_template_random_access(InputIterator, InputIterator,
UserOp, Functionality&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism)
[with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]'
4.3.0/parallel/numeric:103:   instantiated from 'T
std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter =
bool*, T = unsigned int, _BinaryOper = std::plus<bool>]'
4.3.0/parallel/numeric:83:   instantiated from 'T
std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism)
[with _IIter = bool*, T = unsigned int]'
x.cc:4:   instantiated from here
4.3.0/parallel/omp_loop.h:78: error: no match for call to
'(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&,
bool)'
4.3.0/parallel/omp_loop.h:86: error: no match for call to
'(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&,
bool)'
4.3.0/parallel/workstealing.h: In function 'Op
__gnu_parallel::for_each_template_random_access_workstealing(RandomAccessIterator,
RandomAccessIterator, Op, Fu&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type) [with RandomAccessIterator =
bool*, Op = __gnu_parallel::nothing, Fu =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]':
4.3.0/parallel/for_each.h:79:   instantiated from 'UserOp
__gnu_parallel::for_each_template_random_access(InputIterator, InputIterator,
UserOp, Functionality&, Red, Result, Result&, typename
std::iterator_traits<_Iterator>::difference_type, __gnu_parallel::parallelism)
[with InputIterator = bool*, UserOp = __gnu_parallel::nothing, Functionality =
__gnu_parallel::accumulate_selector<bool*>, Red =
__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >, Result = unsigned
int]'
4.3.0/parallel/numeric:103:   instantiated from 'T
std::__parallel::accumulate_switch(_RAIter, _RAIter, T, _BinaryOper,
std::random_access_iterator_tag, __gnu_parallel::parallelism) [with _RAIter =
bool*, T = unsigned int, _BinaryOper = std::plus<bool>]'
4.3.0/parallel/numeric:83:   instantiated from 'T
std::__parallel::accumulate(_IIter, _IIter, T, __gnu_parallel::parallelism)
[with _IIter = bool*, T = unsigned int]'
x.cc:4:   instantiated from here
4.3.0/parallel/workstealing.h:204: error: no match for call to
'(__gnu_parallel::accumulate_binop_reduct<std::plus<bool> >) (unsigned int&,
bool)'


While 26.4.1 doesn't spell this out explicitly, one can only deduce that
what is mean is that the accumulator variable has the same type as
the initializer, which in the example is 'unsigned int'. Consequently,
the function should do something like
  while (p!=q)
    acc += *p++;
in which case the rhs is converted to int. The current implementation
attempts to use an accumulator of type 'bool'.

W.


-- 
           Summary: parallel v3: std::accumulate uses accumulator of wrong
                    type
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Keywords: rejects-valid
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bangerth at dealii dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33488

Reply via email to