pub enum IoError {
BufferTooBig {
size: u64,
backtrace: BackTrace,
},
OutOfMemory {
size: u64,
backtrace: BackTrace,
},
PageUpdateForbidden {
size: u64,
backtrace: BackTrace,
},
PageSizesExhausted {
size: u64,
backtrace: BackTrace,
},
UnsupportedStrides {
backtrace: BackTrace,
},
NotFound {
backtrace: BackTrace,
reason: Reason,
},
StorageHandleNotFound {
reason: Reason,
backtrace: BackTrace,
},
StorageMappingFailed {
size: u64,
source: Box<IoError>,
backtrace: BackTrace,
},
DevicePoisoned(DevicePoison),
Unknown {
description: String,
backtrace: BackTrace,
},
UnsupportedIoOperation {
backtrace: BackTrace,
},
}Expand description
Error returned from create/read/write functions. Due to async execution not all errors
are able to be caught, so some IO errors will still panic.
Variants§
BufferTooBig
Buffer size exceeds the max available
OutOfMemory
The device had no memory left for this allocation.
Unlike IoError::BufferTooBig (the allocation can never fit), this
describes the device at one moment: pool pages whose slices have all
been dropped are still resident, and the frees that would release them
may not have reached the driver yet. Reclaiming and retrying is a
reasonable response, which is why a storage backend must not report a
driver out-of-memory as BufferTooBig: that tells every caller the
allocation is hopeless when it is merely untimely.
Fields
PageUpdateForbidden
No room for the allocation in the pages the memory holds, and the reservation was not allowed to add one.
A stream recording a graph reserves this way: an allocation would become part of the recording, and a hardware graph holding one cannot be relaunched. The warmup before a capture is what leaves the pools holding what the recorded run asks for.
PageSizesExhausted
An allocation needs pages of a new size, and the memory already holds as many page sizes as it keeps track of.
Every size a workload grew through keeps a pool until what lives on it is freed or relocated. A cleanup relocates what it can, so reclaiming and retrying is a reasonable response.
UnsupportedStrides
Strides aren’t supported for this copy operation on this runtime
NotFound
Memory wasn’t found in the memory pool
StorageHandleNotFound
The storage backend holds no allocation for a handle’s storage id.
One layer below IoError::NotFound: there the memory manager could
not route a binding to a slice, here the routing succeeded and the
allocation the slice names is gone. A handle outliving its page, or a
storage id a deallocation retired, reaches the storage this way.
Fields
StorageMappingFailed
An allocation carved lazily under a DryRun
could not be given real device backing when it was finally resolved.
Distinct from the same failure at reservation time, and the distinction is what a caller acts on: the memory was promised earlier, by a pass that measured a plan without paying for it, and is only now being charged for. A plan whose replay hits this was measured against more device memory than the replay has — warm the tune caches first, or measure a smaller one.
Fields
DevicePoisoned(DevicePoison)
The device is poisoned: a kernel faulted in a way the driver makes sticky (an illegal address, a trap, a hardware fault, etc.)
Unknown
Unknown error happened during execution
UnsupportedIoOperation
The current IO operation is not supported
Implementations§
Source§impl IoError
impl IoError
Sourcepub fn is_device_poisoned(&self) -> bool
pub fn is_device_poisoned(&self) -> bool
Whether the device that emitted the error is poisoned.
Sourcepub fn may_succeed_after_reclaim(&self) -> bool
pub fn may_succeed_after_reclaim(&self) -> bool
Whether reclaiming memory could still make this allocation succeed.
Out of memory right now is not out of memory for good: pool pages whose slices have all been dropped are still resident, and the frees that would release them may sit in a deferred drop queue. A transient peak — a model build holding float weights while their quantized copies allocate, an autotune sample on a full device — is rescued by a reclaim and a second attempt.
A buffer larger than any page the device can hold is the exception. It never fits, so reclaiming would only spend the time. So is an allocation while a graph records, where nothing may be released.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for IoError
impl<'de> Deserialize<'de> for IoError
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Error for IoError
impl Error for IoError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl From<DevicePoison> for IoError
impl From<DevicePoison> for IoError
Source§fn from(source: DevicePoison) -> Self
fn from(source: DevicePoison) -> Self
Source§impl From<IoError> for ServerError
impl From<IoError> for ServerError
Auto Trait Implementations§
impl Freeze for IoError
impl RefUnwindSafe for IoError
impl Send for IoError
impl Sync for IoError
impl Unpin for IoError
impl UnsafeUnpin for IoError
impl UnwindSafe for IoError
Blanket Implementations§
impl<T> AnyError for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more