summaryrefslogtreecommitdiff
path: root/src/solvers/gpu/mod.rs
blob: 17bc9642fba9d3bdac5ef5636498d8f76e7777b6 (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
107
108
109
110
111
112
113
114
115
pub mod host;
pub mod manager;
pub mod output;

pub use manager::*;
use rayon::prelude::*;

type MaskMessage = (u64, u32, Vec<u64>);
type RowMessage = (u64, Vec<Vec<u32>>);

#[derive(Debug)]
pub enum Message {
    CheckRequest(CheckRequest),
    HostMessage(MaskMessage),
    OutputMessage(RowMessage),
    ResultMessage(ResultMessage),
    RowResult(RowResult),
    Terminate,
    CpuDone,
    GpuDone,
}

#[derive(Debug)]
pub struct ResultMessage {
    data: Vec<u64>,
    offset: usize,
    size: usize,
    wg_size: usize,
    id: u64,
}

impl ResultMessage {
    fn new(data: Vec<u64>, offset: usize, size: usize, wg_size: usize, id: u64) -> Self {
        Self {
            data,
            offset,
            size,
            wg_size,
            id,
        }
    }
    fn valid_walls(&self) -> Vec<Vec<u32>> {
        let mut result = vec![Vec::new(); self.wg_size];
        let tup: Vec<(usize, u32)> = self
            .data
            .par_iter()
            .enumerate()
            .filter_map(|(j, r)| {
                if *r != 0 {
                    Some(
                        (0..64)
                            .filter_map(|b| {
                                if r & (1 << b) != 0 {
                                    let permutation = j / self.size + self.offset;
                                    let instruction = (j % self.size) * 64 + b;
                                    Some((instruction, permutation as u32))
                                } else {
                                    None
                                }
                            })
                            .collect(),
                    )
                } else {
                    None
                }
            })
            .flat_map(|a: Vec<_>| a.to_vec())
            .collect();
        for t in tup {
            result[t.0 as usize].push(t.1);
        }
        result
    }
}

#[derive(Debug)]
pub struct CheckRequest {
    rows: Vec<u32>,
    bitmask: u64,
    queue: u32,
}

impl CheckRequest {
    pub fn new(rows: Vec<u32>, bitmask: u64, queue: u32) -> Self {
        Self {
            rows,
            bitmask,
            queue,
        }
    }
}

#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct RowResult {
    rows: Vec<u32>,
}

impl RowResult {
    fn new(mut rows: Vec<u32>) -> Self {
        //rows.push(0);
        rows.sort();
        Self { rows }
    }
    fn output(&self) {
        /*let s = self
            .rows
            .iter()
            .fold(String::new(), |s, d| s + &d.to_string() + " ");
        println!("{}", s);*/
        let i = self.rows[0];
        for r in self.rows.iter() {
            println!("{}\t{}", i, r);
        }
    }
}