~ubuntu-branches/ubuntu/trusty/libthrust/trusty

« back to all changes in this revision

Viewing changes to detail/device/generic/copy_if.inl

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Beckmann
  • Date: 2011-05-28 09:32:48 UTC
  • Revision ID: james.westby@ubuntu.com-20110528093248-np3euv5sj7fw3nyv
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright 2008-2011 NVIDIA Corporation
 
3
 *
 
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
 
5
 *  you may not use this file except in compliance with the License.
 
6
 *  You may obtain a copy of the License at
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 *  Unless required by applicable law or agreed to in writing, software
 
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 *  See the License for the specific language governing permissions and
 
14
 *  limitations under the License.
 
15
 */
 
16
 
 
17
#pragma once
 
18
 
 
19
#include <thrust/iterator/iterator_traits.h>
 
20
#include <thrust/iterator/detail/minimum_space.h>
 
21
#include <thrust/functional.h>
 
22
#include <thrust/distance.h>
 
23
#include <thrust/transform.h>
 
24
 
 
25
#include <thrust/detail/internal_functional.h>
 
26
#include <thrust/detail/raw_buffer.h>
 
27
#include <thrust/detail/type_traits.h>
 
28
 
 
29
#include <thrust/detail/device/scan.h>
 
30
#include <thrust/scatter.h>
 
31
 
 
32
#include <limits>
 
33
 
 
34
namespace thrust
 
35
{
 
36
namespace detail
 
37
{
 
38
namespace device
 
39
{
 
40
 
 
41
// XXX WAR circular #inclusion with forward declaration
 
42
template<typename InputIterator,
 
43
         typename OutputIterator,
 
44
         typename T,
 
45
         typename AssociativeOperator>
 
46
  OutputIterator exclusive_scan(InputIterator first,
 
47
                                InputIterator last,
 
48
                                OutputIterator result,
 
49
                                T init,
 
50
                                AssociativeOperator binary_op);
 
51
 
 
52
 
 
53
template<typename InputIterator1,
 
54
         typename InputIterator2,
 
55
         typename InputIterator3,
 
56
         typename RandomAccessIterator,
 
57
         typename Predicate>
 
58
  void scatter_if(InputIterator1 first,
 
59
                  InputIterator1 last,
 
60
                  InputIterator2 map,
 
61
                  InputIterator3 stencil,
 
62
                  RandomAccessIterator output,
 
63
                  Predicate pred);
 
64
 
 
65
 
 
66
namespace generic
 
67
{
 
68
namespace detail
 
69
{
 
70
 
 
71
template<typename IndexType,
 
72
         typename InputIterator1,
 
73
         typename InputIterator2,
 
74
         typename OutputIterator,
 
75
         typename Predicate>
 
76
OutputIterator copy_if(InputIterator1 first,
 
77
                       InputIterator1 last,
 
78
                       InputIterator2 stencil,
 
79
                       OutputIterator result,
 
80
                       Predicate pred)
 
81
{
 
82
    typedef typename thrust::detail::minimum_space<
 
83
      typename thrust::iterator_space<InputIterator1>::type,
 
84
      typename thrust::iterator_space<InputIterator2>::type,
 
85
      typename thrust::iterator_space<OutputIterator>::type
 
86
    >::type Space;
 
87
 
 
88
    __THRUST_DISABLE_MSVC_POSSIBLE_LOSS_OF_DATA_WARNING(IndexType n = thrust::distance(first, last));
 
89
 
 
90
    // compute {0,1} predicates
 
91
    thrust::detail::raw_buffer<IndexType, Space> predicates(n);
 
92
    thrust::transform(stencil,
 
93
                      stencil + n,
 
94
                      predicates.begin(),
 
95
                      thrust::detail::predicate_to_integral<Predicate,IndexType>(pred));
 
96
 
 
97
    // scan {0,1} predicates
 
98
    thrust::detail::raw_buffer<IndexType, Space> scatter_indices(n);
 
99
    thrust::detail::device::exclusive_scan(predicates.begin(),
 
100
                                           predicates.end(),
 
101
                                           scatter_indices.begin(),
 
102
                                           static_cast<IndexType>(0),
 
103
                                           thrust::plus<IndexType>());
 
104
 
 
105
    // scatter the true elements
 
106
    thrust::scatter_if(first,
 
107
                       last,
 
108
                       scatter_indices.begin(),
 
109
                       predicates.begin(),
 
110
                       result,
 
111
                       thrust::identity<IndexType>());
 
112
 
 
113
    // find the end of the new sequence
 
114
    IndexType output_size = scatter_indices[n - 1] + predicates[n - 1];
 
115
 
 
116
    return result + output_size;
 
117
}
 
118
 
 
119
} // end namespace detail
 
120
 
 
121
template<typename InputIterator1,
 
122
         typename InputIterator2,
 
123
         typename OutputIterator,
 
124
         typename Predicate>
 
125
   OutputIterator copy_if(InputIterator1 first,
 
126
                          InputIterator1 last,
 
127
                          InputIterator2 stencil,
 
128
                          OutputIterator result,
 
129
                          Predicate pred)
 
130
{
 
131
    typedef typename thrust::iterator_traits<InputIterator1>::difference_type difference_type;
 
132
 
 
133
    // empty sequence
 
134
    if (first == last)
 
135
        return result;
 
136
    
 
137
    difference_type n = thrust::distance(first, last);
 
138
 
 
139
    // create an unsigned version of n (we know n is positive from the comparison above)
 
140
    // to avoid a warning in the compare below
 
141
    typename thrust::detail::make_unsigned<difference_type>::type unsigned_n(n);
 
142
  
 
143
    // use 32-bit indices when possible (almost always)
 
144
    if (sizeof(difference_type) > sizeof(unsigned int) && unsigned_n > (std::numeric_limits<unsigned int>::max)())
 
145
        return detail::copy_if<difference_type>(first, last, stencil, result, pred);
 
146
    else
 
147
        return detail::copy_if<unsigned int>(first, last, stencil, result, pred);
 
148
} // end copy_if()
 
149
 
 
150
} // end namespace generic
 
151
} // end namespace device
 
152
} // end namespace detail
 
153
} // end namespace thrust
 
154