cuDDL
Loading...
Searching...
No Matches
Public Member Functions | Friends | List of all members
cuddl::host_batch_results Class Reference

Host copy of a batch_result_tile holding only the passing results, packed in query-major, reference order, in pinned memory; tile views it. More...

Public Member Functions

 host_batch_results (cuda::stream_ref stream)
 Empty results to download into, with pinned buffers for stream's device.
 
 host_batch_results (cuda::stream_ref stream, cuda::pinned_memory_pool_ref pool)
 Empty results to download into, with pinned buffers taken from pool.
 
 host_batch_results (host_batch_results const &)=delete
 
host_batch_results & operator= (host_batch_results const &)=delete
 
__host__ host_batch_results (host_batch_results &&other) noexcept
 
__host__ ~host_batch_results ()
 
std::vector< batch_search_result > passing () const
 Every passing result, query-major and in reference order, as full values.
 
std::span< uint32_t const > passing_match_counts () const &noexcept
 The passing results' index match counts, in passing order; empty unless match counts were requested.
 
void passing_match_counts () const &&=delete
 
batch_result_tile tile () const &noexcept
 View of the packed host results; valid while this object lives.
 
void tile () const &&=delete
 

Friends

Result< void > download (batch_result_tile const &, cuda::stream_ref, host_batch_results &)
 Copies a device tile's passing results into host's pinned buffers, growing them only when needed, and synchronizes stream.
 

Detailed Description

Host copy of a batch_result_tile holding only the passing results, packed in query-major, reference order, in pinned memory; tile views it.

Downloading tile after tile into one object reuses its pinned buffers, which only grow when a tile needs more. That keeps pinned allocation, and the pool growth behind it, out of every tile after the first.

Definition at line 334 of file reference_database.cuh.

Constructor & Destructor Documentation

◆ host_batch_results() [1/4]

cuddl::host_batch_results::host_batch_results ( cuda::stream_ref  stream)
inlineexplicit

Empty results to download into, with pinned buffers for stream's device.

Definition at line 337 of file reference_database.cuh.

339 stream,
341 ) {}
host_batch_results(cuda::stream_ref stream)
Empty results to download into, with pinned buffers for stream's device.
@ device_node
The device's host NUMA node, where the system supports NUMA pools: for buffers the device writes,...
cuda::pinned_memory_pool_ref device_pinned_pool(cuda::device_ref device, pinned_placement placement)
A page-locked memory pool accessible from device only.

◆ host_batch_results() [2/4]

cuddl::host_batch_results::host_batch_results ( cuda::stream_ref  stream,
cuda::pinned_memory_pool_ref  pool 
)
inline

Empty results to download into, with pinned buffers taken from pool.

Definition at line 344 of file reference_database.cuh.

345 : pool_(pool),
346 results_(stream, pool, 0, cuda::no_init),
347 match_counts_(stream, pool, 0, cuda::no_init),
348 pass_bits_(stream, pool, 0, cuda::no_init),
349 word_offsets_(stream, pool, 0, cuda::no_init) {}

◆ host_batch_results() [3/4]

cuddl::host_batch_results::host_batch_results ( host_batch_results const &  )
delete

◆ host_batch_results() [4/4]

__host__ cuddl::host_batch_results::host_batch_results ( host_batch_results &&  other)
inlinenoexcept

Definition at line 354 of file reference_database.cuh.

355 : pool_(other.pool_),
356 results_(std::move(other.results_)),
357 match_counts_(std::move(other.match_counts_)),
358 pass_bits_(std::move(other.pass_bits_)),
359 word_offsets_(std::move(other.word_offsets_)),
360 count_(std::exchange(other.count_, 0U)),
361 has_match_counts_(other.has_match_counts_),
362 layout_(other.layout_) {}

◆ ~host_batch_results()

__host__ cuddl::host_batch_results::~host_batch_results ( )
inline

Definition at line 364 of file reference_database.cuh.

364{}

Member Function Documentation

◆ operator=()

host_batch_results & cuddl::host_batch_results::operator= ( host_batch_results const &  )
delete

◆ passing()

std::vector< batch_search_result > cuddl::host_batch_results::passing ( ) const
inline

Every passing result, query-major and in reference order, as full values.

This builds a 24-byte value per result; tile and for_each_passing read the 8-byte packed results without the copy.

Definition at line 370 of file reference_database.cuh.

