cuDDL
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Static Public Member Functions | List of all members
cuddl::detail::reference_database_view< K, BucketCount, Layout > Class Template Reference

Non-owning, trivially copyable view of one selected reference-row backing. More...

Public Types

using score_type = uint16_t
 
using layout_type = Layout
 
using result_type = reference_search_result
 
using batch_result_type = packed_pairwise_counts
 

Public Member Functions

__host__ __device__ constexpr reference_database_view (device_span< uint32_t const > planes, reference_database_metadata metadata, device_span< uint32_t const > index_offsets={}, device_span< uint32_t const > index_postings={}, bool indexed=false, device_span< uint16_t const > index_keys={}, device_span< uint32_t const > key_directory={}, double index_pair_fraction=0.0, device_span< uint32_t const > bitmap_cells={}, device_span< uint32_t const > posting_bitmaps={}, reference_delta_view deltas={}) noexcept
 
__host__ __device__ constexpr device_span< uint32_t const > planes () const noexcept
 Reference bit-plane rows (detail::score_plane_index layout), in reference-ID order.
 
constexpr reference_database_metadata metadata () const noexcept
 Compatibility metadata and reference count.
 
constexpr uint32_t reference_count () const noexcept
 Reference count.
 
constexpr bool has_index () const noexcept
 True when an index backs this view.
 
constexpr size_t persistent_row_bytes () const noexcept
 Bytes this view's own row store needs.
 
constexpr size_t persistent_index_bytes () const noexcept
 Bytes this view's index needs for offsets, postings, and keys.
 
constexpr size_t single_query_workspace_bytes () const noexcept
 Caller-owned bytes for one exhaustive query on this view.
 
constexpr uint32_t single_query_result_count () const noexcept
 Results one exhaustive query writes: one per reference.
 
Result< size_t > indexed_single_query_workspace_bytes (cuda::stream_ref stream) const
 Caller-owned bytes required by one positive-threshold indexed query.
 
Result< cuddl::batch_search_requirements > batch_search_requirements (uint32_t query_count, cuda::stream_ref stream) const
 Storage reused while exhaustively searching query_count compact rows.
 
Result< cuddl::batch_search_requirements > indexed_batch_search_requirements (uint32_t query_count, cuda::stream_ref stream) const
 Storage reused while searching query_count compact rows through the index.
 
Result< cuddl::batch_search_requirements > all_to_all_search_requirements () const
 Storage reused while exhaustively searching every unique database-row pair.
 
Result< cuddl::batch_search_requirements > indexed_all_to_all_search_requirements () const
 Storage for every unique database-row pair through the index, or with a threshold but no index; it also covers the exhaustive all-to-all search.
 
Result< void > search_async (device_span< score_type const > query, score_compatibility const &query_compatibility, device_span< uint8_t > workspace, device_span< result_type > results, cuda::stream_ref stream) const
 Compares one compact query row with every reference row on stream.
 
Result< void > search_indexed_async (device_span< score_type const > query, score_compatibility const &query_compatibility, device_span< uint8_t > workspace, device_span< result_type > results, device_span< uint32_t > result_count, search_options options, cuda::stream_ref stream) const
 Finds and exactly refines references meeting options on stream.
 
template<typename OnTile >
Result< void > search_batch_async (device_span< score_type const > queries, score_compatibility const &query_compatibility, uint32_t query_id_offset, device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, cuda::stream_ref stream) const
 Exhaustively searches compact queries using bounded reusable storage.
 
template<typename OnTile >
Result< void > search_batch_indexed_async (device_span< score_type const > queries, score_compatibility const &query_compatibility, uint32_t query_id_offset, device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, search_options options, cuda::stream_ref stream) const
 Indexed search for compact queries using bounded reusable storage.
 
template<typename OnTile >
Result< void > search_all_to_all_async (device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, cuda::stream_ref stream, all_to_all_shard shard={}) const
 Exhaustively searches every unique database-row pair using bounded storage.
 
template<typename OnTile >
Result< void > search_all_to_all_async (device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, cuda::stream_ref stream, all_to_all_tile_queue &tiles) const
 Exhaustive all-to-all search of the tiles claimed from tiles, which other searches, for example on other devices' replicas, may claim from concurrently.
 
template<typename OnTile >
Result< void > search_all_to_all_indexed_async (device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, search_options options, cuda::stream_ref stream, all_to_all_shard shard={}) const
 Indexed search of every unique database-row pair using bounded storage.
 
template<typename OnTile >
Result< void > search_all_to_all_indexed_async (device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, search_options options, cuda::stream_ref stream, all_to_all_tile_queue &tiles) const
 Indexed all-to-all search of the tiles claimed from tiles, which other searches may claim from concurrently.
 

Static Public Member Functions

static constexpr size_t persistent_row_bytes (uint32_t reference_count) noexcept
 Bytes one compact row store needs for reference_count references.
 
static constexpr size_t single_query_workspace_bytes (uint32_t reference_count) noexcept
 Caller-owned bytes for one exhaustive query: the query's bit-planes.
 
static constexpr uint32_t single_query_result_count (uint32_t reference_count) noexcept
 
