use crate::block_manager::v2::physical::transfer::PhysicalLayout;
use crate::block_manager::v2::physical::transfer::context::TransferCompleteNotification;
use anyhow::Result;
use std::ops::Range;
pub fn execute_memcpy_transfer(
src: &PhysicalLayout,
dst: &PhysicalLayout,
src_block_ids: &[usize],
dst_block_ids: &[usize],
layer_range: Option<Range<usize>>,
) -> Result<TransferCompleteNotification> {
let src_layout = src.layout();
let dst_layout = dst.layout();
if src_layout.num_layers() != dst_layout.num_layers() {
return Err(anyhow::anyhow!(
"Layouts have incompatible layer counts: src={}, dst={}",
src_layout.num_layers(),
dst_layout.num_layers()
));
}
if src_layout.outer_dim() != dst_layout.outer_dim() {
return Err(anyhow::anyhow!(
"Layouts have incompatible outer dimensions: src={}, dst={}",
src_layout.outer_dim(),
dst_layout.outer_dim()
));
}
let layers = layer_range.unwrap_or(0..src_layout.num_layers());
for (&src_block_id, &dst_block_id) in src_block_ids.iter().zip(dst_block_ids.iter()) {
for layer_id in layers.clone() {
for outer_id in 0..src_layout.outer_dim() {
let src_region = src.memory_region(src_block_id, layer_id, outer_id)?;
let dst_region = dst.memory_region(dst_block_id, layer_id, outer_id)?;
if src_region.size() != dst_region.size() {
return Err(anyhow::anyhow!(
"Memory region size mismatch at block=({},{}), layer={}, outer={}: src={}, dst={}",
src_block_id,
dst_block_id,
layer_id,
outer_id,
src_region.size(),
dst_region.size()
));
}
unsafe {
let src_ptr = src_region.addr() as *const u8;
let dst_ptr = dst_region.addr() as *mut u8;
std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_region.size());
}
}
}
}
Ok(TransferCompleteNotification::completed())
}