pnnl / lamellar-runtime

Lamellar is an asynchronous tasking runtime for HPC systems developed in RUST
Other
43 stars 5 forks source link

Derive macro for 'Dist' in simple enums and structs #4

Closed JosephCottam closed 2 years ago

JosephCottam commented 2 years ago

It would be nice to make a distributed array of structs. It seems reasonable to support #[derive(Dist)] if a struct or enum is made entirely of things that already implement Dist. (I say 'reasonable' having never made a macro in rust, so feel free to tell me this is not a reasonable request.)

Desired uses:

use lamellar::array::{Distribution, UnsafeArray};
use lamellar::{Dist, LamellarWorld};

// An enum with no associated values
enum Colors {
   Red,   White,   Blue,   Green,   Black,   Pink
}

// A struct with some fields that are already Dist
#[derive(Dist)]
struct Size {
    length: usize,
    width: usize,
    height: usize
}

// An enum like Option (some entries have values, some do not)
#[derive(Dist)]
enum Message {
    Letter,
    Package(Size)
}

struct ArrayWrapper<T> {
    array: UnsafeArray<T>,
}

impl<T: Dist> ArrayWrapper<T> {
    fn new(world: LamellarWorld, len: usize) -> Self {
        ArrayWrapper {
            array: UnsafeArray::<T>::new(world, len, Distribution::Block),
        }
    }
}

fn main() {
    let world = lamellar::LamellarWorldBuilder::new().build();
    let _my_pe = world.my_pe();
    let num_pes = world.num_pes();
    let colors = ArrayWrapper::<Colors>::new(world.clone(), 10*num_pes);
    let sizes = ArrayWrapper::<Size>::new(world.clone(), 10*num_pes);
    let messages = ArrayWrapper::<Message>::new(world.clone(), 10*num_pes);
    colors.array.print();
    sizes.array.print();
    messages.array.print();
}

The use immediate use-case is to provide a mailbox-style array for doing some inter-process communication, but it would make a nice general capability.

rdfriese commented 2 years ago

for a short term fix, assuming all the inner members are Sync+Send you probably just need to derive Copy (and thus I think the compiler will also make you derive Clone). I'm actually half tempted to change the user facing api to split dist into its underlying bounds so that the compiler message is more explicit about what bound isn't being met.

For a long term fix, the macro should be easy to do, in fact I'm in the process of doing something similar (although a fair bit more complicated) to support operations like add, sub, mul, div, etc. I hope to push this up this week sometime.

JosephCottam commented 2 years ago

I will try the derive-copy+clone technique. For completeness, I made a branch (issue-4-derive-dist-macro) with the example above in it.