370 {
371 std::vector<batch_search_result> kept;
372 kept.reserve(static_cast<size_t>(count_));
373 tile().for_each_passing([&](batch_search_result const& result) { kept.push_back(result); });
374 return kept;
375 }
batch_result_tile tile() const &noexcept
View of the packed host results; valid while this object lives.
__host__ __device__ void for_each_passing(F &&f) const
Calls f with every passing result, query-major and in reference order.
Here is the call graph for this function:

◆ passing_match_counts() [1/2]

void cuddl::host_batch_results::passing_match_counts ( ) const &&
delete

◆ passing_match_counts() [2/2]

std::span< uint32_t const > cuddl::host_batch_results::passing_match_counts ( ) const &
inlinenoexcept

The passing results' index match counts, in passing order; empty unless match counts were requested.

Definition at line 380 of file reference_database.cuh.

380 {
381 return {match_counts_.data(), has_match_counts_ ? static_cast<size_t>(count_) : 0U};
382 }

◆ tile() [1/2]

void cuddl::host_batch_results::tile ( ) const &&
delete

◆ tile() [2/2]

batch_result_tile cuddl::host_batch_results::tile ( ) const &
inlinenoexcept

View of the packed host results; valid while this object lives.

Definition at line 386 of file reference_database.cuh.

386 {
387 auto view = layout_;
388 view.results = results_.data();
389 view.match_counts = has_match_counts_ ? match_counts_.data() : nullptr;
390 view.pass_bits = layout_.pass_bits == nullptr ? nullptr : pass_bits_.data();
391 view.word_offsets = layout_.pass_bits == nullptr ? nullptr : word_offsets_.data();
392 return view;
393 }
packed_pairwise_counts const * results
uint32_t const * pass_bits
Passing pairs, when the tile applied a threshold; null when every slot is filled.
Here is the caller graph for this function:

Friends And Related Symbol Documentation

◆ download

Result< void > download ( batch_result_tile const &  tile,
cuda::stream_ref  stream,
host_batch_results &  host 
)
friend

Copies a device tile's passing results into host's pinned buffers, growing them only when needed, and synchronizes stream.

Exhaustive tiles are copied as they are, since every slot passes in order. Threshold tiles are packed on the device: a scan of the pass-bit words gives each word's first packed position, and a gather writes the passing records straight into the host buffer.

Definition at line 427 of file reference_database.cuh.

