Skip to main content

j2k_cuda_runtime/
context.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use std::sync::Arc;
4
5use crate::{
6    error::CudaError,
7    execution::CudaExecutionStats,
8    htj2k_decode::{
9        htj2k_decode_needs_zero_fill, CudaHtj2kCodeBlockJob, CudaHtj2kDecodeOutput,
10        CudaHtj2kDecodeStageTimings,
11    },
12};
13
14mod band_transfer;
15mod compact;
16mod creation;
17mod device;
18mod diagnostics;
19mod host_budget;
20mod inner;
21mod kernel_cache;
22mod kernel_dispatch;
23mod lifecycle;
24mod operations;
25mod pinned_host;
26mod pointer;
27mod resource_creation;
28#[cfg(test)]
29mod test_kernels;
30
31pub use self::compact::{CudaHtj2kCompactEncodedCodeBlock, CudaHtj2kCompactEncodedCodeBlocks};
32pub use self::diagnostics::CudaContextDiagnostics;
33#[doc(hidden)]
34pub use self::host_budget::{CudaExternalHostOwner, CudaExternalHostReservation};
35#[cfg(test)]
36pub(crate) use self::pinned_host::validate_non_null_pinned_host_allocation;
37#[cfg(test)]
38pub(crate) use self::test_kernels::{CudaKernelModule, CudaKernelName};
39pub(crate) use self::{
40    band_transfer::cuda_idwt_trace_enabled,
41    compact::HTJ2K_UVLC_ENCODE_TABLE_BYTES,
42    inner::{ContextInner, ContextOwnership},
43    kernel_cache::{CompiledKernel, CompiledKernelKey},
44    lifecycle::ContextResourceLifecycle,
45    operations::ensure_context_ownership,
46    pinned_host::PinnedUploadStaging,
47    resource_creation::{validate_device_allocation, validate_resource_handle},
48};
49
50/// CUDA driver context shared by J2K CUDA adapter crates.
51#[derive(Clone)]
52pub struct CudaContext {
53    pub(crate) inner: Arc<ContextInner>,
54}
55
56impl CudaContext {
57    /// Returns whether both handles own the same CUDA driver context.
58    #[doc(hidden)]
59    #[must_use]
60    pub fn is_same_context(&self, other: &Self) -> bool {
61        self.inner.context == other.inner.context
62    }
63
64    /// Device ordinal associated with this context.
65    #[doc(hidden)]
66    #[must_use]
67    pub fn device_ordinal(&self) -> usize {
68        self.inner.device_ordinal
69    }
70
71    pub(crate) fn decode_empty_htj2k_codeblocks(
72        &self,
73        jobs: &[CudaHtj2kCodeBlockJob],
74        output_words: usize,
75    ) -> Result<CudaHtj2kDecodeOutput, CudaError> {
76        self.inner.set_current()?;
77        let output_bytes = output_words
78            .checked_mul(std::mem::size_of::<f32>())
79            .ok_or(CudaError::LengthTooLarge { len: output_words })?;
80        let coefficients = self.allocate(output_bytes)?;
81        if htj2k_decode_needs_zero_fill(jobs, output_words)? {
82            self.memset_d32(&coefficients, 0, output_words)?;
83            self.synchronize()?;
84        }
85        Ok(CudaHtj2kDecodeOutput {
86            coefficients,
87            execution: CudaExecutionStats::default(),
88            statuses: Vec::new(),
89            stage_timings: CudaHtj2kDecodeStageTimings::default(),
90        })
91    }
92}
93
94impl std::fmt::Debug for CudaContext {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        f.debug_struct("CudaContext").finish_non_exhaustive()
97    }
98}
99
100#[cfg(test)]
101mod structure_tests;