Skip to content

Commit

Permalink
Add experimental multimap insert and contains (#549)
Browse files Browse the repository at this point in the history
This PR adds a new `experimental::static_multimap` using the new OA
design. It adds `insert` and `contains` operations for the new multimap.

---------

Co-authored-by: Daniel Jünger <[email protected]>
  • Loading branch information
PointKernel and sleeepyjack authored Jul 21, 2024
1 parent b7cd96d commit c05af72
Show file tree
Hide file tree
Showing 6 changed files with 1,487 additions and 2 deletions.
276 changes: 275 additions & 1 deletion include/cuco/detail/static_multimap/static_multimap.inl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021-2023, NVIDIA CORPORATION.
* Copyright (c) 2021-2024, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,280 @@
#include <iterator>

namespace cuco {
namespace experimental {
template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
static_multimap(Extent capacity,
empty_key<Key> empty_key_sentinel,
empty_value<T> empty_value_sentinel,
KeyEqual const& pred,
ProbingScheme const& probing_scheme,
cuda_thread_scope<Scope>,
Storage,
Allocator const& alloc,
cuda::stream_ref stream)
: impl_{std::make_unique<impl_type>(capacity,
cuco::pair{empty_key_sentinel, empty_value_sentinel},
pred,
probing_scheme,
alloc,
stream)},
empty_value_sentinel_{empty_value_sentinel}
{
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
static_multimap(Extent n,
double desired_load_factor,
empty_key<Key> empty_key_sentinel,
empty_value<T> empty_value_sentinel,
KeyEqual const& pred,
ProbingScheme const& probing_scheme,
cuda_thread_scope<Scope>,
Storage,
Allocator const& alloc,
cuda::stream_ref stream)
: impl_{std::make_unique<impl_type>(n,
desired_load_factor,
cuco::pair{empty_key_sentinel, empty_value_sentinel},
pred,
probing_scheme,
alloc,
stream)},
empty_value_sentinel_{empty_value_sentinel}
{
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
static_multimap(Extent capacity,
empty_key<Key> empty_key_sentinel,
empty_value<T> empty_value_sentinel,
erased_key<Key> erased_key_sentinel,
KeyEqual const& pred,
ProbingScheme const& probing_scheme,
cuda_thread_scope<Scope>,
Storage,
Allocator const& alloc,
cuda::stream_ref stream)
: impl_{std::make_unique<impl_type>(capacity,
cuco::pair{empty_key_sentinel, empty_value_sentinel},
erased_key_sentinel,
pred,
probing_scheme,
alloc,
stream)},
empty_value_sentinel_{empty_value_sentinel}
{
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
void static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::clear(
cuda::stream_ref stream)
{
impl_->clear(stream);
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
void static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
clear_async(cuda::stream_ref stream) noexcept
{
impl_->clear_async(stream);
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
template <typename InputIt>
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::size_type
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::insert(
InputIt first, InputIt last, cuda::stream_ref stream)
{
return impl_->insert(first, last, ref(op::insert), stream);
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
template <typename InputIt>
void static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
insert_async(InputIt first, InputIt last, cuda::stream_ref stream) noexcept
{
impl_->insert_async(first, last, ref(op::insert), stream);
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
template <typename InputIt, typename OutputIt>
void static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::contains(
InputIt first, InputIt last, OutputIt output_begin, cuda::stream_ref stream) const
{
this->contains_async(first, last, output_begin, stream);
stream.wait();
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
template <typename InputIt, typename OutputIt>
void static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
contains_async(InputIt first,
InputIt last,
OutputIt output_begin,
cuda::stream_ref stream) const noexcept
{
impl_->contains_async(first, last, output_begin, ref(op::contains), stream);
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr auto
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::capacity()
const noexcept
{
return impl_->capacity();
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
key_type
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
empty_key_sentinel() const noexcept
{
return impl_->empty_key_sentinel();
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
mapped_type
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
empty_value_sentinel() const noexcept
{
return empty_value_sentinel_;
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
constexpr static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
key_type
static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::
erased_key_sentinel() const noexcept
{
return impl_->erased_key_sentinel();
}

template <class Key,
class T,
class Extent,
cuda::thread_scope Scope,
class KeyEqual,
class ProbingScheme,
class Allocator,
class Storage>
template <typename... Operators>
auto static_multimap<Key, T, Extent, Scope, KeyEqual, ProbingScheme, Allocator, Storage>::ref(
Operators...) const noexcept
{
static_assert(sizeof...(Operators), "No operators specified");
return cuco::detail::bitwise_compare(this->empty_key_sentinel(), this->erased_key_sentinel())
? ref_type<Operators...>{cuco::empty_key<key_type>(this->empty_key_sentinel()),
cuco::empty_value<mapped_type>(this->empty_value_sentinel()),
impl_->key_eq(),
impl_->probing_scheme(),
cuda_thread_scope<Scope>{},
impl_->storage_ref()}
: ref_type<Operators...>{cuco::empty_key<key_type>(this->empty_key_sentinel()),
cuco::empty_value<mapped_type>(this->empty_value_sentinel()),
cuco::erased_key<key_type>(this->erased_key_sentinel()),
impl_->key_eq(),
impl_->probing_scheme(),
cuda_thread_scope<Scope>{},
impl_->storage_ref()};
}
} // namespace experimental

template <typename Key,
typename Value,
Expand Down
Loading

0 comments on commit c05af72

Please sign in to comment.