From 1650906f010574e8810c8b0b98334e22fac5894d Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Sun, 12 Jan 2020 03:47:14 +0100 Subject: Restructuring --- src/solvers/gpu/manager.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/solvers/gpu/manager.rs (limited to 'src/solvers/gpu/manager.rs') diff --git a/src/solvers/gpu/manager.rs b/src/solvers/gpu/manager.rs new file mode 100644 index 0000000..1dd6a4d --- /dev/null +++ b/src/solvers/gpu/manager.rs @@ -0,0 +1,104 @@ +use std::sync::mpsc::{Receiver, Sender, channel}; +use std::thread::JoinHandle; +use super::*; + +#[derive(Debug)] +struct RequestBuffer { + mask_buff: Vec, + pointer: usize, +} + +impl RequestBuffer { + pub fn new(size: usize) -> Self { + RequestBuffer { + mask_buff: vec![0; size], + pointer: 0, + } + } + pub fn read(&mut self, request: CheckRequest) -> Option<&[u64]> { + self.mask_buff[self.pointer] = request.bitmask; + self.pointer += 1; + if self.pointer == self.mask_buff.len() { + self.pointer = 0; + return Some(self.mask_buff.as_ref()); + } + None + } +} + +pub struct OclManager { + job_id: u64, + host_sender: Sender, + output_sender: Sender, + reciever: Receiver, + buffers: Vec, + output_handle: JoinHandle, + host_handle: JoinHandle, +} + +impl OclManager { + pub fn launch_sevice( + permutations: &[&[u32]], + permutations_mask: &[u64], + n: u32, + // Workgroup size, set to 0 for max + wg_size: u32, + ) -> (Sender, JoinHandle) { + let (h, w) = crate::solvers::wall_stats(n); + let src = include_str!("check.cl"); + let (output_sender, output_handle) = + super::output::Output::launch_sevice(permutations, permutations_mask, n, h, w); + let (host_sender, host_handle) = + super::host::Host::launch_sevice(permutations_mask, n, h, w, wg_size as usize, src); + + let (receiver, sender) = channel(); + + let mut buffers = Vec::with_capacity((n - h + 1) as usize); + for _ in 0..=(n - h) { + buffers.push(RequestBuffer::new(wg_size as usize)); + } + + let manager = Self { + 0, + host_sender, + output_sender, + receiver, + buffers, + output_handle, + host_handle, + } + (sender, + std::thread::Builder::new() + .name("GPU Manager Deamon".into()) + .spawn(move || { + manager.run(); + }) + .unwrap()) + + } + + fn run(mut self) { + loop { + match self.reciever.recv().expect("Channel to GPU Manager broke") { + Message::CheckRequest(request) => { + if let Some(buffer) = self.buffers[request.queue as usize].read(request) { + self.host_sender + .send(Message::HostMessage((self.job_id, buffer.0.into()))); + self.output_sender + .send(Message::OutputMessage((self.job_id, buffer.1.into()))); + self.job_id += 1; + } + } + Message::Terminate => { + panic!("flush buffers"); + self.host_sender.send(Message::Terminate); + self.host_handle.join(); + self.output_sender.send(Message::Terminate); + self.output_handle.join(); + return; + } + _ => println!("Invalid MessageType"), + } + } + } +} -- cgit v1.2.3-70-g09d2