1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//! The distrib module provides methods for executing the rendering in a //! distributed environment across multiple machines. The worker module provides //! the Worker which does the actual job of rendering a subregion of the image. //! The master module provides the Master which instructs the Workers what to render //! and collects their results to save out the final image. //! //! # Usage //! //! The worker process takes very few arguments, just a flag indicating it's a worker //! and optionally the number of threads to use with `-n`. //! //! ```text //! ./tray_rust --worker //! ``` //! //! The worker processes will listen on a hard-coded port for the master to send them instructions //! about what parts of the image they should render. This is `exec::distrib::worker::PORT` which //! you can change and re-compile if the default of 63234 conflicts with other applications. //! //! The master process can be run on the same machine as a worker since it doesn't take //! up too much CPU time. To run the master you'll pass it the scene file, a list of the //! worker hostnames or IP addresses and optionally an output path and start/end frame numbers. //! You can also run tray\_rust with the `-h` or `--help` flag to see a list of options. //! //! ```text //! ./tray_rust cornell_box.json --master worker1 worker2 192.168.32.129 //! ``` //! //! The master will send the workers the location of the scene file which is assumed to //! be on some shared filesystem or otherwise available at the same path on all the workers. //! //! # Running on GCE or EC2 //! //! You can run on any network of home machines but you can also run on virtual machines from //! Google or Amazon if you want to rent a mini cluster. On GCE or EC2 you'll want machines in the //! same region for faster communication and will then pass the local IPs of the workers to //! the master. For example on GCE you're given a virtual local network, you would use //! these IP addresses instead of the public IPs of the worker nodes. //! use bincode::serialized_size; pub use self::worker::Worker; pub use self::master::Master; pub mod worker; pub mod master; /// Stores instructions sent to a worker about which blocks it should be rendering, /// block size is assumed to be 8x8 #[derive(Debug, Clone, Serialize, Deserialize)] struct Instructions { /// Size header for binary I/O with bincode pub encoded_size: u64, /// Scene file for the worker to load pub scene: String, /// Frames to be rendered (inclusive) pub frames: (usize, usize), /// Block in the z-order queue of blocks this worker will /// start at pub block_start: usize, /// Number of blocks this worker will render pub block_count: usize, } impl Instructions { pub fn new(scene: &str, frames: (usize, usize), block_start: usize, block_count: usize) -> Instructions { let mut instr = Instructions { encoded_size: 0, scene: scene.to_owned(), frames: frames, block_start: block_start, block_count: block_count }; instr.encoded_size = serialized_size(&instr); instr } } /// Frame is used by the worker to send its results back to the master. Sends information /// about which frame is being sent, which blocks were rendered and the data for the blocks #[derive(Serialize, Deserialize)] struct Frame { /// Size header for binary I/O with bincode pub encoded_size: u64, /// Which frame the worker is sending its results for pub frame: usize, /// Block size of the blocks being sent pub block_size: (usize, usize), /// Starting locations of each block pub blocks: Vec<(usize, usize)>, /// Sample data for each block, RGBW_F32 (W = weight) pub pixels: Vec<f32>, } impl Frame { pub fn new(frame: usize, block_size: (usize, usize), blocks: Vec<(usize, usize)>, pixels: Vec<f32>) -> Frame { let mut frame = Frame { encoded_size: 0, frame: frame, block_size: block_size, blocks: blocks, pixels: pixels }; frame.encoded_size = serialized_size(&frame); frame } }