graphblas_sparse_linear_algebra/operators/options/
options_for_operator_with_matrix_arguments.rs

1use suitesparse_graphblas_sys::GrB_Descriptor;
2
3use super::{
4    graphblas_descriptor, GetClearOutputBeforeUse, GetGraphblasDescriptor, GetOperatorMaskOptions,
5    GetOperatorOptions, GetTransposeArguments, WithTransposeArguments,
6};
7
8// Implemented methods do not provide mutable access to GraphBLAS operators or options.
9// Code review must consider that no mtable access is provided.
10// https://doc.rust-lang.org/nomicon/send-and-sync.html
11unsafe impl Send for OptionsForOperatorWithMatrixArguments {}
12unsafe impl Sync for OptionsForOperatorWithMatrixArguments {}
13
14#[derive(Debug, Clone)]
15pub struct OptionsForOperatorWithMatrixArguments {
16    clear_output_before_use: bool,
17    use_mask_structure_of_stored_values_as_mask: bool,
18    use_mask_complement: bool,
19    transpose_first_argument: bool,
20    transpose_second_argument: bool,
21
22    graphblas_descriptor: GrB_Descriptor,
23}
24
25pub trait GetOptionsForOperatorWithMatrixArguments:
26    GetOperatorOptions + GetTransposeArguments
27{
28}
29
30impl GetOperatorOptions for OptionsForOperatorWithMatrixArguments {}
31impl GetOptionsForOperatorWithMatrixArguments for OptionsForOperatorWithMatrixArguments {}
32
33impl GetClearOutputBeforeUse for OptionsForOperatorWithMatrixArguments {
34    fn clear_output_before_use(&self) -> bool {
35        self.clear_output_before_use
36    }
37}
38
39impl GetOperatorMaskOptions for OptionsForOperatorWithMatrixArguments {
40    fn use_mask_structure_of_stored_values_as_mask(&self) -> bool {
41        self.use_mask_structure_of_stored_values_as_mask
42    }
43
44    fn use_mask_complement(&self) -> bool {
45        self.use_mask_complement
46    }
47}
48
49impl GetTransposeArguments for OptionsForOperatorWithMatrixArguments {
50    fn transpose_first_argument(&self) -> bool {
51        self.transpose_first_argument
52    }
53
54    fn transpose_second_argument(&self) -> bool {
55        self.transpose_second_argument
56    }
57}
58
59impl GetGraphblasDescriptor for OptionsForOperatorWithMatrixArguments {
60    fn graphblas_descriptor(&self) -> GrB_Descriptor {
61        self.graphblas_descriptor
62    }
63}
64
65impl WithTransposeArguments for OptionsForOperatorWithMatrixArguments {
66    fn with_negated_transpose_first_argument(&self) -> Self {
67        OptionsForOperatorWithMatrixArguments::new(
68            self.clear_output_before_use,
69            self.use_mask_structure_of_stored_values_as_mask,
70            self.use_mask_complement,
71            !self.transpose_first_argument,
72            self.transpose_second_argument,
73        )
74    }
75
76    fn with_negated_transpose_second_argument(&self) -> Self {
77        OptionsForOperatorWithMatrixArguments::new(
78            self.clear_output_before_use,
79            self.use_mask_structure_of_stored_values_as_mask,
80            self.use_mask_complement,
81            self.transpose_first_argument,
82            !self.transpose_second_argument,
83        )
84    }
85
86    fn with_transpose_first_argument(&self, transpose_first_argument: bool) -> Self {
87        if transpose_first_argument == self.transpose_first_argument {
88            self.clone()
89        } else {
90            OptionsForOperatorWithMatrixArguments::new(
91                self.clear_output_before_use,
92                self.use_mask_structure_of_stored_values_as_mask,
93                self.use_mask_complement,
94                transpose_first_argument,
95                self.transpose_second_argument,
96            )
97        }
98    }
99
100    fn with_transpose_second_argument(&self, transpose_second_argument: bool) -> Self {
101        if transpose_second_argument == self.transpose_second_argument {
102            self.clone()
103        } else {
104            OptionsForOperatorWithMatrixArguments::new(
105                self.clear_output_before_use,
106                self.use_mask_structure_of_stored_values_as_mask,
107                self.use_mask_complement,
108                self.transpose_first_argument,
109                transpose_second_argument,
110            )
111        }
112    }
113
114    fn with_transpose_matrix_arguments(
115        &self,
116        transpose_first_argument: bool,
117        transpose_second_argument: bool,
118    ) -> Self {
119        if transpose_first_argument == self.transpose_first_argument
120            && transpose_second_argument == self.transpose_second_argument
121        {
122            self.clone()
123        } else {
124            OptionsForOperatorWithMatrixArguments::new(
125                self.clear_output_before_use,
126                self.use_mask_structure_of_stored_values_as_mask,
127                self.use_mask_complement,
128                transpose_first_argument,
129                transpose_second_argument,
130            )
131        }
132    }
133}
134
135impl OptionsForOperatorWithMatrixArguments {
136    pub fn new(
137        clear_output_before_use: bool,
138        use_mask_structure_of_stored_values_as_mask: bool,
139        use_mask_complement: bool,
140        transpose_first_argument: bool,
141        transpose_second_argument: bool,
142    ) -> Self {
143        Self {
144            clear_output_before_use,
145            use_mask_structure_of_stored_values_as_mask,
146            use_mask_complement,
147            transpose_first_argument,
148            transpose_second_argument,
149
150            graphblas_descriptor: graphblas_descriptor(
151                clear_output_before_use,
152                false,
153                false,
154                transpose_first_argument,
155                transpose_second_argument,
156            ),
157        }
158    }
159
160    pub fn new_default() -> Self {
161        let use_mask_structure_of_stored_values_as_mask = false;
162        let use_mask_complement = false;
163        let transpose_first_argument = false;
164        let transpose_second_argument = false;
165        let clear_output_before_use = false;
166
167        Self {
168            clear_output_before_use,
169            use_mask_structure_of_stored_values_as_mask,
170            use_mask_complement,
171            transpose_first_argument,
172            transpose_second_argument,
173
174            graphblas_descriptor: graphblas_descriptor(
175                clear_output_before_use,
176                false,
177                false,
178                transpose_first_argument,
179                transpose_second_argument,
180            ),
181        }
182    }
183}
184
185#[cfg(test)]
186mod tests {
187    use std::ptr;
188
189    use super::*;
190
191    #[test]
192    fn test_options() {
193        let default_options = OptionsForOperatorWithMatrixArguments::new_default();
194        let expected_value: GrB_Descriptor = ptr::null_mut();
195        assert_eq!(default_options.graphblas_descriptor(), expected_value)
196    }
197}