rtx-cfd legacy GPU tests: the current CudaKernelManager API (Arc-held manager, allocate-on-copy, copy_from_device returning the host vector), MatrixOpsKernel::tridiagonal_matvec added over the existing kernel, PoissonKernel::solve_jacobi_2d kept as the older name; CfdConfig literals take ..Default
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Build CPU-Only (Explicit) (push) Failing after 6s
CI / Build (ubuntu-latest) (push) Failing after 6s
Documentation / Build API Documentation (push) Failing after 6s
Documentation / Build User Guide (push) Successful in 7s
CI / Format Check (push) Failing after 13s
CI / Clippy Check (push) Failing after 37s
Performance Benchmarks / Run Benchmarks (push) Successful in 3m23s
CI / Build (macos-latest) (push) Waiting to run
CI / Test (macos-latest) (push) Blocked by required conditions
CI / Test (ubuntu-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (macos-latest) (push) Blocked by required conditions
CI / Python Bindings (maturin) (ubuntu-latest) (push) Blocked by required conditions
CI / WASM Build + Size Check (push) Blocked by required conditions
CI / Distributed Training Tests (push) Blocked by required conditions
CI / CI Success (push) Blocked by required conditions
CI / Build CPU-Only (Explicit) (push) Failing after 6s
CI / Build (ubuntu-latest) (push) Failing after 6s
Documentation / Build API Documentation (push) Failing after 6s
Documentation / Build User Guide (push) Successful in 7s
CI / Format Check (push) Failing after 13s
CI / Clippy Check (push) Failing after 37s
Performance Benchmarks / Run Benchmarks (push) Successful in 3m23s
This commit is contained in:
@@ -601,6 +601,23 @@ impl PoissonKernel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`Self::solve_2d`] under its older name.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn solve_jacobi_2d(
|
||||||
|
&self,
|
||||||
|
phi: &mut CudaSlice<f32>,
|
||||||
|
source: &CudaSlice<f32>,
|
||||||
|
nx: usize,
|
||||||
|
ny: usize,
|
||||||
|
dx: f32,
|
||||||
|
dy: f32,
|
||||||
|
max_iterations: usize,
|
||||||
|
tolerance: f32,
|
||||||
|
) -> CfdResult<usize> {
|
||||||
|
self.solve_2d(phi, source, nx, ny, dx, dy, max_iterations, tolerance)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn solve_2d(
|
pub fn solve_2d(
|
||||||
&self,
|
&self,
|
||||||
phi: &mut CudaSlice<f32>,
|
phi: &mut CudaSlice<f32>,
|
||||||
@@ -757,6 +774,39 @@ impl MatrixOpsKernel {
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `y = T x` for the tridiagonal matrix with `diagonal` (n) and
|
||||||
|
/// `off_diagonal` (n − 1) — the `tridiagonal_matvec` kernel.
|
||||||
|
pub fn tridiagonal_matvec(
|
||||||
|
&self,
|
||||||
|
diagonal: &CudaSlice<f32>,
|
||||||
|
off_diagonal: &CudaSlice<f32>,
|
||||||
|
x: &CudaSlice<f32>,
|
||||||
|
y: &mut CudaSlice<f32>,
|
||||||
|
) -> CfdResult<()> {
|
||||||
|
let n = x.len();
|
||||||
|
let func = self
|
||||||
|
.module
|
||||||
|
.load_function("tridiagonal_matvec")
|
||||||
|
.map_err(|e| CfdError::gpu_error(&format!("Failed to get kernel: {}", e)))?;
|
||||||
|
let config = LaunchConfig {
|
||||||
|
grid_dim: ((n as u32 + 255) / 256, 1, 1),
|
||||||
|
block_dim: (256, 1, 1),
|
||||||
|
shared_mem_bytes: 0,
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
self.stream
|
||||||
|
.launch_builder(&func)
|
||||||
|
.arg(diagonal)
|
||||||
|
.arg(off_diagonal)
|
||||||
|
.arg(x)
|
||||||
|
.arg(y)
|
||||||
|
.arg(&(n as i32))
|
||||||
|
.launch(config)
|
||||||
|
.map_err(|e| CfdError::gpu_error(&format!("Kernel launch failed: {}", e)))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Compute L2 norm of vector
|
/// Compute L2 norm of vector
|
||||||
pub fn vector_norm(&self, x: &CudaSlice<f32>) -> CfdResult<f32> {
|
pub fn vector_norm(&self, x: &CudaSlice<f32>) -> CfdResult<f32> {
|
||||||
let n = x.len();
|
let n = x.len();
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
viscosity: 0.01,
|
viscosity: 0.01,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
device_id: 0,
|
device_id: 0,
|
||||||
|
..CfdConfig::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Verify manager is created successfully
|
// Verify manager is created successfully
|
||||||
// Context and stream should be valid (non-null references)
|
// Context and stream should be valid (non-null references)
|
||||||
@@ -49,7 +50,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test that required modules are loaded
|
// Test that required modules are loaded
|
||||||
// Getting a module should succeed and return a valid Arc reference
|
// Getting a module should succeed and return a valid Arc reference
|
||||||
@@ -72,7 +73,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test that non-existent module returns error
|
// Test that non-existent module returns error
|
||||||
let result = manager.get_module("nonexistent_module");
|
let result = manager.get_module("nonexistent_module");
|
||||||
@@ -92,7 +93,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test allocating GPU memory
|
// Test allocating GPU memory
|
||||||
let size = 1024;
|
let size = 1024;
|
||||||
@@ -110,7 +111,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test copying data to GPU
|
// Test copying data to GPU
|
||||||
let host_data: Vec<f32> = (0..100).map(|i| i as f32).collect();
|
let host_data: Vec<f32> = (0..100).map(|i| i as f32).collect();
|
||||||
@@ -128,7 +129,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test round-trip copy: host -> device -> host
|
// Test round-trip copy: host -> device -> host
|
||||||
let original_data: Vec<f32> = (0..100).map(|i| i as f32 * 0.1).collect();
|
let original_data: Vec<f32> = (0..100).map(|i| i as f32 * 0.1).collect();
|
||||||
@@ -159,7 +160,7 @@ mod cuda_kernel_manager_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test that synchronization doesn't error
|
// Test that synchronization doesn't error
|
||||||
manager.synchronize()?;
|
manager.synchronize()?;
|
||||||
|
|||||||
@@ -37,9 +37,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.001,
|
dt: 0.001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test all advection schemes
|
// Test all advection schemes
|
||||||
let schemes = vec![
|
let schemes = vec![
|
||||||
@@ -117,9 +118,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.001,
|
dt: 0.001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
||||||
|
|
||||||
let nx = 64;
|
let nx = 64;
|
||||||
@@ -202,9 +204,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.0001,
|
dt: 0.0001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test all diffusion schemes
|
// Test all diffusion schemes
|
||||||
let schemes = vec![
|
let schemes = vec![
|
||||||
@@ -288,9 +291,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.0001,
|
dt: 0.0001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
||||||
|
|
||||||
let nx = 64;
|
let nx = 64;
|
||||||
@@ -366,9 +370,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.001,
|
dt: 0.001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = PoissonKernel::new(&manager)?;
|
let kernel = PoissonKernel::new(&manager)?;
|
||||||
|
|
||||||
let nx = 32;
|
let nx = 32;
|
||||||
@@ -443,9 +448,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.001,
|
dt: 0.001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test allocation and deallocation of large arrays
|
// Test allocation and deallocation of large arrays
|
||||||
let sizes = vec![1024, 65536, 262144];
|
let sizes = vec![1024, 65536, 262144];
|
||||||
@@ -491,9 +497,10 @@ mod gpu_kernel_tests {
|
|||||||
lz: 0.0,
|
lz: 0.0,
|
||||||
dt: 0.001,
|
dt: 0.001,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
||||||
|
|
||||||
let n = 512 * 512;
|
let n = 512 * 512;
|
||||||
|
|||||||
@@ -25,20 +25,21 @@ mod cuda_tests {
|
|||||||
viscosity: 0.01,
|
viscosity: 0.01,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
device_id: 0,
|
device_id: 0,
|
||||||
|
..CfdConfig::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cuda_kernel_manager_creation() -> CfdResult<()> {
|
fn test_cuda_kernel_manager_creation() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let _manager = CudaKernelManager::new(&config)?;
|
let _manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_memory_operations() -> CfdResult<()> {
|
fn test_memory_operations() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test allocation
|
// Test allocation
|
||||||
let size = 1000;
|
let size = 1000;
|
||||||
@@ -63,7 +64,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_advection_kernel_1d() -> CfdResult<()> {
|
fn test_advection_kernel_1d() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
||||||
|
|
||||||
let n = 100;
|
let n = 100;
|
||||||
@@ -99,7 +100,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_advection_kernel_2d() -> CfdResult<()> {
|
fn test_advection_kernel_2d() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
let kernel = AdvectionKernel::new(&manager, AdvectionScheme::Upwind)?;
|
||||||
|
|
||||||
let nx = 32;
|
let nx = 32;
|
||||||
@@ -147,7 +148,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_diffusion_kernel_explicit() -> CfdResult<()> {
|
fn test_diffusion_kernel_explicit() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
||||||
|
|
||||||
let n = 100;
|
let n = 100;
|
||||||
@@ -182,7 +183,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_diffusion_kernel_2d() -> CfdResult<()> {
|
fn test_diffusion_kernel_2d() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
let kernel = DiffusionKernel::new(&manager, DiffusionScheme::Explicit)?;
|
||||||
|
|
||||||
let nx = 32;
|
let nx = 32;
|
||||||
@@ -225,7 +226,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_poisson_kernel_jacobi() -> CfdResult<()> {
|
fn test_poisson_kernel_jacobi() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = PoissonKernel::new(&manager)?;
|
let kernel = PoissonKernel::new(&manager)?;
|
||||||
|
|
||||||
let nx = 32;
|
let nx = 32;
|
||||||
@@ -267,7 +268,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_matrix_ops_tridiagonal() -> CfdResult<()> {
|
fn test_matrix_ops_tridiagonal() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = MatrixOpsKernel::new(&manager)?;
|
let kernel = MatrixOpsKernel::new(&manager)?;
|
||||||
|
|
||||||
let n = 100;
|
let n = 100;
|
||||||
@@ -303,7 +304,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_matrix_ops_dot_product() -> CfdResult<()> {
|
fn test_matrix_ops_dot_product() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = MatrixOpsKernel::new(&manager)?;
|
let kernel = MatrixOpsKernel::new(&manager)?;
|
||||||
|
|
||||||
let n = 1000;
|
let n = 1000;
|
||||||
@@ -325,7 +326,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_matrix_ops_vector_norm() -> CfdResult<()> {
|
fn test_matrix_ops_vector_norm() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = MatrixOpsKernel::new(&manager)?;
|
let kernel = MatrixOpsKernel::new(&manager)?;
|
||||||
|
|
||||||
let n = 100;
|
let n = 100;
|
||||||
@@ -345,7 +346,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_matrix_ops_axpy() -> CfdResult<()> {
|
fn test_matrix_ops_axpy() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let kernel = MatrixOpsKernel::new(&manager)?;
|
let kernel = MatrixOpsKernel::new(&manager)?;
|
||||||
|
|
||||||
let n = 100;
|
let n = 100;
|
||||||
@@ -372,7 +373,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_performance_comparison() -> CfdResult<()> {
|
fn test_performance_comparison() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
let n = 10000;
|
let n = 10000;
|
||||||
let host_data: Vec<f32> = (0..n).map(|i| i as f32 * 0.1).collect();
|
let host_data: Vec<f32> = (0..n).map(|i| i as f32 * 0.1).collect();
|
||||||
@@ -394,7 +395,7 @@ mod cuda_tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_kernel_error_handling() -> CfdResult<()> {
|
fn test_kernel_error_handling() -> CfdResult<()> {
|
||||||
let config = create_test_config();
|
let config = create_test_config();
|
||||||
let manager = CudaKernelManager::new(&config)?;
|
let manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
|
|
||||||
// Test with mismatched array sizes (should not crash)
|
// Test with mismatched array sizes (should not crash)
|
||||||
let small_array = manager.allocate_f32(10)?;
|
let small_array = manager.allocate_f32(10)?;
|
||||||
@@ -434,6 +435,7 @@ mod cpu_fallback_tests {
|
|||||||
reference_length: 1.0,
|
reference_length: 1.0,
|
||||||
reference_velocity: 1.0,
|
reference_velocity: 1.0,
|
||||||
use_gpu: true,
|
use_gpu: true,
|
||||||
|
..CfdConfig::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let result = CudaKernelManager::new(&config);
|
let result = CudaKernelManager::new(&config);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ mod gpu_reduction_tests {
|
|||||||
viscosity: 0.01,
|
viscosity: 0.01,
|
||||||
density: 1.0,
|
density: 1.0,
|
||||||
device_id: 0,
|
device_id: 0,
|
||||||
|
..CfdConfig::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ mod cuda_tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_advection_kernel_upwind() -> CfdResult<()> {
|
async fn test_advection_kernel_upwind() -> CfdResult<()> {
|
||||||
let config = CfdConfig::new().with_gpu(true);
|
let config = CfdConfig::new().with_gpu(true);
|
||||||
let kernel_manager = CudaKernelManager::new(&config)?;
|
let kernel_manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let advection_kernel = AdvectionKernel::new(&kernel_manager, AdvectionScheme::Upwind)?;
|
let advection_kernel = AdvectionKernel::new(&kernel_manager, AdvectionScheme::Upwind)?;
|
||||||
|
|
||||||
// Test data: 1D advection with known analytical solution
|
// Test data: 1D advection with known analytical solution
|
||||||
@@ -43,14 +43,14 @@ mod cuda_tests {
|
|||||||
let d_phi_new = kernel_manager.allocate_f32(nx)?;
|
let d_phi_new = kernel_manager.allocate_f32(nx)?;
|
||||||
|
|
||||||
// Copy to GPU
|
// Copy to GPU
|
||||||
kernel_manager.copy_to_device(&phi, &mut d_phi)?;
|
d_phi = kernel_manager.copy_to_device(&phi)?;
|
||||||
|
|
||||||
// Run advection kernel
|
// Run advection kernel
|
||||||
advection_kernel.apply(&d_phi, &d_phi_new, velocity as f32, dt as f32, dx as f32)?;
|
advection_kernel.apply(&d_phi, &d_phi_new, velocity as f32, dt as f32, dx as f32)?;
|
||||||
|
|
||||||
// Copy result back
|
// Copy result back
|
||||||
let mut result = vec![0.0f32; nx];
|
let mut result = vec![0.0f32; nx];
|
||||||
kernel_manager.copy_from_device(&d_phi_new, &mut result)?;
|
result = kernel_manager.copy_from_device(&d_phi_new)?;
|
||||||
|
|
||||||
// Verify that the pulse has moved (mass conservation)
|
// Verify that the pulse has moved (mass conservation)
|
||||||
let initial_mass: f32 = phi.iter().sum();
|
let initial_mass: f32 = phi.iter().sum();
|
||||||
@@ -82,7 +82,7 @@ mod cuda_tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_advection_kernel_central() -> CfdResult<()> {
|
async fn test_advection_kernel_central() -> CfdResult<()> {
|
||||||
let config = CfdConfig::new().with_gpu(true);
|
let config = CfdConfig::new().with_gpu(true);
|
||||||
let kernel_manager = CudaKernelManager::new(&config)?;
|
let kernel_manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let advection_kernel = AdvectionKernel::new(&kernel_manager, AdvectionScheme::Central)?;
|
let advection_kernel = AdvectionKernel::new(&kernel_manager, AdvectionScheme::Central)?;
|
||||||
|
|
||||||
// Test data: smooth sinusoidal wave
|
// Test data: smooth sinusoidal wave
|
||||||
@@ -100,11 +100,11 @@ mod cuda_tests {
|
|||||||
let mut d_phi = kernel_manager.allocate_f32(nx)?;
|
let mut d_phi = kernel_manager.allocate_f32(nx)?;
|
||||||
let d_phi_new = kernel_manager.allocate_f32(nx)?;
|
let d_phi_new = kernel_manager.allocate_f32(nx)?;
|
||||||
|
|
||||||
kernel_manager.copy_to_device(&phi, &mut d_phi)?;
|
d_phi = kernel_manager.copy_to_device(&phi)?;
|
||||||
advection_kernel.apply(&d_phi, &d_phi_new, velocity as f32, dt as f32, dx as f32)?;
|
advection_kernel.apply(&d_phi, &d_phi_new, velocity as f32, dt as f32, dx as f32)?;
|
||||||
|
|
||||||
let mut result = vec![0.0f32; nx];
|
let mut result = vec![0.0f32; nx];
|
||||||
kernel_manager.copy_from_device(&d_phi_new, &mut result)?;
|
result = kernel_manager.copy_from_device(&d_phi_new)?;
|
||||||
|
|
||||||
// For central scheme, verify mass conservation and smoothness
|
// For central scheme, verify mass conservation and smoothness
|
||||||
let initial_mass: f32 = phi.iter().sum();
|
let initial_mass: f32 = phi.iter().sum();
|
||||||
@@ -117,7 +117,7 @@ mod cuda_tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_diffusion_kernel_explicit() -> CfdResult<()> {
|
async fn test_diffusion_kernel_explicit() -> CfdResult<()> {
|
||||||
let config = CfdConfig::new().with_gpu(true);
|
let config = CfdConfig::new().with_gpu(true);
|
||||||
let kernel_manager = CudaKernelManager::new(&config)?;
|
let kernel_manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let diffusion_kernel = DiffusionKernel::new(&kernel_manager, DiffusionScheme::Explicit)?;
|
let diffusion_kernel = DiffusionKernel::new(&kernel_manager, DiffusionScheme::Explicit)?;
|
||||||
|
|
||||||
// Test 1D heat equation with analytical solution
|
// Test 1D heat equation with analytical solution
|
||||||
@@ -135,11 +135,11 @@ mod cuda_tests {
|
|||||||
let mut d_temp = kernel_manager.allocate_f32(nx)?;
|
let mut d_temp = kernel_manager.allocate_f32(nx)?;
|
||||||
let d_temp_new = kernel_manager.allocate_f32(nx)?;
|
let d_temp_new = kernel_manager.allocate_f32(nx)?;
|
||||||
|
|
||||||
kernel_manager.copy_to_device(&temperature, &mut d_temp)?;
|
d_temp = kernel_manager.copy_to_device(&temperature)?;
|
||||||
diffusion_kernel.apply(&d_temp, &d_temp_new, alpha as f32, dt as f32, dx as f32)?;
|
diffusion_kernel.apply(&d_temp, &d_temp_new, alpha as f32, dt as f32, dx as f32)?;
|
||||||
|
|
||||||
let mut result = vec![0.0f32; nx];
|
let mut result = vec![0.0f32; nx];
|
||||||
kernel_manager.copy_from_device(&d_temp_new, &mut result)?;
|
result = kernel_manager.copy_from_device(&d_temp_new)?;
|
||||||
|
|
||||||
// Verify diffusion: edges should be smoother, total heat conserved
|
// Verify diffusion: edges should be smoother, total heat conserved
|
||||||
let initial_total: f32 = temperature.iter().sum();
|
let initial_total: f32 = temperature.iter().sum();
|
||||||
@@ -160,7 +160,7 @@ mod cuda_tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_poisson_kernel_2d() -> CfdResult<()> {
|
async fn test_poisson_kernel_2d() -> CfdResult<()> {
|
||||||
let config = CfdConfig::new().with_gpu(true);
|
let config = CfdConfig::new().with_gpu(true);
|
||||||
let kernel_manager = CudaKernelManager::new(&config)?;
|
let kernel_manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let poisson_kernel = PoissonKernel::new(&kernel_manager)?;
|
let poisson_kernel = PoissonKernel::new(&kernel_manager)?;
|
||||||
|
|
||||||
// Test 2D Poisson equation: ∇²φ = f
|
// Test 2D Poisson equation: ∇²φ = f
|
||||||
@@ -190,8 +190,8 @@ mod cuda_tests {
|
|||||||
let mut d_phi = kernel_manager.allocate_f32(nx * ny)?;
|
let mut d_phi = kernel_manager.allocate_f32(nx * ny)?;
|
||||||
let mut d_source = kernel_manager.allocate_f32(nx * ny)?;
|
let mut d_source = kernel_manager.allocate_f32(nx * ny)?;
|
||||||
|
|
||||||
kernel_manager.copy_to_device(&phi, &mut d_phi)?;
|
d_phi = kernel_manager.copy_to_device(&phi)?;
|
||||||
kernel_manager.copy_to_device(&source, &mut d_source)?;
|
d_source = kernel_manager.copy_to_device(&source)?;
|
||||||
|
|
||||||
// Solve Poisson equation
|
// Solve Poisson equation
|
||||||
let max_iterations = 1000;
|
let max_iterations = 1000;
|
||||||
@@ -208,7 +208,7 @@ mod cuda_tests {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut result = vec![0.0f32; nx * ny];
|
let mut result = vec![0.0f32; nx * ny];
|
||||||
kernel_manager.copy_from_device(&d_phi, &mut result)?;
|
result = kernel_manager.copy_from_device(&d_phi)?;
|
||||||
|
|
||||||
// Verify against analytical solution
|
// Verify against analytical solution
|
||||||
let mut max_error = 0.0f32;
|
let mut max_error = 0.0f32;
|
||||||
@@ -233,7 +233,7 @@ mod cuda_tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_matrix_ops_kernel() -> CfdResult<()> {
|
async fn test_matrix_ops_kernel() -> CfdResult<()> {
|
||||||
let config = CfdConfig::new().with_gpu(true);
|
let config = CfdConfig::new().with_gpu(true);
|
||||||
let kernel_manager = CudaKernelManager::new(&config)?;
|
let kernel_manager = std::sync::Arc::new(CudaKernelManager::new(&config)?);
|
||||||
let matrix_ops = MatrixOpsKernel::new(&kernel_manager)?;
|
let matrix_ops = MatrixOpsKernel::new(&kernel_manager)?;
|
||||||
|
|
||||||
// Test sparse matrix-vector multiplication (typical in CFD)
|
// Test sparse matrix-vector multiplication (typical in CFD)
|
||||||
@@ -246,17 +246,17 @@ mod cuda_tests {
|
|||||||
let mut d_diag = kernel_manager.allocate_f32(n)?;
|
let mut d_diag = kernel_manager.allocate_f32(n)?;
|
||||||
let mut d_off_diag = kernel_manager.allocate_f32(n - 1)?;
|
let mut d_off_diag = kernel_manager.allocate_f32(n - 1)?;
|
||||||
let mut d_x = kernel_manager.allocate_f32(n)?;
|
let mut d_x = kernel_manager.allocate_f32(n)?;
|
||||||
let d_y = kernel_manager.allocate_f32(n)?;
|
let mut d_y = kernel_manager.allocate_f32(n)?;
|
||||||
|
|
||||||
kernel_manager.copy_to_device(&diagonal, &mut d_diag)?;
|
d_diag = kernel_manager.copy_to_device(&diagonal)?;
|
||||||
kernel_manager.copy_to_device(&off_diagonal, &mut d_off_diag)?;
|
d_off_diag = kernel_manager.copy_to_device(&off_diagonal)?;
|
||||||
kernel_manager.copy_to_device(&x, &mut d_x)?;
|
d_x = kernel_manager.copy_to_device(&x)?;
|
||||||
|
|
||||||
// Perform A*x = y operation
|
// Perform A*x = y operation
|
||||||
matrix_ops.tridiagonal_matvec(&d_diag, &d_off_diag, &d_x, &d_y, n)?;
|
matrix_ops.tridiagonal_matvec(&d_diag, &d_off_diag, &d_x, &mut d_y)?;
|
||||||
|
|
||||||
let mut result = vec![0.0f32; n];
|
let mut result = vec![0.0f32; n];
|
||||||
kernel_manager.copy_from_device(&d_y, &mut result)?;
|
result = kernel_manager.copy_from_device(&d_y)?;
|
||||||
|
|
||||||
// Verify result manually for first few elements
|
// Verify result manually for first few elements
|
||||||
assert_relative_eq!(result[0], 2.0 * x[0] - x[1], epsilon = 1e-6);
|
assert_relative_eq!(result[0], 2.0 * x[0] - x[1], epsilon = 1e-6);
|
||||||
@@ -287,7 +287,7 @@ async fn test_kernel_manager_initialization() -> CfdResult<()> {
|
|||||||
#[cfg(feature = "cuda")]
|
#[cfg(feature = "cuda")]
|
||||||
{
|
{
|
||||||
// Should successfully create kernel manager
|
// Should successfully create kernel manager
|
||||||
let result = rtx_cfd::kernels::CudaKernelManager::new(&config);
|
let mut result = rtx_cfd::kernels::CudaKernelManager::new(&config);
|
||||||
// May fail if no CUDA device available - that's expected in CI
|
// May fail if no CUDA device available - that's expected in CI
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => println!("CUDA kernel manager created successfully"),
|
Ok(_) => println!("CUDA kernel manager created successfully"),
|
||||||
|
|||||||
Reference in New Issue
Block a user