3
// ************************************************************************
5
// Kokkos: Manycore Performance-Portable Multidimensional Arrays
6
// Copyright (2012) Sandia Corporation
8
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9
// the U.S. Government retains certain rights in this software.
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are
15
// 1. Redistributions of source code must retain the above copyright
16
// notice, this list of conditions and the following disclaimer.
18
// 2. Redistributions in binary form must reproduce the above copyright
19
// notice, this list of conditions and the following disclaimer in the
20
// documentation and/or other materials provided with the distribution.
22
// 3. Neither the name of the Corporation nor the names of the
23
// contributors may be used to endorse or promote products derived from
24
// this software without specific prior written permission.
26
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
40
// ************************************************************************
44
#ifndef KOKKOS_UNORDERED_MAP_IMPL_HPP
45
#define KOKKOS_UNORDERED_MAP_IMPL_HPP
47
#include <Kokkos_Core_fwd.hpp>
55
namespace Kokkos { namespace Impl {
57
uint32_t find_hash_size( uint32_t size );
59
template <typename Map>
60
struct UnorderedMapRehash
63
typedef typename map_type::const_map_type const_map_type;
64
typedef typename map_type::device_type device_type;
65
typedef typename map_type::size_type size_type;
70
UnorderedMapRehash( map_type const& dst, const_map_type const& src)
71
: m_dst(dst), m_src(src)
76
parallel_for(m_src.capacity(), *this);
79
KOKKOS_INLINE_FUNCTION
80
void operator()(size_type i) const
82
if ( m_src.valid_at(i) )
83
m_dst.insert(m_src.key_at(i), m_src.value_at(i));
88
template <typename UMap>
89
struct UnorderedMapErase
91
typedef UMap map_type;
92
typedef typename map_type::device_type device_type;
93
typedef typename map_type::size_type size_type;
94
typedef typename map_type::key_type key_type;
95
typedef typename map_type::impl_value_type value_type;
99
UnorderedMapErase( map_type const& map)
105
parallel_for(m_map.m_hash_lists.size(), *this);
108
KOKKOS_INLINE_FUNCTION
109
void operator()( size_type i ) const
111
const size_type invalid_index = map_type::invalid_index;
113
size_type curr = m_map.m_hash_lists(i);
114
size_type next = invalid_index;
116
// remove erased head of the linked-list
117
while (curr != invalid_index && !m_map.valid_at(curr)) {
118
next = m_map.m_next_index[curr];
119
m_map.m_next_index[curr] = invalid_index;
120
m_map.m_keys[curr] = key_type();
121
if (m_map.is_set) m_map.m_values[curr] = value_type();
123
m_map.m_hash_lists(i) = next;
126
// if the list is non-empty and the head is valid
127
if (curr != invalid_index && m_map.valid_at(curr) ) {
128
size_type prev = curr;
129
curr = m_map.m_next_index[prev];
131
while (curr != invalid_index) {
132
next = m_map.m_next_index[curr];
133
if (m_map.valid_at(curr)) {
137
// remove curr from list
138
m_map.m_next_index[prev] = next;
139
m_map.m_next_index[curr] = invalid_index;
140
m_map.m_keys[curr] = key_type();
141
if (map_type::is_set) m_map.m_values[curr] = value_type();
149
template <typename UMap>
150
struct UnorderedMapHistogram
152
typedef UMap map_type;
153
typedef typename map_type::device_type device_type;
154
typedef typename map_type::size_type size_type;
156
typedef View<int[100], device_type> histogram_view;
157
typedef typename histogram_view::HostMirror host_histogram_view;
160
histogram_view m_length;
161
histogram_view m_distance;
162
histogram_view m_block_distance;
164
UnorderedMapHistogram( map_type const& map)
166
, m_length("UnorderedMap Histogram")
167
, m_distance("UnorderedMap Histogram")
168
, m_block_distance("UnorderedMap Histogram")
173
parallel_for(m_map.m_hash_lists.size(), *this);
178
Kokkos::deep_copy(m_length, 0);
179
Kokkos::deep_copy(m_distance, 0);
180
Kokkos::deep_copy(m_block_distance, 0);
183
void print_length(std::ostream &out)
185
host_histogram_view host_copy = create_mirror_view(m_length);
186
Kokkos::deep_copy(host_copy, m_length);
188
for (int i=0, size = host_copy.size(); i<size; ++i)
190
out << host_copy[i] << " , ";
192
out << "\b\b\b " << std::endl;
195
void print_distance(std::ostream &out)
197
host_histogram_view host_copy = create_mirror_view(m_distance);
198
Kokkos::deep_copy(host_copy, m_distance);
200
for (int i=0, size = host_copy.size(); i<size; ++i)
202
out << host_copy[i] << " , ";
204
out << "\b\b\b " << std::endl;
207
void print_block_distance(std::ostream &out)
209
host_histogram_view host_copy = create_mirror_view(m_block_distance);
210
Kokkos::deep_copy(host_copy, m_block_distance);
212
for (int i=0, size = host_copy.size(); i<size; ++i)
214
out << host_copy[i] << " , ";
216
out << "\b\b\b " << std::endl;
219
KOKKOS_INLINE_FUNCTION
220
void operator()( size_type i ) const
222
const size_type invalid_index = map_type::invalid_index;
225
size_type min_index = ~0u, max_index = 0;
226
for (size_type curr = m_map.m_hash_lists(i); curr != invalid_index; curr = m_map.m_next_index[curr]) {
228
min_index = (curr < min_index) ? curr : min_index;
229
max_index = (max_index < curr) ? curr : max_index;
232
size_type distance = (0u < length) ? max_index - min_index : 0u;
233
size_type blocks = (0u < length) ? max_index/32u - min_index/32u : 0u;
236
length = length < 100u ? length : 99u;
237
distance = distance < 100u ? distance : 99u;
238
blocks = blocks < 100u ? blocks : 99u;
242
atomic_fetch_add( &m_length(length), 1);
243
atomic_fetch_add( &m_distance(distance), 1);
244
atomic_fetch_add( &m_block_distance(blocks), 1);
249
template <typename UMap>
250
struct UnorderedMapPrint
252
typedef UMap map_type;
253
typedef typename map_type::device_type device_type;
254
typedef typename map_type::size_type size_type;
258
UnorderedMapPrint( map_type const& map)
264
parallel_for(m_map.m_hash_lists.size(), *this);
267
KOKKOS_INLINE_FUNCTION
268
void operator()( size_type i ) const
270
const size_type invalid_index = map_type::invalid_index;
272
uint32_t list = m_map.m_hash_lists(i);
273
for (size_type curr = list, ii=0; curr != invalid_index; curr = m_map.m_next_index[curr], ++ii) {
274
printf("%d[%d]: %d->%d\n", list, ii, m_map.key_at(curr), m_map.value_at(curr));
279
template <typename DKey, typename DValue, typename SKey, typename SValue>
280
struct UnorderedMapCanAssign : public false_ {};
282
template <typename Key, typename Value>
283
struct UnorderedMapCanAssign<Key,Value,Key,Value> : public true_ {};
285
template <typename Key, typename Value>
286
struct UnorderedMapCanAssign<const Key,Value,Key,Value> : public true_ {};
288
template <typename Key, typename Value>
289
struct UnorderedMapCanAssign<const Key,const Value,Key,Value> : public true_ {};
291
template <typename Key, typename Value>
292
struct UnorderedMapCanAssign<const Key,const Value,const Key,Value> : public true_ {};
297
#endif // KOKKOS_UNORDERED_MAP_IMPL_HPP