use std::sync::{Arc, OnceLock};
use rustc_hash::FxHashMap;
use crate::ir_inner::model::node::Node;
use super::BufferDecl;
#[derive(Debug)]
pub struct Program {
pub entry_op_id: Option<String>,
pub buffers: Arc<[BufferDecl]>,
pub(crate) buffer_index: Arc<FxHashMap<Arc<str>, usize>>,
pub workgroup_size: [u32; 3],
pub entry: Arc<Vec<Node>>,
pub(crate) hash: OnceLock<blake3::Hash>,
#[doc(hidden)]
pub(crate) validation_set: Arc<dashmap::DashSet<Arc<str>>>,
pub(crate) structural_validated: std::sync::atomic::AtomicBool,
pub(crate) fingerprint: OnceLock<[u8; 32]>,
pub(crate) output_buffer_index: OnceLock<Arc<Vec<u32>>>,
pub(crate) has_indirect_dispatch: OnceLock<bool>,
pub(crate) stats: OnceLock<Arc<super::ProgramStats>>,
pub non_composable_with_self: bool,
}
impl Default for Program {
#[inline]
fn default() -> Self {
Self::empty()
}
}
impl Clone for Program {
fn clone(&self) -> Self {
let cloned = Self {
entry_op_id: self.entry_op_id.clone(),
buffers: Arc::clone(&self.buffers),
buffer_index: Arc::clone(&self.buffer_index),
workgroup_size: self.workgroup_size,
entry: Arc::clone(&self.entry),
hash: OnceLock::new(),
validation_set: Arc::clone(&self.validation_set),
structural_validated: std::sync::atomic::AtomicBool::new(
self.is_structurally_validated(),
),
fingerprint: OnceLock::new(),
output_buffer_index: OnceLock::new(),
has_indirect_dispatch: OnceLock::new(),
stats: OnceLock::new(),
non_composable_with_self: self.non_composable_with_self,
};
if let Some(hash) = self.hash.get() {
let _ = cloned.hash.set(*hash);
}
if let Some(fingerprint) = self.fingerprint.get() {
let _ = cloned.fingerprint.set(*fingerprint);
}
if let Some(output_buffer_index) = self.output_buffer_index.get() {
let _ = cloned
.output_buffer_index
.set(Arc::clone(output_buffer_index));
}
if let Some(has_indirect_dispatch) = self.has_indirect_dispatch.get() {
let _ = cloned.has_indirect_dispatch.set(*has_indirect_dispatch);
}
if let Some(stats) = self.stats.get() {
let _ = cloned.stats.set(Arc::clone(stats));
}
cloned
}
}
impl PartialEq for Program {
fn eq(&self, other: &Self) -> bool {
self.structural_eq(other)
}
}
impl Eq for Program {}