cuSBF
Loading...
Searching...
No Matches
count_positive_kmers.cuh
Go to the documentation of this file.
1#pragma once
2
3#include <cuda/__cmath/ceil_div.h>
4#include <cuda_runtime.h>
5
6#include <thrust/count.h>
7#include <thrust/device_ptr.h>
8#include <thrust/execution_policy.h>
9
10#include <cstdint>
11
12#include <cusbf/config.cuh>
14#include <cusbf/device_span.cuh>
15#include <cusbf/error.hpp>
16#include <cusbf/helpers.cuh>
17
18namespace cusbf::detail {
19
21template <typename Config>
23 const uint8_t* hits,
24 const QueryLayoutRecord* records,
27) {
28 const uint64_t record_index = static_cast<uint64_t>(blockIdx.x) * blockDim.x + threadIdx.x;
29 if (record_index >= record_count) {
30 return;
31 }
32
33 const QueryLayoutRecord& record = records[record_index];
34 if (record.hit_count == 0) {
35 positive_kmers_out[record_index] = 0;
36 return;
37 }
38
41 for (uint64_t i = 0; i < record.hit_count; ++i) {
42 positive += hits[begin + i];
43 }
44 positive_kmers_out[record_index] = positive;
45}
46
48template <typename Config>
49[[nodiscard]] inline uint64_t
51 if (hits.empty()) {
52 return 0;
53 }
54
55 const auto execution = thrust::cuda::par.on(stream.get());
56 return static_cast<uint64_t>(thrust::count(
58 thrust::device_pointer_cast(hits.data()),
59 thrust::device_pointer_cast(hits.data()) + hits.size(),
60 uint8_t{1}
61 ));
62}
63
69template <typename Config>
74 cuda::stream_ref stream
75) {
76 if (records.empty()) {
77 return {};
78 }
79 if (positive_kmers_out.size() < records.size()) {
80 return Err(Error::invalid_argument("positive k-mer output buffer is too small"));
81 }
82
83 const uint32_t block_size = 256;
84 const uint32_t grid_size = cuda::ceil_div(records.size(), static_cast<uint64_t>(block_size));
86 hits.data(), records.data(), positive_kmers_out.data(), records.size()
87 );
89 return {};
90}
91
92} // namespace cusbf::detail
#define CUSBF_CUDA_TRY(expr)
Propagates a CUDA error wrapped in cusbf::Result<void>.
Definition error.hpp:269
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...
Definition Alphabet.cuh:37
__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.
Definition error.hpp:219
static Error invalid_argument(std::string message)
Definition error.hpp:131
Fallible API result: cuda::std::expected<T, Error> with cuSBF factories.
Definition error.hpp:152
A span that is assumed to point to device-accessible memory.