OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [parallel/] [unique_copy.h] - Rev 35

Compare with Previous | Blame | View Log

// -*- C++ -*-
 
// Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software
// Foundation; either version 3, or (at your option) any later
// version.
 
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
 
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
 
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.
 
/** @file parallel/unique_copy.h
 *  @brief Parallel implementations of std::unique_copy().
 *  This file is a GNU parallel extension to the Standard C++ Library.
 */
 
// Written by Robert Geisberger and Robin Dapp.
 
#ifndef _GLIBCXX_PARALLEL_UNIQUE_COPY_H
#define _GLIBCXX_PARALLEL_UNIQUE_COPY_H 1
 
#include <parallel/parallel.h>
#include <parallel/multiseq_selection.h>
 
namespace __gnu_parallel
{
  /** @brief Parallel std::unique_copy(), w/__o explicit equality predicate.
    *  @param __first Begin iterator of input sequence.
    *  @param __last End iterator of input sequence.
    *  @param __result Begin iterator of result __sequence.
    *  @param __binary_pred Equality predicate.
    *  @return End iterator of result __sequence. */
  template<typename _IIter,
           class _OutputIterator,
           class _BinaryPredicate>
    _OutputIterator
    __parallel_unique_copy(_IIter __first, _IIter __last,
			   _OutputIterator __result,
			   _BinaryPredicate __binary_pred)
    {
      _GLIBCXX_CALL(__last - __first)
 
      typedef std::iterator_traits<_IIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;
 
      _DifferenceType __size = __last - __first;
 
      if (__size == 0)
	return __result;
 
      // Let the first thread process two parts.
      _DifferenceType *__counter;
      _DifferenceType *__borders;
 
      _ThreadIndex __num_threads = __get_max_threads();
      // First part contains at least one element.
#     pragma omp parallel num_threads(__num_threads)
      {
#       pragma omp single
	{
	  __num_threads = omp_get_num_threads();
	  __borders = new _DifferenceType[__num_threads + 2];
	  __equally_split(__size, __num_threads + 1, __borders);
	  __counter = new _DifferenceType[__num_threads + 1];
	}
 
	_ThreadIndex __iam = omp_get_thread_num();
 
	_DifferenceType __begin, __end;
 
	// Check for length without duplicates
	// Needed for position in output
	_DifferenceType __i = 0;
	_OutputIterator __out = __result;
 
	if (__iam == 0)
          {
            __begin = __borders[0] + 1;   // == 1
            __end = __borders[__iam + 1];
 
            ++__i;
            *__out++ = *__first;
 
            for (_IIter __iter = __first + __begin; __iter < __first + __end;
		 ++__iter)
              {
        	if (!__binary_pred(*__iter, *(__iter - 1)))
                  {
                    ++__i;
                    *__out++ = *__iter;
                  }
              }
          }
	else
          {
            __begin = __borders[__iam]; //one part
            __end = __borders[__iam + 1];
 
            for (_IIter __iter = __first + __begin; __iter < __first + __end;
		 ++__iter)
              {
        	if (!__binary_pred(*__iter, *(__iter - 1)))
                  ++__i;
              }
          }
	__counter[__iam] = __i;
 
	// Last part still untouched.
	_DifferenceType __begin_output;
 
#       pragma omp barrier
 
	// Store result in output on calculated positions.
	__begin_output = 0;
 
	if (__iam == 0)
          {
            for (_ThreadIndex __t = 0; __t < __num_threads; ++__t)
              __begin_output += __counter[__t];
 
            __i = 0;
 
            _OutputIterator __iter_out = __result + __begin_output;
 
            __begin = __borders[__num_threads];
            __end = __size;
 
            for (_IIter __iter = __first + __begin; __iter < __first + __end;
		 ++__iter)
              {
        	if (__iter == __first
		    || !__binary_pred(*__iter, *(__iter - 1)))
                  {
                    ++__i;
                    *__iter_out++ = *__iter;
                  }
              }
 
            __counter[__num_threads] = __i;
          }
	else
          {
            for (_ThreadIndex __t = 0; __t < __iam; __t++)
              __begin_output += __counter[__t];
 
            _OutputIterator __iter_out = __result + __begin_output;
            for (_IIter __iter = __first + __begin; __iter < __first + __end;
		 ++__iter)
              {
        	if (!__binary_pred(*__iter, *(__iter - 1)))
                  *__iter_out++ = *__iter;
              }
          }
      }
 
      _DifferenceType __end_output = 0;
      for (_ThreadIndex __t = 0; __t < __num_threads + 1; __t++)
	__end_output += __counter[__t];
 
      delete[] __borders;
 
      return __result + __end_output;
    }
 
  /** @brief Parallel std::unique_copy(), without explicit equality predicate
    *  @param __first Begin iterator of input sequence.
    *  @param __last End iterator of input sequence.
    *  @param __result Begin iterator of result __sequence.
    *  @return End iterator of result __sequence. */
  template<typename _IIter, class _OutputIterator>
    inline _OutputIterator
    __parallel_unique_copy(_IIter __first, _IIter __last,
			   _OutputIterator __result)
    {
      typedef typename std::iterator_traits<_IIter>::value_type
	_ValueType;
      return __parallel_unique_copy(__first, __last, __result,
				    std::equal_to<_ValueType>());
    }
 
}//namespace __gnu_parallel
 
#endif /* _GLIBCXX_PARALLEL_UNIQUE_COPY_H */
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.