static constexpr uint32_t all_to_all_result_capacity (uint32_t reference_count) noexcept
 

Detailed Description

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
class cuddl::detail::reference_database_view< K, BucketCount, Layout >

Non-owning, trivially copyable view of one selected reference-row backing.

Inputs, database rows, workspace, and results must remain valid until the supplied stream completes.

Definition at line 1129 of file reference_database.cuh.

Member Typedef Documentation

◆ batch_result_type

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
using cuddl::detail::reference_database_view< K, BucketCount, Layout >::batch_result_type = packed_pairwise_counts

Definition at line 1138 of file reference_database.cuh.

◆ layout_type

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
using cuddl::detail::reference_database_view< K, BucketCount, Layout >::layout_type = Layout

Definition at line 1136 of file reference_database.cuh.

◆ result_type

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
using cuddl::detail::reference_database_view< K, BucketCount, Layout >::result_type = reference_search_result

Definition at line 1137 of file reference_database.cuh.

◆ score_type

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
using cuddl::detail::reference_database_view< K, BucketCount, Layout >::score_type = uint16_t

Definition at line 1135 of file reference_database.cuh.

Constructor & Destructor Documentation

◆ reference_database_view()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
__host__ __device__ constexpr cuddl::detail::reference_database_view< K, BucketCount, Layout >::reference_database_view ( device_span< uint32_t const >  planes,
reference_database_metadata  metadata,
device_span< uint32_t const >  index_offsets = {},
device_span< uint32_t const >  index_postings = {},
bool  indexed = false,
device_span< uint16_t const >  index_keys = {},
device_span< uint32_t const >  key_directory = {},
double  index_pair_fraction = 0.0,
device_span< uint32_t const >  bitmap_cells = {},
device_span< uint32_t const >  posting_bitmaps = {},
reference_delta_view  deltas = {} 
)
inlineconstexprnoexcept

Definition at line 1140 of file reference_database.cuh.

1143 {},
1144 device_span<uint32_t const> index_postings = {},
1145 bool indexed = false,
1146 device_span<uint16_t const> index_keys = {},
1147 device_span<uint32_t const> key_directory = {},
1148 double index_pair_fraction = 0.0,
1149 device_span<uint32_t const> bitmap_cells = {},
1150 device_span<uint32_t const> posting_bitmaps = {},
1151 reference_delta_view deltas = {}
1152 ) noexcept
1153 : planes_(planes),
1154 metadata_(metadata),
1155 index_offsets_(index_offsets),
1156 index_postings_(index_postings),
1157 index_keys_(index_keys),
1158 key_directory_(key_directory),
1159 bitmap_cells_(bitmap_cells),
1160 posting_bitmaps_(posting_bitmaps),
1161 deltas_(deltas),
1162 index_pair_fraction_(index_pair_fraction),
1163 indexed_(indexed) {}
constexpr reference_database_metadata metadata() const noexcept
Compatibility metadata and reference count.
__host__ __device__ constexpr device_span< uint32_t const > planes() const noexcept
Reference bit-plane rows (detail::score_plane_index layout), in reference-ID order.

Member Function Documentation

◆ all_to_all_result_capacity()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
static constexpr uint32_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::all_to_all_result_capacity ( uint32_t  reference_count)
inlinestaticconstexprnoexcept

Definition at line 1300 of file reference_database.cuh.

1302 {
1303 if (reference_count < 2U) {
1304 return 0U;
1305 }
1307 auto const pair_count = static_cast<uint64_t>(query_count) *
1308 (2ULL * reference_count - query_count - 1ULL) / 2ULL;
1309 auto const tiles = (reference_count + query_count - 1U) / query_count;
1310 return static_cast<uint32_t>(pair_count * pipeline_slots(tiles));
1311 }
constexpr uint32_t reference_count() const noexcept
Reference count.
constexpr uint32_t all_to_all_tile_queries(uint32_t reference_count, uint32_t parts=1U) noexcept
Query rows one all-to-all tile compares: about 2^25 pairs, and at least batch_query_tile_count.
__global__ size_t uint32_t query_count
Definition kernels.cuh:600
auto const tiles
Definition kernels.cuh:937
Here is the call graph for this function:
Here is the caller graph for this function:

◆ all_to_all_search_requirements()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< cuddl::batch_search_requirements > cuddl::detail::reference_database_view< K, BucketCount, Layout >::all_to_all_search_requirements ( ) const
inline

Storage reused while exhaustively searching every unique database-row pair.

Definition at line 1290 of file reference_database.cuh.

1290 {
1291 auto const slot = CUDDL_TRY(all_to_all_slot_pairs());
1292 if (slot > std::numeric_limits<uint32_t>::max() / 2U) {
1293 return Err(Error::resource("all-to-all tile exceeds 32-bit result counts"));
1294 }
1295 return make_batch_requirements(
1296 0U, pipeline_slots(all_to_all_tile_count()) * slot, false, 0U
1297 );
1298 }
#define CUDDL_TRY(expr)
Propagates a cuddl::Result failure from the enclosing function (GNU statement expression).
Definition error.hpp:225
cuda::std::unexpected< Error > Err(Error error)
Failure return; converts to any Result<T> via cuda::std::unexpected.
Definition error.hpp:176
static Error resource(std::string message)
Definition error.hpp:103
Here is the call graph for this function:
Here is the caller graph for this function:

