mod composition;
mod compute_block;
mod context;
mod error;
mod policy;
mod resources;
mod scales;
mod strategy;
mod transform;
mod workload;
pub use composition::CompositionMode;
pub use compute_block::{BuiltComputeBlock, ComputeBlock, ComputeBlockBuilder, ExecutionResult};
pub use context::{CpuAffinity, ExecutionContext};
pub use error::{GrammarError, GrammarResult};
pub use policy::{ExecutionPolicy, ObservabilityConfig, QosLevel, ResourceLimits, RetryPolicy};
pub use resources::{ByteSize, ResourceMapping, ScaleBinding};
pub use scales::{LinearResourceScale, LogResourceScale, ResourceScale};
pub use strategy::{ExecutionStrategy, GpuDevice, KernelSpec, SimdWidth, StrategyLayer};
pub use transform::{DataTransform, QuantScheme};
pub use workload::{DataType, Dimensions, Operation, TensorSpec, WorkloadSpec};
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_workload_spec_dot() {
let workload = WorkloadSpec::dot(1000);
assert_eq!(workload.operation, Operation::Dot);
assert_eq!(workload.dimensions.n, 1000);
assert_eq!(workload.flop_count(), 2000);
}
#[test]
fn test_workload_spec_matmul() {
let workload = WorkloadSpec::matmul(64, 64, 64);
assert_eq!(workload.operation, Operation::Matmul);
assert_eq!(workload.dimensions.m, 64);
assert_eq!(workload.dimensions.n, 64);
assert_eq!(workload.dimensions.k, 64);
}
#[test]
fn test_builder_missing_workload() {
let result = ComputeBlock::builder().build();
assert!(matches!(result, Err(GrammarError::MissingWorkload)));
}
#[test]
fn test_builder_with_workload() {
let result = ComputeBlock::builder()
.workload(WorkloadSpec::dot(1000))
.build();
assert!(result.is_ok());
}
#[test]
fn test_strategy_fallback() {
let block = ComputeBlock::builder()
.workload(WorkloadSpec::matmul(1024, 1024, 1024))
.strategy_with_priority(ExecutionStrategy::gpu_auto(), 10)
.strategy_with_priority(ExecutionStrategy::simd_auto(), 5)
.strategy_with_priority(ExecutionStrategy::Sequential, 0)
.build()
.unwrap();
let result = block.execute().unwrap();
assert!(result.strategy_used.contains("Gpu"));
}
#[test]
fn test_execution_policy_realtime() {
let policy = ExecutionPolicy::realtime();
assert_eq!(policy.qos, QosLevel::Realtime);
assert!(!policy.preemptible);
assert!(policy.timeout.is_some());
}
#[test]
fn test_linear_scale() {
let scale = LinearResourceScale::new((0.0, 100.0), (0.0, 8.0)).unwrap();
assert_eq!(scale.scale(50.0), 4.0);
assert_eq!(scale.scale(0.0), 0.0);
assert_eq!(scale.scale(100.0), 8.0);
}
#[test]
fn test_linear_scale_invalid_domain() {
let result = LinearResourceScale::new((100.0, 0.0), (0.0, 8.0));
assert!(matches!(
result,
Err(GrammarError::InvalidScaleDomain { .. })
));
}
#[test]
fn test_data_type_byte_size() {
assert_eq!(DataType::F32.byte_size(), 4);
assert_eq!(DataType::F16.byte_size(), 2);
assert_eq!(DataType::I8.byte_size(), 1);
}
#[test]
fn test_tensor_spec() {
let spec = TensorSpec::new("test", vec![10, 20, 30], DataType::F32);
assert_eq!(spec.numel(), 6000);
assert_eq!(spec.byte_size(), 24000);
}
#[test]
fn test_composition_modes() {
let batch = CompositionMode::batch(32);
assert!(matches!(
batch,
CompositionMode::Batch { batch_size: 32, .. }
));
let dp = CompositionMode::data_parallel(4);
assert!(matches!(dp, CompositionMode::DataParallel { shards: 4 }));
}
#[test]
fn test_transform_identity() {
let t = DataTransform::identity();
assert!(matches!(t, DataTransform::Identity));
}
#[test]
fn test_facet_by() {
let block = ComputeBlock::builder()
.workload(WorkloadSpec::matmul(64, 64, 64))
.facet_by("tile_size", vec![16.0, 32.0, 64.0])
.build()
.unwrap();
assert!(block.inner.facet_params.is_some());
}
}