summaryrefslogtreecommitdiff
path: root/src/solvers/opencl.rs
blob: 25b8119ac29b2080d218661d94e04b044f827198 (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
use lazy_static::*;
use ocl::ProQue;
#[macro_use]

lazy_static! {
    static ref BUFFER: ocl::Buffer<u64> = {
        let platform = ocl::Platform::default();
        let device = ocl::Device::first(platform).unwrap();
        let context = ocl::Context::builder()
            .platform(platform)
            .devices(device.clone())
            .build()
            .unwrap();
        let queue = ocl::Queue::new(&context, device, None).unwrap();

        println!("created buffer!");
        ocl::Buffer::builder()
            .queue(queue)
            .copy_host_slice(crate::solvers::PERMUTATIONS.1.as_ref())
            .len(crate::solvers::PERMUTATIONS.1.len())
            .build()
            .unwrap()
    };
    static ref QUEUE: ocl::ProQue = {
        let src =
            std::fs::read_to_string("src/solvers/check.cl").expect("failed to open kernel file");
        ProQue::builder()
            .src(src)
            .dims(crate::solvers::PERMUTATIONS.0.len())
            .build()
            .unwrap()
    };
}

pub fn get_buffer() -> &'static ocl::Buffer<u64> {
    &BUFFER
}

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 = 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(())
}