◆ batch_search_requirements()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< cuddl::batch_search_requirements > cuddl::detail::reference_database_view< K, BucketCount, Layout >::batch_search_requirements ( uint32_t  query_count,
cuda::stream_ref  stream 
) const
inline

Storage reused while exhaustively searching query_count compact rows.

Definition at line 1270 of file reference_database.cuh.

1270 {
1271 auto const pair_count =
1272 CUDDL_TRY(dense_batch_pair_count(external_batch_tile(query_count, stream)));
1273 return make_batch_requirements(
1274 pair_count, pair_count, false, pair_count / reference_divisor()
1275 );
1276 }

◆ has_index()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr bool cuddl::detail::reference_database_view< K, BucketCount, Layout >::has_index ( ) const
inlineconstexprnoexcept

True when an index backs this view.

Definition at line 1182 of file reference_database.cuh.

1182 {
1183 return indexed_;
1184 }

◆ indexed_all_to_all_search_requirements()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< cuddl::batch_search_requirements > cuddl::detail::reference_database_view< K, BucketCount, Layout >::indexed_all_to_all_search_requirements ( ) const
inline

Storage for every unique database-row pair through the index, or with a threshold but no index; it also covers the exhaustive all-to-all search.

Definition at line 1316 of file reference_database.cuh.

1316 {
1317 auto requirements = CUDDL_TRY(indexed_all_to_all_tile_search_requirements(
1319 ));
1320 auto const exhaustive = CUDDL_TRY(all_to_all_search_requirements());
1321 requirements.maximum_pair_count =
1322 std::max(requirements.maximum_pair_count, exhaustive.maximum_pair_count);
1323 requirements.result_bytes = std::max(requirements.result_bytes, exhaustive.result_bytes);
1324 requirements.match_count_bytes =
1325 std::max(requirements.match_count_bytes, exhaustive.match_count_bytes);
1326 return requirements;
1327 }
Result< cuddl::batch_search_requirements > all_to_all_search_requirements() const
Storage reused while exhaustively searching every unique database-row pair.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ indexed_batch_search_requirements()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< cuddl::batch_search_requirements > cuddl::detail::reference_database_view< K, BucketCount, Layout >::indexed_batch_search_requirements ( uint32_t  query_count,
cuda::stream_ref  stream 
) const
inline

Storage reused while searching query_count compact rows through the index.

Definition at line 1280 of file reference_database.cuh.

1280 {
1281 CUDDL_TRY(validate_index_storage());
1282 auto const pair_count =
1283 CUDDL_TRY(dense_batch_pair_count(external_batch_tile(query_count, stream)));
1284 return make_batch_requirements(
1285 pair_count, pair_count, true, pair_count / reference_divisor()
1286 );
1287 }
Here is the caller graph for this function:

◆ indexed_single_query_workspace_bytes()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< size_t > cuddl::detail::reference_database_view< K, BucketCount, Layout >::indexed_single_query_workspace_bytes ( cuda::stream_ref  stream) const
inline

Caller-owned bytes required by one positive-threshold indexed query.

Definition at line 1226 of file reference_database.cuh.

1228 {
1229 CUDDL_TRY(validate_index_storage());
1230 if (metadata_.reference_count == 0U) {
1231 return size_t{0};
1232 }
1233
1234 size_t selection_bytes = 0;
1235 auto const ids = cuda::make_counting_iterator(uint32_t{0});
1236 auto const selection = cuda_try(
1237 cub::DeviceSelect::If(
1238 nullptr,
1239 selection_bytes,
1240 ids,
1241 static_cast<uint32_t*>(nullptr),
1242 static_cast<uint32_t*>(nullptr),
1243 static_cast<int64_t>(metadata_.reference_count),
1244 detail::minimum_match_predicate{nullptr, 1U},
1245 stream.get()
1246 )
1247 );
1248 if (!selection) {
1249 return Err(selection.error());
1250 }
1251 // The counting pass stages two words per indexed bucket in the selection storage.
1252 selection_bytes = std::max(
1253 selection_bytes,
1254 static_cast<size_t>(metadata_.compatibility.indexed_bucket_count) * 2U *
1255 sizeof(uint32_t)
1256 );
1257
1258 constexpr size_t alignment_slack = plane_alignment - 1U + 3U + 255U;
1259 auto const arrays_bytes =
1260 query_plane_bytes(1U) +
1261 static_cast<size_t>(metadata_.reference_count) * 2U * sizeof(uint32_t);
1262 if (selection_bytes > std::numeric_limits<size_t>::max() - arrays_bytes - alignment_slack) {
1263 return Err(Error::resource("indexed single-query workspace size overflows"));
1264 }
1265 return arrays_bytes + alignment_slack + selection_bytes;
1266 }
__global__ uint32_t uint32_t uint64_t uint32_t * ids
Result< void > cuda_try(cudaError_t error, std::source_location location=std::source_location::current())
Checks a CUDA runtime call and returns an error on failure.
Definition error.hpp:187
Here is the call graph for this function:
Here is the caller graph for this function:

