use alloc::vec::Vec;
use core::num::NonZeroUsize;
use super::BatchInfrastructureError;
mod planner;
pub use self::planner::plan_ht_gpu_job_chunks;
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HtGpuJobPassBucket {
CleanupOnly,
SigProp,
MagRef,
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HtGpuJobChunkRequest {
source_index: usize,
coding_passes: u8,
payload_bytes: usize,
descriptor_bytes: usize,
}
impl HtGpuJobChunkRequest {
#[doc(hidden)]
#[must_use]
pub const fn new(
source_index: usize,
coding_passes: u8,
payload_bytes: usize,
descriptor_bytes: usize,
) -> Self {
Self {
source_index,
coding_passes,
payload_bytes,
descriptor_bytes,
}
}
#[doc(hidden)]
#[must_use]
pub const fn source_index(self) -> usize {
self.source_index
}
#[doc(hidden)]
#[must_use]
pub const fn coding_passes(self) -> u8 {
self.coding_passes
}
#[doc(hidden)]
#[must_use]
pub const fn payload_bytes(self) -> usize {
self.payload_bytes
}
#[doc(hidden)]
#[must_use]
pub const fn descriptor_bytes(self) -> usize {
self.descriptor_bytes
}
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HtGpuJobChunkLimits {
jobs: NonZeroUsize,
payload_bytes: usize,
descriptor_bytes: usize,
}
impl HtGpuJobChunkLimits {
#[doc(hidden)]
#[must_use]
pub const fn new(
max_jobs: NonZeroUsize,
max_payload_bytes: usize,
max_descriptor_bytes: usize,
) -> Self {
Self {
jobs: max_jobs,
payload_bytes: max_payload_bytes,
descriptor_bytes: max_descriptor_bytes,
}
}
#[doc(hidden)]
#[must_use]
pub const fn max_jobs(self) -> NonZeroUsize {
self.jobs
}
#[doc(hidden)]
#[must_use]
pub const fn max_payload_bytes(self) -> usize {
self.payload_bytes
}
#[doc(hidden)]
#[must_use]
pub const fn max_descriptor_bytes(self) -> usize {
self.descriptor_bytes
}
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HtGpuJobChunkLimit {
PayloadBytes,
DescriptorBytes,
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum HtGpuJobChunkPlanError {
#[error(
"HTJ2K source {source_index} job {original_job_index} has invalid coding-pass count {coding_passes}"
)]
InvalidCodingPassCount {
source_index: usize,
original_job_index: usize,
coding_passes: u8,
},
#[error(
"HTJ2K source {source_index} job {original_job_index} requires {requested} {limit:?}, cap {cap}"
)]
SingleJobTooLarge {
source_index: usize,
original_job_index: usize,
limit: HtGpuJobChunkLimit,
requested: usize,
cap: usize,
},
#[error(transparent)]
BatchInfrastructure(#[from] BatchInfrastructureError),
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HtGpuJobChunkEntry {
original_job_index: usize,
source_index: usize,
}
impl HtGpuJobChunkEntry {
pub(super) const fn new(original_job_index: usize, source_index: usize) -> Self {
Self {
original_job_index,
source_index,
}
}
#[doc(hidden)]
#[must_use]
pub const fn original_job_index(self) -> usize {
self.original_job_index
}
#[doc(hidden)]
#[must_use]
pub const fn source_index(self) -> usize {
self.source_index
}
}
#[doc(hidden)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HtGpuJobChunk {
bucket: HtGpuJobPassBucket,
entry_start: usize,
entry_end: usize,
payload_bytes: usize,
descriptor_bytes: usize,
}
impl HtGpuJobChunk {
pub(super) const fn new(
bucket: HtGpuJobPassBucket,
entry_start: usize,
entry_end: usize,
payload_bytes: usize,
descriptor_bytes: usize,
) -> Self {
Self {
bucket,
entry_start,
entry_end,
payload_bytes,
descriptor_bytes,
}
}
#[doc(hidden)]
#[must_use]
pub const fn bucket(self) -> HtGpuJobPassBucket {
self.bucket
}
#[doc(hidden)]
#[must_use]
pub const fn job_count(self) -> usize {
self.entry_end - self.entry_start
}
#[doc(hidden)]
#[must_use]
pub const fn payload_bytes(self) -> usize {
self.payload_bytes
}
#[doc(hidden)]
#[must_use]
pub const fn descriptor_bytes(self) -> usize {
self.descriptor_bytes
}
}
#[doc(hidden)]
#[derive(Debug, Default, PartialEq, Eq)]
pub struct HtGpuJobChunkPlan {
chunks: Vec<HtGpuJobChunk>,
entries: Vec<HtGpuJobChunkEntry>,
}
impl HtGpuJobChunkPlan {
pub(super) const fn new(chunks: Vec<HtGpuJobChunk>, entries: Vec<HtGpuJobChunkEntry>) -> Self {
Self { chunks, entries }
}
#[doc(hidden)]
#[must_use]
pub fn chunks(&self) -> &[HtGpuJobChunk] {
&self.chunks
}
#[doc(hidden)]
#[must_use]
pub fn entries(&self) -> &[HtGpuJobChunkEntry] {
&self.entries
}
#[doc(hidden)]
#[must_use]
pub fn chunk_entries(&self, chunk_index: usize) -> Option<&[HtGpuJobChunkEntry]> {
let chunk = self.chunks.get(chunk_index)?;
self.entries.get(chunk.entry_start..chunk.entry_end)
}
}
#[cfg(test)]
mod tests;