use crate::hip::{self, Device, DeviceMemory, Stream};
use crate::rocfft::{
self,
description::PlanDescription,
plan::{ArrayType, PlacementType, Plan, Precision, TransformType},
};
pub fn run_1d_complex_example() -> Result<(), Box<dyn std::error::Error>> {
let length = 1024;
let lengths = vec![length];
let mut plan = Plan::new(
PlacementType::InPlace,
TransformType::ComplexForward,
Precision::Single,
1,
&lengths,
1,
None,
)?;
let complex_length = length * 2;
let mut input_data = vec![0.0f32; complex_length];
println!("Initializing sine wave...");
for i in 0..length {
let x = i as f32 / length as f32;
input_data[i * 2] = f32::sin(2.0 * std::f32::consts::PI * 10.0 * x);
input_data[i * 2 + 1] = 0.0; }
println!("Input data samples:");
for i in 0..5 {
println!(
" Element {}: Real={:.4}, Imag={:.4}",
i,
input_data[i * 2],
input_data[i * 2 + 1]
);
}
let mut d_input = DeviceMemory::<f32>::new(complex_length)?;
d_input.copy_from_host(&input_data)?;
let input_ptr = [d_input.as_ptr()];
plan.execute(&input_ptr, &[], None)?;
let mut output_data = vec![0.0f32; complex_length];
d_input.copy_to_host(&mut output_data)?;
println!("FFT Results:");
let mut found_nonzero = false;
for i in 0..15 {
let real = output_data[i * 2];
let imag = output_data[i * 2 + 1];
let magnitude = (real * real + imag * imag).sqrt();
println!("Freq {}: Magnitude = {:.4}", i, magnitude);
if magnitude > 0.1 {
found_nonzero = true;
}
}
if !found_nonzero {
println!("WARNING: No significant magnitudes found. This may indicate a problem.");
println!("Checking bin 10 where we expect a peak:");
let i = 10;
let real = output_data[i * 2];
let imag = output_data[i * 2 + 1];
let magnitude = (real * real + imag * imag).sqrt();
println!("Freq {}: Magnitude = {:.4}", i, magnitude);
}
Ok(())
}
pub fn run_1d_real_example() -> Result<(), Box<dyn std::error::Error>> {
let length = 1024;
let lengths = vec![length];
let complex_length = (length / 2 + 1) * 2;
let mut forward_plan = Plan::new(
PlacementType::NotInPlace,
TransformType::RealForward,
Precision::Single,
1,
&lengths,
1,
None,
)?;
let mut description = PlanDescription::new()?;
description.set_scale_factor(1.0 / length as f64)?;
let mut inverse_plan = Plan::new(
PlacementType::NotInPlace,
TransformType::RealInverse,
Precision::Single,
1,
&lengths,
1,
Some(&description),
)?;
let mut input_data = vec![0.0f32; length];
for i in 0..length {
let x = i as f32 / length as f32;
input_data[i] = f32::sin(2.0 * std::f32::consts::PI * 10.0 * x)
+ 0.5 * f32::sin(2.0 * std::f32::consts::PI * 25.0 * x);
}
let mut d_input = DeviceMemory::<f32>::new(length)?;
let mut d_output = DeviceMemory::<f32>::new(complex_length)?;
let mut d_reconstructed = DeviceMemory::<f32>::new(length)?;
d_input.copy_from_host(&input_data)?;
let input_ptr = [d_input.as_ptr()];
let output_ptr = [d_output.as_ptr()];
forward_plan.execute(&input_ptr, &output_ptr, None)?;
let mut output_data = vec![0.0f32; complex_length];
d_output.copy_to_host(&mut output_data)?;
println!("Real FFT Results (first 5 frequencies):");
for i in 0..5 {
let mag = (output_data[i * 2].powi(2) + output_data[i * 2 + 1].powi(2)).sqrt();
println!("Freq {}: Magnitude = {:.4}", i, mag);
}
let cutoff = (length / 2 + 1) / 5;
for i in cutoff..(length / 2 + 1) {
output_data[i * 2] = 0.0; output_data[i * 2 + 1] = 0.0; }
d_output.copy_from_host(&output_data)?;
let inverse_input_ptr = [d_output.as_ptr()];
let inverse_output_ptr = [d_reconstructed.as_ptr()];
inverse_plan.execute(&inverse_input_ptr, &inverse_output_ptr, None)?;
let mut reconstructed_data = vec![0.0f32; length];
d_reconstructed.copy_to_host(&mut reconstructed_data)?;
let mut error_sum = 0.0;
for i in 0..length {
error_sum += (input_data[i] - reconstructed_data[i]).abs();
}
let avg_error = error_sum / length as f32;
println!("Average error after low-pass filtering: {:.4e}", avg_error);
Ok(())
}