futuresdr 0.0.41

An Experimental Async SDR Runtime for Heterogeneous Architectures.
Documentation
use anyhow::Result;
use futuresdr::blocks::VectorSink;
use futuresdr::blocks::VectorSource;
use futuresdr::blocks::Vulkan;
use futuresdr::prelude::*;
use futuresdr::runtime::buffer::vulkan::D2HReader;
use futuresdr::runtime::buffer::vulkan::H2DWriter;
use futuresdr::runtime::buffer::vulkan::Instance;
use std::iter::repeat_with;
use std::panic;

mod cs {
    vulkano_shaders::shader! {
        ty: "compute",
        src: "
#version 450

layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;

layout(set = 0, binding = 0) buffer Data {
    float data[];
} buf;

void main() {
    uint idx = gl_GlobalInvocationID.x;
    buf.data[idx] *= 12.0;
}"
    }
}

#[test]
fn fg_vulkan() -> Result<()> {
    let mut fg = Flowgraph::new();

    let n_items = 10_000;
    let orig: Vec<f32> = repeat_with(rand::random::<f32>).take(n_items).collect();

    let instance = match panic::catch_unwind(Instance::new) {
        Ok(instance) => instance,
        Err(_) => {
            eprintln!("Skipping Vulkan test: failed to initialize Vulkan instance");
            return Ok(());
        }
    };
    let entry_point = match cs::load(instance.device())
        .ok()
        .and_then(|shader| shader.entry_point("main"))
    {
        Some(entry_point) => entry_point,
        None => {
            eprintln!("Skipping Vulkan test: failed to load Vulkan shader entry point");
            return Ok(());
        }
    };

    let mut src = VectorSource::<f32, H2DWriter<f32>>::new(orig.clone());
    let vulkan = Vulkan::new(instance.clone(), entry_point, 32);
    let snk = VectorSink::<f32, D2HReader<f32>>::new(n_items);

    for _ in 0..4 {
        let buffer = instance.create_buffer(1024 * 1024 * 8)?;
        src.output().add_buffer(buffer);
    }

    connect!(fg, src > vulkan > snk);
    connect!(fg, src < snk);

    let fg = Runtime::new().run(fg)?;

    let snk = fg.block(&snk)?;
    let v = snk.items();

    assert_eq!(v.len(), n_items);
    for i in 0..v.len() {
        assert!((orig[i] * 12.0 - v[i]).abs() < f32::EPSILON);
    }

    Ok(())
}