j2k_cuda_runtime/
context.rs1use 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#[derive(Clone)]
52pub struct CudaContext {
53 pub(crate) inner: Arc<ContextInner>,
54}
55
56impl CudaContext {
57 #[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 #[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;