3#include <cuda/__cmath/ceil_div.h>
4#include <cuda_runtime.h>
6#include <thrust/count.h>
7#include <thrust/device_ptr.h>
8#include <thrust/execution_policy.h>
21template <
typename Config>
34 if (
record.hit_count == 0) {
48template <
typename Config>
56 return static_cast<uint64_t>(thrust::count(
58 thrust::device_pointer_cast(hits.data()),
59 thrust::device_pointer_cast(hits.data()) + hits.size(),
69template <
typename Config>
76 if (records.empty()) {
#define CUSBF_CUDA_TRY(expr)
Propagates a CUDA error wrapped in cusbf::Result<void>.
Result< void > count_positive_kmers_per_record(device_span< const uint8_t > hits, device_span< const QueryLayoutRecord > records, device_span< uint64_t > positive_kmers_out, cuda::stream_ref stream)
Fills positive_kmers_out with per-record positive k-mer counts.
uint64_t count_positive_kmers_total(device_span< const uint8_t > hits, cuda::stream_ref stream)
Device-wide count of set bits in a per-k-mer hit buffer.
consteval bool separatorPositionAlwaysEncodesInvalid(char *input, uint64_t separatorPosition, uint64_t index)
Recursively tests whether placing the separator byte at any position in an input of valid bytes alway...
__global__ void count_positive_kmers_per_record_kernel(const uint8_t *hits, const QueryLayoutRecord *records, uint64_t *positive_kmers_out, uint64_t record_count)
Per-record kernel: sums hits[hit_offset ..] for each QueryLayoutRecord.
cuda::std::unexpected< Error > Err(Error error)
Failure return; converts to any Result<T> via cuda::std::unexpected.
static Error invalid_argument(std::string message)
Fallible API result: cuda::std::expected<T, Error> with cuSBF factories.
A span that is assumed to point to device-accessible memory.