summaryrefslogtreecommitdiff
path: root/src/solvers/opencl.rs
blob: 676c5cc44609752a266114c864eda8902f51b515 (plain)
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
102
103
104
105
106
use ocl::{Buffer, Context, Device, Platform, Queue};
use std::sync::mpsc::{Receiver, Sender};

pub struct Job {
    rows: Vec<u32>,
    bitmask: u64,
}

pub struct GpuSolver {
    platform: Platform,
    device: Device,
    context: Context,
    queue: Queue,
    n: u32,
    h: u32,
    w: u32,
    permutations: Buffer<u64>,
    rec_queues: Vec<Receiver<Job>>,
}

impl GpuSolver {
    pub fn new(permutation_masks: &[u64], n: u32, h: u32, w: u32) -> ocl::Result<Vec<Sender<Job>>> {
        let platform = ocl::Platform::default();
        let device = ocl::Device::first(platform)?;
        let context = ocl::Context::builder()
            .platform(platform)
            .devices(device.clone())
            .build()?;
        let queue = ocl::Queue::new(&context, device, None)?;

        let buffer = ocl::Buffer::builder()
            .queue(queue.clone())
            .copy_host_slice(permutation_masks)
            .len(permutation_masks.len())
            .build()?;

        let mut senders = Vec::with_capacity(h as usize);
        let mut receivers = Vec::with_capacity(h as usize);
        for _ in 0..h {
            let (sx, rx) = std::sync::mpsc::channel();
            senders.push(sx);
            receivers.push(rx);
        }

        let solver = Self {
            platform,
            device,
            context,
            queue,
            n,
            h,
            w,
            permutations: buffer,
            rec_queues: receivers,
        };
        std::thread::spawn(move || {
            solver.run();
        });
        Ok(senders)
    }

    fn run(self) -> ! {
        for rec in self.rec_queues.iter().cycle() {
            //if rec.
        }
        loop {}
    }
}
/*
pub fn check(permutations: &[u64], w: u32, n: u32, mask: u64, offset: usize) -> ocl::Result<()> {
    //println!("read src!");
    let src = std::fs::read_to_string("src/solvers/check.cl").expect("failed to open kernel file");

    //println!("created queue!");
    println!("offset: {}", offset);
    println!("length: {}", permutations.len() - offset);
    let pro_que = ocl::ProQue::builder()
        .src(src)
        .dims(permutations.len() - offset)
        .build()?;

    let results = pro_que.create_buffer::<i32>()?;
    let kernel = pro_que
        .kernel_builder("check")
        .arg(get_buffer())
        .arg(&results)
        .arg(mask)
        .arg(n)
        .arg(w)
        .arg(offset as u64)
        //.global_work_offset(offset)
        .build()?;

    //println!("starting calculation");
    unsafe {
        kernel.enq()?;
    }

    let mut vec = vec![0; results.len()];
    results.read(&mut vec).enq()?;

    if vec.iter().any(|x| *x != 0) {
        println!("The resuts are now '{:?}'!", vec);
    }
    Ok(())
}*/