diff --git a/Cargo.lock b/Cargo.lock index 8db6692..66ddb13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -216,6 +216,7 @@ dependencies = [ "cust_derive", "cust_raw", "find_cuda_helper", + "vek", ] [[package]] @@ -412,6 +413,7 @@ version = "0.1.0" dependencies = [ "cuda_builder", "cust", + "gpu", "image", ] diff --git a/Cargo.toml b/Cargo.toml index 493ac80..9a5b69e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cust = "0.2.2" +cust = { version = "0.2.2", features = ["vek"] } image = "0.23.14" +gpu = { path = "./gpu" } [profile.dev] opt-level = 3 diff --git a/gpu.png b/gpu.png new file mode 100644 index 0000000..2a6acb4 Binary files /dev/null and b/gpu.png differ diff --git a/gpu/src/lib.rs b/gpu/src/lib.rs index 97daaf4..3f17497 100644 --- a/gpu/src/lib.rs +++ b/gpu/src/lib.rs @@ -47,6 +47,7 @@ pub unsafe fn mandelbrot( let idx = thread::index_2d(); + if idx.x >= width || idx.y >= height { return; } @@ -61,12 +62,12 @@ fn check_part_of_mandelbrot(cfg: Cfg, id: Vec2) -> u32 { let x_step_size = (cfg.end.real - cfg.start.real) / cfg.width as f64; let y_step_size = (cfg.end.imag - cfg.start.imag) / cfg.height as f64; - let x = x_step_size * id.x as f64; - let y = y_step_size * id.y as f64; + let x_offset = x_step_size * id.x as f64; + let y_offset = y_step_size * id.y as f64; let sample_pos = CNumber { - real: cfg.start.real + x, - imag: cfg.start.imag + y, + real: cfg.start.real + x_offset, + imag: cfg.start.imag + y_offset, }; check_mandelbrot(sample_pos, cfg.iterations, cfg.threshold) diff --git a/src/lib.rs b/src/lib.rs index e6b0644..2980fca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,18 +6,26 @@ use std::fmt::{Display, Formatter}; use std::time::{Duration, SystemTime}; use cust::prelude::*; +use cust::vek::Vec2; use gpu::{CNumber, Cfg}; use image::{ImageBuffer, ImageResult, Rgb, RgbImage}; static PTX: &str = include_str!("../target/gpu.ptx"); -pub fn run(config: Config) -> Result<(), Box> { - let start_time = SystemTime::now(); +pub fn run(_: Config) -> Result<(), Box> { + let cfg = Cfg { + start: CNumber::new(-3.0, 1.), + end: CNumber::new(1., -1.), + height: 500 * 10, + width: 1000 * 10, + iterations: 100000, + threshold: 100, + }; - let debug = config.debug; - let height = config.width * 2.0 / 3.0; - let amount = (height * config.width) as usize; + let amount = cfg.height as usize * cfg.width as usize; + + println!("{} points will be calculated", amount); let _ctx = cust::quick_init()?; @@ -29,22 +37,13 @@ pub fn run(config: Config) -> Result<(), Box> { let func = module.get_function("mandelbrot")?; - let (_, block_size) = func.suggested_launch_configuration(amount, 0.into())?; - - let grid_size = (amount as u32 + block_size - 1) / block_size; - - let cfg = Cfg { - start: CNumber::new(-0.5, 0.5), - end: CNumber::new(0.5, 0.5), - height: 500, - width: 500, - iterations: 1000, - threshold: 100, - }; + let threads = Vec2::new(16, 16); + let blocks = (Vec2::new(cfg.width, cfg.height) / threads) + 1; + let start_time = SystemTime::now(); unsafe { launch!( - func<<>>( + func<<>>( cfg.start.real, cfg.start.imag, cfg.end.real, @@ -62,23 +61,17 @@ pub fn run(config: Config) -> Result<(), Box> { out_buf.copy_to(&mut out)?; - create_image(&out, cfg, "gpu.png")?; - - // now do things with out println!("expected {}, got {} numbers!", amount, out.len()); - if debug { - println!("calculated in: {}", format_time(start_time.elapsed()?)); - } + create_image(&out, cfg, "gpu.png")?; + + println!("calculated in: {}", format_time(start_time.elapsed()?)); + println!("Total Time: {}", format_time(start_time.elapsed()?)); - if debug { - println!("Total Time: {}", format_time(start_time.elapsed()?)); - } Ok(()) } fn create_image(values: &[u32], cfg: Cfg, path: &str) -> ImageResult<()> { - let mut image: RgbImage = ImageBuffer::new(cfg.width, cfg.height); for y in 0..cfg.height {