weld 0.4.0

Weld is a language and runtime for improving the performance of data-intensive applications.
weld-0.4.0 doesn't have any documentation.
Weld is a runtime for improving the performance of data-intensive applications. It optimizes across libraries and functions by expressing the core computations in libraries using a small common intermediate representation, similar to CUDA and OpenCL. # Using Weld Weld is a small programming language that supports _parallel loops_ and _builders_, which are declarative objects that specify how to build results. The parallel loops can be used in conjunction with the builders to build a result in parallel. This crate contains the Weld compiler and runtime, though users only interact with the compiler. Users use Weld by constructing a Weld program (currently as a string), compiling the string into a runnable _module_, and then running the module with in-memory data. Weld JITs code into the current process using LLVM. As a result, Weld users must have a version of LLVM installed on their machine (currently, Weld uses LLVM 6). ## Example The following program shows a minimal Weld program that adds two numbers: ```rust,no_run # extern crate weld; # # use weld::*; # #[repr(C)] struct MyArgs { a: i32, b: i32, } let code = "|a: i32, b: i32| a + b"; let conf = &WeldConf::new(); let mut module = WeldModule::compile(code, conf).unwrap(); // Weld accepts a packed C struct as an argument. let args = &MyArgs { a: 1, b: 50 }; let input = &WeldValue::new_from_data(args as *const _ as Data); // A context manages memory. let context = &mut WeldContext::new(conf).unwrap(); // Running a Weld module and reading a value out of it is unsafe! unsafe { // Run the module, which returns a wrapper `WeldValue`. let result = module.run(context, input).unwrap(); // The data is just a pointer: cast it to the expected type let data = result.data() as *const i32; let result = (*data).clone(); assert_eq!(args.a + args.b, result); } ``` Users write a Weld program as a string, compile it into a module, and then pass packed arguments into it to run the JITed code. The result is a pointer that represents the output of the Weld program: we can cast that to the appropriate pointer type and read it by dereferencing. ## Modules The `WeldModule` is the main entry point into Weld. Users can compile Weld programs using `WeldModule::compile`, and then run compiled programs using `WeldModule::run`. The module functions can be configured in several ways. This configuration is controlled using the `WeldConf` struct, which is effectively a dictionary of `String` key/value pairs that control how a Weld program is compiled and run. ## Values Since Weld JITs code and implements a custom runtime, data passed in and out of it must be in a specific, C-compatible packed format. The [Weld Github](http://github.com/weld-project/weld) contains a plethora of information on how data should be formatted when passed into Weld, but in short, it is **not** safe to simply pass Rust objects into Weld. `WeldModule` accepts and returns a wrapper struct called `WeldValue`, which wraps an opaque `*const void` that Weld reads depending on the argument and return types of the Weld program. Weld's main `run` function is thus `unsafe`: users need to guarantee that the data passed into Weld is properly formatted! ### Passing Rust Values into Weld Currently, users need to manually munge Rust values into a format that Weld understands, as specified [here](https://github.com/weld-project/weld/blob/master/docs/api.md). Eventually, we may add a module in this crate that contains wrappers for some useful types. The current Rust types can be passed safely into Weld already: * Primitive types such as `i8`, `i16`, and `f32`. These have a 1-1 correspondance with Weld. * Rust structs with `repr(C)`. Notably, `Vec` _cannot_ be passed without adhering to the custom Weld format. Currently, that format is defined as: ``` #[repr(C)] struct WeldVec { ptr: *const T, len: i64, } ``` There is thus a straightforward conversion from `Vec` to a `WeldVec`. The `data` module defines layouts of Weld-compatible types, and also contains some methods for converting Rust values into Weld values. ## Contexts A context manages state such as allocation information. A context is passed into `WeldModule::run` and updated by the compiled Weld program. The `WeldContext` struct wraps a context. Contexts are internally reference counted because values produced by Weld hold references to the context in which they are allocated. The memory backing a `WeldContext` is freed when all references to the context are dropped.