427 {
428 detail::device_scope const scope{stream};
429 host.layout_ = tile;
430 host.layout_.word_offsets = nullptr;
431 host.has_match_counts_ = tile.match_counts != nullptr;
432 if (tile.pass_bits == nullptr) {
433 auto const slots = static_cast<size_t>(tile.slot_count());
434 host.count_ = slots;
435 host.reserve(host.results_, slots, stream);
436 if (slots != 0U) {
438 cuda::copy_bytes(
439 stream,
440 cuda::std::span{tile.results, slots},
441 cuda::std::span{host.results_.data(), slots}
442 )
443 );
444 }
445 if (host.has_match_counts_) {
446 host.reserve(host.match_counts_, slots, stream);
447 if (slots != 0U) {
449 cuda::copy_bytes(
450 stream,
451 cuda::std::span{tile.match_counts, slots},
452 cuda::std::span{host.match_counts_.data(), slots}
453 )
454 );
455 }
456 }
457 CUDDL_CUDA_TRY(stream.sync());
458 return Ok();
459 }
460
461 auto const words = static_cast<size_t>(tile.query_count) * tile.words_per_query();
462 host.reserve(host.pass_bits_, words, stream);
463 host.reserve(host.word_offsets_, words, stream);
464 if (words == 0U) {
465 host.count_ = 0U;
466 CUDDL_CUDA_TRY(stream.sync());
467 return Ok();
468 }
469 auto const popcounts = cuda::make_transform_iterator(tile.pass_bits, detail::word_popcount{});
470 size_t scan_bytes = 0;
472 cub::DeviceScan::ExclusiveSum(
473 nullptr,
474 scan_bytes,
475 popcounts,
476 host.word_offsets_.data(),
477 static_cast<int64_t>(words),
478 stream.get()
479 )
480 );
481 auto scan_storage = CUDDL_CUDA_TRY(
482 cuda::make_device_buffer<uint8_t>(stream, stream.device(), scan_bytes, cuda::no_init)
483 );
485 cub::DeviceScan::ExclusiveSum(
486 scan_storage.data(),
487 scan_bytes,
488 popcounts,
489 host.word_offsets_.data(),
490 static_cast<int64_t>(words),
491 stream.get()
492 )
493 );
495 cuda::copy_bytes(
496 stream,
497 cuda::std::span{tile.pass_bits, words},
498 cuda::std::span{host.pass_bits_.data(), words}
499 )
500 );
501 CUDDL_CUDA_TRY(stream.sync());
502 host.count_ = static_cast<uint64_t>(host.word_offsets_.data()[words - 1U]) +
503 static_cast<uint64_t>(cuda::std::popcount(host.pass_bits_.data()[words - 1U]));
504 auto const count = static_cast<size_t>(host.count_);
505 host.reserve(host.results_, count, stream);
506 if (host.has_match_counts_) host.reserve(host.match_counts_, count, stream);
507 if (count == 0U) {
508 CUDDL_CUDA_TRY(stream.sync());
509 return Ok();
510 }
511 // Passing records are gathered into bounded device staging, so each chunk crosses the bus as
512 // one bulk copy rather than as scattered small writes.
513 constexpr size_t staging_records = size_t{1} << 23U;
514 auto const staged = std::min(count, staging_records);
515 auto staging = CUDDL_CUDA_TRY(
516 cuda::make_device_buffer<packed_pairwise_counts>(
517 stream, stream.device(), staged, cuda::no_init
518 )
519 );
520 auto staging_matches = CUDDL_CUDA_TRY(
521 cuda::make_device_buffer<uint32_t>(
522 stream, stream.device(), tile.match_counts == nullptr ? 0U : staged, cuda::no_init
523 )
524 );
525 auto const kernel = tile.upper_triangle
526 ? detail::gather_passing_kernel<true, packed_pairwise_counts>
527 : detail::gather_passing_kernel<false, packed_pairwise_counts>;
528 auto const* offsets = host.word_offsets_.data();
529 for (size_t first_word = 0U; first_word < words;) {
530 auto const base = offsets[first_word];
531 // The last word whose results all fit the staging buffer ends the chunk.
532 auto const last_word = static_cast<size_t>(
533 std::upper_bound(offsets + first_word + 1U, offsets + words, base + staged - 32U) -
534 offsets
535 );
536 auto const end = last_word == words ? count : static_cast<size_t>(offsets[last_word]);
537 kernel<<<
538 detail::warp_grid_blocks(last_word - first_word),
540 0,
541 stream.get()>>>(
545 host.word_offsets_.data(),
549 last_word,
550 base,
551 staging.data(),
552 tile.match_counts == nullptr ? nullptr : staging_matches.data()
553 );
554 CUDDL_CUDA_TRY(cudaGetLastError());
555 auto const records = end - base;
556 if (records != 0U) {
558 cuda::copy_bytes(
559 stream,
560 cuda::std::span{staging.data(), records},
561 cuda::std::span{host.results_.data() + base, records}
562 )
563 );
564 if (tile.match_counts != nullptr) {
566 cuda::copy_bytes(
567 stream,
568 cuda::std::span{staging_matches.data(), records},
569 cuda::std::span{host.match_counts_.data() + base, records}
570 )
571 );
572 }
573 }
574 first_word = last_word;
575 }
576 CUDDL_CUDA_TRY(stream.sync());
577 return Ok();
578}
#define CUDDL_CUDA_TRY(...)
Propagates a CUDA error wrapped in cuddl::Result<void>.
Definition error.hpp:248
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 count
Definition kernels.cuh:1031
@ host
Any node: for buffers host threads fill.
constexpr uint32_t block_size
Threads per CTA for the single-pair and cardinality reduction kernels.
Definition kernels.cuh:28
__global__ top_k_slots slots
Definition top_k.cuh:195
__global__ uint32_t uint32_t first_word
Definition top_k.cuh:234
constexpr bool staged
Definition kernels.cuh:1860
auto const words
Definition top_k.cuh:204
::cuda::__ensure_current_context device_scope
Makes stream's device current for the enclosing scope and restores the previous context on exit.
static __global__ uint32_t const * offsets
Definition kernels.cuh:536
Result< void > Ok() noexcept
Success return for Result<void>; same as return {}.
Definition error.hpp:181
uint32_t const * match_counts
Index match counts parallel to results, when requested; otherwise null.
__host__ __device__ constexpr uint32_t words_per_query() const noexcept
__host__ __device__ uint64_t slot_count() const noexcept
Slots of the tile's layout, filled or not.

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