Safer (and Easier) Rust Interface
The current Rust interface has a major problem because it requires changes to the Rust code when device assignments are changed. This makes it harder to experiment with schedules (which is the whole point of schedules) and would especially be an issue when trying to automatically assign devices since the user's Rust code must be aware of the decisions by the compiler. This issue is also supported by the large amount of code that must currently be wrapped in #[cfg(feature = "cuda")]
or #[cfg(not(feature = "cuda"))]
to get our CI to be able to test both CPU and GPU.
The interface is also quite unsafe, in particular to retrieve memory from the GPU involves unsafe code and the user computing the size of the returned memory (despite Hercules knowing it). Also, even for CPU memory when we retrieve the memory as a slice, the user specifies the type of the elements (which again Hercules knows).
I would suggest a few changes:
- Memory being passed to Hercules programs should either always be wrapped in the same manner (like the original
HerculesBox
idea) or should be able to be coerced in the same manner from the appropriate Rust type into the appropriate Hercules type (for example by implementingFrom<&[T]>
for all Ref types, so that we could just use.into()
regardless of target device). - Memory returned from Hercules programs should all satisfy a standard interface, in particular a method to retrieve the results as a slice (or a boxed slice).
- The types we use for (1) and (2) should be type/memory-safe. In particular, we should not have to compute the size of any memory (like we're doing for GPU now) nor should we have to specify the type (like the
as_slice
method forHerculesCPURef
does).
I agree we need some representation of memory that is under Hercule's management; this is something HPVM does not handle well and is really important to allow the reuse of memory across executions, but the device specific approach we currently have is really not ideal.