// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-License-Identifier: Apache-2.0 use super::*; /// Individual block storage #[derive(Debug)] pub struct LocalBlockData { layout: Arc>, block_idx: usize, block_set_idx: usize, worker_id: WorkerID, } impl Clone for LocalBlockData { fn clone(&self) -> Self { Self { layout: self.layout.clone(), block_idx: self.block_idx, block_set_idx: self.block_set_idx, worker_id: self.worker_id, } } } impl LocalBlockData where S: Storage, { /// Create a new block storage pub(crate) fn new( layout: Arc>, block_idx: usize, block_set_idx: usize, worker_id: WorkerID, ) -> Self { Self { layout, block_idx, block_set_idx, worker_id, } } } impl BlockDataExt for LocalBlockData where S: Storage, { #[inline(always)] fn block_id(&self) -> BlockId { self.block_idx } #[inline(always)] fn block_set_id(&self) -> usize { self.block_set_idx } #[inline(always)] fn worker_id(&self) -> WorkerID { self.worker_id } #[inline(always)] fn storage_type(&self) -> &StorageType { self.layout.storage_type() } fn is_fully_contiguous(&self) -> bool { self.layout.layout_type() == LayoutType::FullyContiguous } fn num_layers(&self) -> usize { self.layout.num_layers() } fn num_outer_dims(&self) -> usize { self.layout.outer_dim() } fn num_inner_dims(&self) -> usize { self.layout.inner_dim() } fn page_size(&self) -> usize { self.layout.page_size() } fn is_local(&self) -> Option<&dyn BlockDataViews> { Some(self) } fn is_local_mut(&mut self) -> Option<&mut dyn BlockDataViews> { Some(self) } } impl BlockDataViews for LocalBlockData { fn local_layer_view( &self, layer_idx: usize, outer_idx: usize, ) -> BlockResult> { let mr = self .layout .memory_region(self.block_idx, layer_idx, outer_idx)?; let storage_type = mr.storage_type(); unsafe { view::LayerView::new(self, mr.addr(), mr.size(), storage_type) } } fn local_layer_view_mut( &mut self, layer_idx: usize, outer_idx: usize, ) -> BlockResult> { let mr = self .layout .memory_region(self.block_idx, layer_idx, outer_idx)?; unsafe { view::LayerViewMut::new(self, mr.addr(), mr.size(), mr.storage_type()) } } fn local_block_view(&self) -> BlockResult> { if self.is_fully_contiguous() { let mr = self.layout.memory_region(self.block_idx, 0, 0)?; let offset = mr.addr(); let size = mr.size() * self.num_layers(); let storage_type = mr.storage_type(); unsafe { view::BlockView::new(self, offset, size, storage_type) } } else { Err(BlockError::InvalidState( "Block is not fully contiguous".to_string(), )) } } fn local_block_view_mut(&mut self) -> BlockResult> { if self.is_fully_contiguous() { let mr = self.layout.memory_region(self.block_idx, 0, 0)?; let offset = mr.addr(); let size = mr.size() * self.num_layers(); let storage_type = mr.storage_type(); unsafe { view::BlockViewMut::new(self, offset, size, storage_type) } } else { Err(BlockError::InvalidState( "Block is not fully contiguous".to_string(), )) } } } impl StorageTypeProvider for LocalBlockData { type StorageType = S; } impl BlockDataProvider for LocalBlockData { type Locality = locality::Local; fn block_data(&self) -> &impl BlockDataExt { self } } impl BlockDataProviderMut for LocalBlockData { type Locality = locality::Local; fn block_data_mut(&mut self) -> &mut impl BlockDataExt { self } } impl Local for LocalBlockData {}