◆ metadata()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr reference_database_metadata cuddl::detail::reference_database_view< K, BucketCount, Layout >::metadata ( ) const
inlineconstexprnoexcept

Compatibility metadata and reference count.

Definition at line 1172 of file reference_database.cuh.

1172 {
1173 return metadata_;
1174 }

◆ persistent_index_bytes()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr size_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::persistent_index_bytes ( ) const
inlineconstexprnoexcept

Bytes this view's index needs for offsets, postings, and keys.

Definition at line 1197 of file reference_database.cuh.

1197 {
1198 return index_offsets_.size_bytes() + index_postings_.size_bytes() +
1199 index_keys_.size_bytes();
1200 }

◆ persistent_row_bytes() [1/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr size_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::persistent_row_bytes ( ) const
inlineconstexprnoexcept

Bytes this view's own row store needs.

Definition at line 1192 of file reference_database.cuh.

1192 {
1193 return planes_.size_bytes();
1194 }
Here is the caller graph for this function:

◆ persistent_row_bytes() [2/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
static constexpr size_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::persistent_row_bytes ( uint32_t  reference_count)
inlinestaticconstexprnoexcept

Bytes one compact row store needs for reference_count references.

Definition at line 1187 of file reference_database.cuh.

1187 {
1188 return static_cast<size_t>(reference_count) * BucketCount * sizeof(score_type);
1189 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ planes()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
__host__ __device__ constexpr device_span< uint32_t const > cuddl::detail::reference_database_view< K, BucketCount, Layout >::planes ( ) const
inlineconstexprnoexcept

Reference bit-plane rows (detail::score_plane_index layout), in reference-ID order.

Definition at line 1167 of file reference_database.cuh.

1167 {
1168 return planes_;
1169 }

◆ reference_count()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr uint32_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::reference_count ( ) const
inlineconstexprnoexcept

Reference count.

Definition at line 1177 of file reference_database.cuh.

1177 {
1178 return metadata_.reference_count;
1179 }
Here is the caller graph for this function:

◆ search_all_to_all_async() [1/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_all_to_all_async ( device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
cuda::stream_ref  stream,
all_to_all_shard  shard = {} 
) const
inline

Exhaustively searches every unique database-row pair using bounded storage.

on_tile receives each tile's batch_result_tile. Before returning, it must consume the tile synchronously or enqueue dependent work on stream because the supplied storage is reused by the next tile. shard restricts the search to one part of the pairs.

Definition at line 1670 of file reference_database.cuh.

1676 {}
1677 ) const {
1680 workspace, results, std::forward<OnTile>(on_tile), result_match_counts, stream, tiles
1681 );
1682 }
static Result< all_to_all_tile_queue > make(uint32_t reference_count, all_to_all_shard shard={}, uint32_t searchers=1U, std::function< uint64_t()> next_tile={})
Result< void > search_all_to_all_async(device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, cuda::stream_ref stream, all_to_all_shard shard={}) const
Exhaustively searches every unique database-row pair using bounded storage.
__global__ uint32_t uint32_t uint32_t const uint32_t uint32_t uint16_t uint32_t const SearchResult uint32_t * result_match_counts
Definition kernels.cuh:1852
__global__ uint32_t const uint32_t uint32_t const uint32_t const SearchResult * results
Definition kernels.cuh:1544
Here is the caller graph for this function:

◆ search_all_to_all_async() [2/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_all_to_all_async ( device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
cuda::stream_ref  stream,
all_to_all_tile_queue &  tiles 
) const
inline

Exhaustive all-to-all search of the tiles claimed from tiles, which other searches, for example on other devices' replicas, may claim from concurrently.

Definition at line 1687 of file reference_database.cuh.

1694 {
1695 device_scope const scope{stream};
1696 CUDDL_TRY(validate_stored_rows());
1697 CUDDL_TRY(validate_tile_queue(tiles));
1698 auto const requirements = CUDDL_TRY(all_to_all_search_requirements());
1699 CUDDL_TRY(validate_batch_outputs(requirements, results, result_match_counts));
1700 std::vector<all_to_all_tile_queue::tile> claimed;
1701 return pipeline_tiles(
1702 [&]() -> std::optional<uint32_t> {
1703 auto const tile = tiles.claim();
1704 if (!tile) return std::nullopt;
1705 claimed.push_back(*tile);
1706 return static_cast<uint32_t>(claimed.size() - 1U);
1707 },
1708 CUDDL_TRY(all_to_all_slot_pairs()),
1709 results,
1711 [&](uint32_t index,
1712 device_span<batch_result_type> slot_results,
1713 device_span<uint32_t> slot_matches,
1714 cuda::stream_ref work) {
1715 auto const tile = claimed[index];
1716 return launch_batch_exhaustive<true>(
1717 {},
1718 tile.first_query_id,
1719 tile.query_count,
1720 tile.first_query_id,
1721 workspace,
1722 slot_results,
1723 slot_matches,
1724 work
1725 );
1726 },
1727 on_tile,
1728 stream
1729 );
1730 }
__global__ size_t uint32_t const uint32_t const uint32_t uint32_t uint16_t uint32_t tile
Definition kernels.cuh:922
::cuda::__ensure_current_context device_scope
Makes stream's device current for the enclosing scope and restores the previous context on exit.
__global__ uint16_t const uint32_t uint32_t uint32_t unsigned long long * work
Definition kernels.cuh:474
Here is the call graph for this function:

◆ search_all_to_all_indexed_async() [1/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_all_to_all_indexed_async ( device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
search_options  options,
cuda::stream_ref  stream,
all_to_all_shard  shard = {} 
) const
inline

Indexed search of every unique database-row pair using bounded storage.

on_tile receives each tile's batch_result_tile, holding exactly the pairs with at least options.minimum_matches index matches. Before returning, it must consume the tile synchronously or enqueue dependent work on stream because the supplied storage is reused by the next tile. shard restricts the search to one part of the pairs.

Definition at line 1741 of file reference_database.cuh.

1748 {}
1749 ) const {
1752 workspace,
1753 results,
1754 std::forward<OnTile>(on_tile),
1756 options,
1757 stream,
1758 tiles
1759 );
1760 }
Result< void > search_all_to_all_indexed_async(device_span< uint8_t > workspace, device_span< batch_result_type > results, OnTile &&on_tile, device_span< uint32_t > result_match_counts, search_options options, cuda::stream_ref stream, all_to_all_shard shard={}) const
Indexed search of every unique database-row pair using bounded storage.

◆ search_all_to_all_indexed_async() [2/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_all_to_all_indexed_async ( device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
search_options  options,
cuda::stream_ref  stream,
all_to_all_tile_queue &  tiles 
) const
inline

Indexed all-to-all search of the tiles claimed from tiles, which other searches may claim from concurrently.

Definition at line 1765 of file reference_database.cuh.

1773 {
1774 device_scope const scope{stream};
1775 CUDDL_TRY(validate_stored_rows());
1776 CUDDL_TRY(validate_tile_queue(tiles));
1777 auto const requirements = CUDDL_TRY(indexed_all_to_all_search_requirements());
1778 CUDDL_TRY(validate_indexed_batch_inputs(
1779 requirements, workspace, results, result_match_counts, options
1780 ));
1781 // Every tile reuses the same storage, so the next tile is claimed once the previous
1782 // tile's consumers are done; tiles claimed from a shared queue then go to whichever
1783 // device frees up first.
1784 std::optional<cuda::event> consumed;
1785 while (true) {
1786 if (consumed) CUDDL_CUDA_TRY(consumed->sync());
1787 auto const tile = tiles.claim();
1788 if (!tile) break;
1789 on_tile(CUDDL_TRY(
1790 launch_batch_indexed<true>(
1791 nullptr,
1792 tile->first_query_id,
1793 tile->query_count,
1794 tile->first_query_id,
1795 workspace,
1796 results,
1798 options,
1799 stream
1800 )
1801 ));
1802 if (!consumed) consumed.emplace(CUDDL_CUDA_TRY(cuda::event(stream.device())));
1803 CUDDL_CUDA_TRY(consumed->record(stream));
1804 }
1805 return Ok();
1806 }
Result< cuddl::batch_search_requirements > indexed_all_to_all_search_requirements() const
Storage for every unique database-row pair through the index, or with a threshold but no index; it al...
#define CUDDL_CUDA_TRY(...)
Propagates a CUDA error wrapped in cuddl::Result<void>.
Definition error.hpp:248
Result< void > Ok() noexcept
Success return for Result<void>; same as return {}.
Definition error.hpp:181
Here is the call graph for this function:

◆ search_async()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_async ( device_span< score_type const >  query,
score_compatibility const &  query_compatibility,
device_span< uint8_t >  workspace,
device_span< result_type >  results,
cuda::stream_ref  stream 
) const
inline

Compares one compact query row with every reference row on stream.

Definition at line 1330 of file reference_database.cuh.

1336 {
1337 device_scope const scope{stream};
1338 auto const expected_scores = static_cast<size_t>(metadata_.reference_count) * BucketCount;
1339 if (!rows_match_metadata(expected_scores)) {
1340 return Err(Error::invalid_argument("database extent does not match its metadata"));
1341 }
1342 if (query.size() != BucketCount || query.data() == nullptr) {
1343 return Err(Error::invalid_argument("query must contain one complete score row"));
1344 }
1345 CUDDL_TRY(
1346 (detail::validate_score_compatibility<K, BucketCount, Layout>(query_compatibility))
1347 );
1348 if (query_compatibility != metadata_.compatibility) {
1349 return Err(Error::invalid_argument("query construction metadata is incompatible"));
1350 }
1351 if (workspace.size_bytes() < single_query_workspace_bytes()) {
1352 return Err(Error::resource("single-query workspace is too small"));
1353 }
1354 if (results.size() < metadata_.reference_count) {
1355 return Err(Error::resource("single-query result capacity is too small"));
1356 }
1357 if (metadata_.reference_count == 0U) {
1358 return Ok();
1359 }
1360 if (results.data() == nullptr) {
1361 return Err(Error::invalid_argument("result storage must be device accessible"));
1362 }
1363
1364 if (workspace.data() == nullptr) {
1365 return Err(Error::invalid_argument("single-query workspace must be device accessible"));
1366 }
1367 auto* query_planes = CUDDL_TRY(stage_query_planes(query, 0U, 1U, workspace, stream));
1368 detail::single_query_planes_kernel<BucketCount>
1371 0,
1372 stream.get()>>>(
1373 query_planes,
1374 planes_.data(),
1375 metadata_.reference_count,
1376 nullptr,
1377 nullptr,
1378 results.data()
1379 );
1380 return cuda_try(cudaGetLastError());
1381 }
constexpr size_t single_query_workspace_bytes() const noexcept
Caller-owned bytes for one exhaustive query on this view.
uint32_t warp_grid_blocks(size_t warps) noexcept
Blocks for a grid-stride launch covering warps warps of block_size threads.
Definition kernels.cuh:1524
auto const * query
Definition kernels.cuh:1030
constexpr uint32_t block_size
Threads per CTA for the single-pair and cardinality reduction kernels.
Definition kernels.cuh:28
static Error invalid_argument(std::string message)
Definition error.hpp:99
Here is the call graph for this function:
Here is the caller graph for this function:

◆ search_batch_async()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_batch_async ( device_span< score_type const >  queries,
score_compatibility const &  query_compatibility,
uint32_t  query_id_offset,
device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
cuda::stream_ref  stream 
) const
inline

Exhaustively searches compact queries using bounded reusable storage.

on_tile receives each tile's batch_result_tile. Before returning, it must consume the tile synchronously or enqueue dependent work on stream because the supplied storage is reused by the next tile.

Definition at line 1563 of file reference_database.cuh.

1572 {
1573 device_scope const scope{stream};
1574 auto const query_count =
1575 CUDDL_TRY(validate_batch_queries(queries, query_compatibility, query_id_offset));
1576 auto const requirements = CUDDL_TRY(batch_search_requirements(query_count, stream));
1577 CUDDL_TRY(validate_batch_outputs(requirements, results, result_match_counts));
1578 CUDDL_TRY(validate_workspace(requirements, workspace));
1579 // Result storage holds one full-size tile; two half-size tiles alternate in it.
1580 auto const storage_queries = external_batch_tile(query_count, stream);
1581 auto const tile_size = storage_queries < 2U ? storage_queries : storage_queries / 2U;
1582 auto const tiles = tile_size == 0U ? 0U : (query_count + tile_size - 1U) / tile_size;
1583 auto const slot = static_cast<size_t>(tile_size) * metadata_.reference_count;
1584 uint32_t next_tile = 0U;
1585 return pipeline_tiles(
1586 [&]() -> std::optional<uint32_t> {
1587 if (next_tile >= tiles) return std::nullopt;
1588 return next_tile++;
1589 },
1590 slot,
1591 results,
1593 [&](uint32_t tile,
1594 device_span<batch_result_type> slot_results,
1595 device_span<uint32_t> slot_matches,
1596 cuda::stream_ref work) {
1597 auto const first_query_id = tile * tile_size;
1598 return launch_batch_exhaustive<false>(
1599 queries,
1601 std::min(tile_size, query_count - first_query_id),
1603 workspace,
1604 slot_results,
1605 slot_matches,
1606 work
1607 );
1608 },
1609 on_tile,
1610 stream
1611 );
1612 }
Result< cuddl::batch_search_requirements > batch_search_requirements(uint32_t query_count, cuda::stream_ref stream) const
Storage reused while exhaustively searching query_count compact rows.
__global__ uint32_t const uint32_t const uint32_t const uint32_t first_query_id
Definition kernels.cuh:1786
__global__ size_t uint32_t const uint32_t const uint32_t uint32_t uint16_t uint32_t uint32_t uint16_t const uint2 const uint32_t uint32_t query_id_offset
Definition kernels.cuh:927
Here is the caller graph for this function:

◆ search_batch_indexed_async()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
template<typename OnTile >
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_batch_indexed_async ( device_span< score_type const >  queries,
score_compatibility const &  query_compatibility,
uint32_t  query_id_offset,
device_span< uint8_t >  workspace,
device_span< batch_result_type >  results,
OnTile &&  on_tile,
device_span< uint32_t >  result_match_counts,
search_options  options,
cuda::stream_ref  stream 
) const
inline

Indexed search for compact queries using bounded reusable storage.

on_tile receives each tile's batch_result_tile, holding exactly the pairs with at least options.minimum_matches index matches. Before returning, it must consume the tile synchronously or enqueue dependent work on stream because the supplied storage is reused by the next tile.

Definition at line 1623 of file reference_database.cuh.

1633 {
1634 device_scope const scope{stream};
1635 auto const query_count =
1636 CUDDL_TRY(validate_batch_queries(queries, query_compatibility, query_id_offset));
1637 auto const requirements = CUDDL_TRY(indexed_batch_search_requirements(query_count, stream));
1638 CUDDL_TRY(validate_indexed_batch_inputs(
1639 requirements, workspace, results, result_match_counts, options
1640 ));
1641 auto const tile_size = external_batch_tile(query_count, stream);
1642 for (uint32_t first_query_id = 0U; tile_size != 0U && first_query_id < query_count;
1643 first_query_id += tile_size) {
1644 auto const tile_query_count = std::min(tile_size, query_count - first_query_id);
1645 on_tile(CUDDL_TRY(
1646 launch_batch_indexed<false>(
1647 queries.data() + static_cast<size_t>(first_query_id) * BucketCount,
1649 tile_query_count,
1651 workspace,
1652 results,
1654 options,
1655 stream
1656 )
1657 ));
1658 }
1659 return Ok();
1660 }
Result< cuddl::batch_search_requirements > indexed_batch_search_requirements(uint32_t query_count, cuda::stream_ref stream) const
Storage reused while searching query_count compact rows through the index.
Here is the call graph for this function:

◆ search_indexed_async()

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
Result< void > cuddl::detail::reference_database_view< K, BucketCount, Layout >::search_indexed_async ( device_span< score_type const >  query,
score_compatibility const &  query_compatibility,
device_span< uint8_t >  workspace,
device_span< result_type >  results,
device_span< uint32_t >  result_count,
search_options  options,
cuda::stream_ref  stream 
) const
inline

Finds and exactly refines references meeting options on stream.

Definition at line 1384 of file reference_database.cuh.

1392 {
1393 device_scope const scope{stream};
1394 auto const expected_scores = static_cast<size_t>(metadata_.reference_count) * BucketCount;
1395 if (!rows_match_metadata(expected_scores)) {
1396 return Err(Error::invalid_argument("database extent does not match its metadata"));
1397 }
1398 CUDDL_TRY(validate_index_storage());
1399 if (query.size() != BucketCount || query.data() == nullptr) {
1400 return Err(Error::invalid_argument("query must contain one complete score row"));
1401 }
1402 CUDDL_TRY(
1403 (detail::validate_score_compatibility<K, BucketCount, Layout>(query_compatibility))
1404 );
1405 if (query_compatibility != metadata_.compatibility) {
1406 return Err(Error::invalid_argument("query construction metadata is incompatible"));
1407 }
1408 if (options.minimum_matches > metadata_.compatibility.indexed_bucket_count) {
1409 return Err(Error::invalid_argument("minimum matches exceeds indexed bucket count"));
1410 }
1411 if (results.size() < metadata_.reference_count) {
1412 return Err(Error::resource("indexed result capacity is too small"));
1413 }
1414 if (result_count.empty()) {
1415 return Err(Error::resource("indexed result count capacity is too small"));
1416 }
1417 if (result_count.data() == nullptr) {
1418 return Err(Error::invalid_argument("result count storage must be device accessible"));
1419 }
1420 if (metadata_.reference_count != 0U && results.data() == nullptr) {
1421 return Err(Error::invalid_argument("result storage must be device accessible"));
1422 }
1423
1424 if (options.minimum_matches == 0U) {
1425 CUDDL_TRY(search_async(query, query_compatibility, workspace, results, stream));
1426 return write_batch_result_count(metadata_.reference_count, result_count, stream);
1427 }
1428 if (metadata_.reference_count == 0U) {
1429 return write_batch_result_count(0U, result_count, stream);
1430 }
1431
1432 auto const required_workspace = CUDDL_TRY(indexed_single_query_workspace_bytes(stream));
1433 if (workspace.size_bytes() < required_workspace) {
1434 return Err(Error::resource("indexed single-query workspace is too small"));
1435 }
1436 if (workspace.data() == nullptr) {
1437 return Err(Error::invalid_argument("indexed workspace must be device accessible"));
1438 }
1439
1440 auto const workspace_begin = reinterpret_cast<uintptr_t>(workspace.data());
1441 auto const workspace_end = workspace_begin + workspace.size_bytes();
1442 if (workspace_end < workspace_begin) {
1443 return Err(Error::resource("indexed workspace address range overflows"));
1444 }
1445 auto* query_planes = CUDDL_TRY(stage_query_planes(query, 0U, 1U, workspace, stream));
1446 auto address = detail::align_up(
1447 reinterpret_cast<uintptr_t>(query_planes) + query_plane_bytes(1U), alignof(uint32_t)
1448 );
1449 auto* match_counts = reinterpret_cast<uint32_t*>(address);
1450 address += static_cast<size_t>(metadata_.reference_count) * sizeof(uint32_t);
1451 address = detail::align_up(address, alignof(uint32_t));
1452 auto* candidate_ids = reinterpret_cast<uint32_t*>(address);
1453 address += static_cast<size_t>(metadata_.reference_count) * sizeof(uint32_t);
1454 address = detail::align_up(address, 256U);
1455 if (address > workspace_end) {
1456 return Err(Error::resource("indexed workspace layout exceeds its capacity"));
1457 }
1458 auto* selection_workspace = reinterpret_cast<void*>(address);
1459 auto selection_bytes = static_cast<size_t>(workspace_end - address);
1460
1461 if (!indexed_) {
1462 detail::count_plane_matches_kernel<BucketCount>
1465 0,
1466 stream.get()>>>(
1467 query_planes,
1468 1U,
1469 planes_.data(),
1470 metadata_.reference_count,
1472 metadata_.compatibility.key_mask,
1474 );
1475 CUDDL_CUDA_TRY(cudaGetLastError());
1476 } else {
1478 cuda::fill_bytes(
1479 stream,
1480 cuda::std::span{match_counts, static_cast<size_t>(metadata_.reference_count)},
1481 0
1482 )
1483 );
1484 // The posting ranges live in the selection workspace, which is free until the
1485 // selection below runs on the same stream.
1487 auto* range_begin = static_cast<uint32_t*>(selection_workspace);
1489 detail::index_posting_ranges_kernel<<<
1490 1,
1492 0,
1493 stream.get()>>>(
1494 query.data(),
1495 index_offsets_.data(),
1496 index_keys_.empty() ? nullptr : index_keys_.data(),
1497 metadata_.reference_count,
1499 metadata_.compatibility.key_mask,
1502 );
1503 CUDDL_CUDA_TRY(cudaGetLastError());
1504 auto const counting_blocks =
1505 static_cast<uint32_t>(
1506 stream.device().attribute(cuda::device_attributes::multiprocessor_count)
1507 ) *
1508 static_cast<uint32_t>(stream.device().attribute(
1509 cuda::device_attributes::max_threads_per_multiprocessor
1510 )) /
1512 detail::count_balanced_index_matches_kernel<<<
1513 counting_blocks,
1515 0,
1516 stream.get()>>>(
1520 index_postings_.data(),
1522 );
1523 CUDDL_CUDA_TRY(cudaGetLastError());
1524 }
1525
1526 auto const ids = cuda::make_counting_iterator(uint32_t{0});
1528 cub::DeviceSelect::If(
1529 selection_workspace,
1530 selection_bytes,
1531 ids,
1533 result_count.data(),
1534 static_cast<int64_t>(metadata_.reference_count),
1535 detail::minimum_match_predicate{match_counts, options.minimum_matches},
1536 stream.get()
1537 )
1538 );
1539
1540 detail::single_query_planes_kernel<BucketCount>
1543 0,
1544 stream.get()>>>(
1545 query_planes,
1546 planes_.data(),
1547 metadata_.reference_count,
1549 result_count.data(),
1550 results.data()
1551 );
1552 return cuda_try(cudaGetLastError());
1553 }
Result< void > search_async(device_span< score_type const > query, score_compatibility const &query_compatibility, device_span< uint8_t > workspace, device_span< result_type > results, cuda::stream_ref stream) const
Compares one compact query row with every reference row on stream.
Result< size_t > indexed_single_query_workspace_bytes(cuda::stream_ref stream) const
Caller-owned bytes required by one positive-threshold indexed query.
constexpr uint32_t posting_range_block_size
Threads of the single index_posting_ranges_kernel block.
Definition kernels.cuh:527
static __global__ uint32_t const uint32_t uint32_t const uint32_t * match_counts
Definition kernels.cuh:576
__global__ uint32_t uint32_t indexed_bucket_count
Definition kernels.cuh:438
static __global__ uint32_t const uint16_t const uint32_t uint32_t uint16_t uint32_t uint32_t * range_end_scan
Definition kernels.cuh:543
uintptr_t align_up(uintptr_t address, size_t alignment) noexcept
static __global__ uint32_t const uint16_t const uint32_t uint32_t uint16_t uint32_t * range_begin
Definition kernels.cuh:541
__global__ uint32_t const uint32_t uint32_t const * candidate_ids
Definition kernels.cuh:1541
Here is the call graph for this function:

◆ single_query_result_count() [1/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr uint32_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::single_query_result_count ( ) const
inlineconstexprnoexcept

Results one exhaustive query writes: one per reference.

Definition at line 1221 of file reference_database.cuh.

1221 {
1222 return metadata_.reference_count;
1223 }
Here is the caller graph for this function:

◆ single_query_result_count() [2/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
static constexpr uint32_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::single_query_result_count ( uint32_t  reference_count)
inlinestaticconstexprnoexcept

Definition at line 1214 of file reference_database.cuh.

1216 {
1217 return reference_count;
1218 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ single_query_workspace_bytes() [1/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
constexpr size_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::single_query_workspace_bytes ( ) const
inlineconstexprnoexcept

Caller-owned bytes for one exhaustive query on this view.

Definition at line 1210 of file reference_database.cuh.

1210 {
1212 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ single_query_workspace_bytes() [2/2]

template<uint32_t K, size_t BucketCount, typename Layout = default_register_layout>
static constexpr size_t cuddl::detail::reference_database_view< K, BucketCount, Layout >::single_query_workspace_bytes ( uint32_t  reference_count)
inlinestaticconstexprnoexcept

Caller-owned bytes for one exhaustive query: the query's bit-planes.

Definition at line 1203 of file reference_database.cuh.

1205 {
1206 return reference_count == 0U ? 0U : query_plane_bytes(1U) + plane_alignment - 1U;
1207 }
Here is the call graph for this function:
Here is the caller graph for this function:

The documentation for this class was generated from the following file: