pub mod device;
pub mod memory;
use std::sync::Arc;
use crate::error::{PrismError, Result};
use self::device::GpuDevice;
use self::memory::GpuBuffer;
#[derive(Debug)]
pub struct GpuContext {
device: Arc<GpuDevice>,
}
impl GpuContext {
pub fn new(device_id: usize) -> Result<Arc<Self>> {
let device = Arc::new(GpuDevice::new(device_id)?);
Ok(Arc::new(Self { device }))
}
pub fn is_available() -> bool {
GpuDevice::is_available()
}
pub fn vram_bytes(&self) -> Result<usize> {
self.device.vram_bytes()
}
pub fn max_qubits_for_statevector(&self) -> Result<usize> {
self.device.max_qubits_for_statevector()
}
#[allow(dead_code)]
pub(crate) fn device(&self) -> &GpuDevice {
&self.device
}
#[cfg(test)]
pub(crate) fn stub_for_tests() -> Arc<Self> {
Arc::new(Self {
device: Arc::new(GpuDevice::stub_for_tests()),
})
}
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct GpuState {
context: Arc<GpuContext>,
buffer: GpuBuffer<f64>,
num_qubits: usize,
pending_norm: f64,
}
impl GpuState {
pub fn new(context: Arc<GpuContext>, num_qubits: usize) -> Result<Self> {
let _ = &context;
let _ = num_qubits;
Err(PrismError::BackendUnsupported {
backend: "gpu".to_string(),
operation: "state allocation (scaffold only)".to_string(),
})
}
pub fn num_qubits(&self) -> usize {
self.num_qubits
}
pub fn pending_norm(&self) -> f64 {
self.pending_norm
}
#[allow(dead_code)]
pub(crate) fn context(&self) -> &Arc<GpuContext> {
&self.context
}
#[allow(dead_code)]
pub(crate) fn buffer(&self) -> &GpuBuffer<f64> {
&self.buffer
}
#[allow(dead_code)]
pub(crate) fn buffer_mut(&mut self) -> &mut GpuBuffer<f64> {
&mut self.buffer
}
#[allow(dead_code)]
pub(crate) fn set_pending_norm(&mut self, norm: f64) {
self.pending_norm = norm;
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn context_new_returns_unsupported() {
assert!(matches!(
GpuContext::new(0).unwrap_err(),
PrismError::BackendUnsupported { .. }
));
}
#[test]
fn context_is_available_false_in_scaffold() {
assert!(!GpuContext::is_available());
}
}