stacked_linear_algebra_graph/graph/vertex_store/vertex_vector/
vertex_vector.rs1use std::fmt::Display;
2use std::mem;
3use std::sync::Arc;
4
5use graphblas_sparse_linear_algebra::collections::sparse_vector::clone_graphblas_vector;
6use graphblas_sparse_linear_algebra::collections::sparse_vector::new_graphblas_vector;
7use graphblas_sparse_linear_algebra::collections::sparse_vector::GetGraphblasSparseVector;
8use graphblas_sparse_linear_algebra::collections::sparse_vector::SparseVector;
9use graphblas_sparse_linear_algebra::context::Context as GraphBLASContext;
10use graphblas_sparse_linear_algebra::context::GetContext;
11use graphblas_sparse_linear_algebra::graphblas_bindings::GrB_Vector;
12use graphblas_sparse_linear_algebra::graphblas_bindings::GrB_Vector_free;
13use graphblas_sparse_linear_algebra::operators::apply::ApplyUnaryOperator;
14use graphblas_sparse_linear_algebra::operators::apply::UnaryOperatorApplier;
15use graphblas_sparse_linear_algebra::operators::binary_operator::Assignment;
16use graphblas_sparse_linear_algebra::operators::mask::SelectEntireVector;
17use graphblas_sparse_linear_algebra::operators::mask::VectorMask;
18use graphblas_sparse_linear_algebra::operators::options::OperatorOptions;
19use graphblas_sparse_linear_algebra::operators::unary_operator::Identity;
20use graphblas_sparse_linear_algebra::value_type::ValueType as GraphblasValueType;
21
22use crate::error::GraphComputingError;
23use crate::graph::graph::GetGraphblasContext;
24use crate::graph::indexing::ElementCount;
25use crate::graph::value_type::implement_1_type_macro_with_enum_type_indentifier_for_all_value_types;
26use crate::graph::value_type::implement_macro_for_all_native_value_types;
27use crate::graph::value_type::GetValueTypeIdentifier;
28use crate::graph::value_type::GetValueTypeIdentifierRef;
29use crate::graph::value_type::ValueType;
30use crate::graph::value_type::ValueTypeIdentifier;
31
32use super::GetVectorLength;
33
34unsafe impl Send for VertexVector {}
35unsafe impl Sync for VertexVector {}
36
37#[derive(Debug)]
38pub(crate) struct VertexVector {
39 graphblas_context: Arc<GraphBLASContext>,
40 value_type: ValueTypeIdentifier,
41 sparse_vector: GrB_Vector,
42}
43
44pub(crate) trait CreateVertexVector<T> {
45 fn new(
46 graphblas_context: Arc<GraphBLASContext>,
47 initial_vertex_capacity: ElementCount,
48 ) -> Result<VertexVector, GraphComputingError>;
49}
50
51impl<T: ValueType + GetValueTypeIdentifier> CreateVertexVector<T> for VertexVector {
52 fn new(
53 graphblas_context: Arc<GraphBLASContext>,
54 initial_vertex_capacity: ElementCount,
55 ) -> Result<VertexVector, GraphComputingError> {
56 Ok(VertexVector {
57 graphblas_context: graphblas_context.clone(),
58 sparse_vector: unsafe {
59 new_graphblas_vector(
60 &graphblas_context,
61 initial_vertex_capacity,
62 T::to_graphblas_type(),
63 )?
64 },
65 value_type: T::value_type_identifier(),
66 })
67 }
68}
69
70impl Drop for VertexVector {
71 fn drop(&mut self) -> () {
72 let _ = self
73 .graphblas_context
74 .call_without_detailed_error_information(|| unsafe {
75 GrB_Vector_free(&mut self.sparse_vector)
76 });
77 }
78}
79
80impl Clone for VertexVector {
81 fn clone(&self) -> Self {
82 VertexVector {
83 graphblas_context: self.graphblas_context.to_owned(),
84 value_type: self.value_type.to_owned(),
85 sparse_vector: unsafe {
86 clone_graphblas_vector(self.context_ref(), self.graphblas_vector_ref()).unwrap()
87 },
88 }
89 }
90}
91
92impl Display for VertexVector {
93 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94 writeln!(f, "VertexVector:");
95 writeln!(f, "graphblas_context: {:?}", self.graphblas_context);
96 writeln!(f, "value_type: {:?}", self.value_type);
97 writeln!(
98 f,
99 "sparse_vector: \n{}",
100 <VertexVector as ToSparseVector<f64>>::to_sparse_vector(self).unwrap()
101 );
102 return writeln!(f, "");
103 }
104}
105
106impl GetGraphblasContext for VertexVector {
107 fn graphblas_context(&self) -> Arc<GraphBLASContext> {
108 self.graphblas_context.clone()
109 }
110
111 fn graphblas_context_ref(&self) -> &Arc<GraphBLASContext> {
112 &self.graphblas_context
113 }
114}
115
116impl GetContext for VertexVector {
117 fn context(&self) -> Arc<GraphBLASContext> {
118 self.graphblas_context.clone()
119 }
120
121 fn context_ref(&self) -> &Arc<GraphBLASContext> {
122 &self.graphblas_context
123 }
124}
125
126impl GetGraphblasSparseVector for VertexVector {
127 unsafe fn graphblas_vector(&self) -> GrB_Vector {
128 self.sparse_vector
129 }
130
131 unsafe fn graphblas_vector_ref(&self) -> &GrB_Vector {
132 &self.sparse_vector
133 }
134
135 unsafe fn graphblas_vector_mut_ref(&mut self) -> &mut GrB_Vector {
136 &mut self.sparse_vector
137 }
138}
139
140impl VectorMask for VertexVector {
141 unsafe fn graphblas_vector(&self) -> GrB_Vector {
142 self.sparse_vector
143 }
144}
145
146impl GetValueTypeIdentifierRef for VertexVector {
147 fn value_type_identifier_ref(&self) -> &ValueTypeIdentifier {
148 &self.value_type
149 }
150}
151
152pub trait ToSparseVector<T: ValueType> {
160 fn to_sparse_vector(&self) -> Result<SparseVector<T>, GraphComputingError>;
161}
162
163pub trait IntoSparseVector<T: ValueType> {
164 fn into_sparse_vector(self) -> Result<SparseVector<T>, GraphComputingError>;
165}
166
167impl<T: ValueType + ToSparseVectorForValueType<T>> ToSparseVector<T> for VertexVector {
168 fn to_sparse_vector(&self) -> Result<SparseVector<T>, GraphComputingError> {
169 T::to_sparse_vector(self)
170 }
171}
172
173impl<T: ValueType + IntoSparseVectorForValueType<T>> IntoSparseVector<T> for VertexVector {
174 fn into_sparse_vector(self) -> Result<SparseVector<T>, GraphComputingError> {
175 T::into_sparse_vector(self)
176 }
177}
178
179pub(crate) trait ToSparseVectorForValueType<T: ValueType> {
180 fn to_sparse_vector(
181 vector: &(impl GetContext
182 + GetGraphblasSparseVector
183 + GetVectorLength
184 + GetValueTypeIdentifierRef),
185 ) -> Result<SparseVector<T>, GraphComputingError>;
186}
187
188pub(crate) trait IntoSparseVectorForValueType<T: ValueType> {
189 fn into_sparse_vector(vector: VertexVector) -> Result<SparseVector<T>, GraphComputingError>;
190}
191
192pub(crate) trait IntoSparseVectorAndClearValuesForValueType<T: ValueType> {
193 fn into_sparse_vector_and_clear_values(
194 vector: &mut VertexVector,
195 ) -> Result<SparseVector<T>, GraphComputingError>;
196}
197
198macro_rules! implement_to_sparse_vector_for_value_type {
199 ($value_type_identifier:ident, $value_type:ty) => {
200 impl ToSparseVectorForValueType<$value_type> for $value_type {
201 fn to_sparse_vector(
202 vector: &(impl GetContext
203 + GetGraphblasSparseVector
204 + GetVectorLength
205 + GetValueTypeIdentifierRef),
206 ) -> Result<SparseVector<$value_type>, GraphComputingError> {
207 match vector.value_type_identifier_ref() {
208 &ValueTypeIdentifier::$value_type_identifier => unsafe {
209 Ok(SparseVector::<$value_type>::from_graphblas_vector(
210 vector.context(),
211 clone_graphblas_vector(
212 vector.context_ref(),
213 vector.graphblas_vector_ref(),
214 )?,
215 )?)
216 },
217 _ => {
218 let mut product_vector =
219 SparseVector::<$value_type>::new(vector.context(), vector.length()?)?;
220
221 UnaryOperatorApplier::new().apply_to_vector(
222 &Identity::<$value_type>::new(),
223 vector,
224 &Assignment::<$value_type>::new(),
225 &mut product_vector,
226 &SelectEntireVector::new(vector.context()),
227 &OperatorOptions::new_default(),
228 )?;
229
230 return Ok(product_vector);
231 }
232 }
233 }
234 }
235 };
236}
237implement_1_type_macro_with_enum_type_indentifier_for_all_value_types!(
238 implement_to_sparse_vector_for_value_type
239);
240
241macro_rules! implement_into_sparse_vector_for_value_type {
242 ($value_type_identifier:ident, $value_type:ty) => {
243 impl IntoSparseVectorForValueType<$value_type> for $value_type {
244 fn into_sparse_vector(
245 mut vertex_vector: VertexVector,
246 ) -> Result<SparseVector<$value_type>, GraphComputingError> {
247 <$value_type>::into_sparse_vector_and_clear_values(&mut vertex_vector)
248 }
249 }
250 };
251}
252implement_1_type_macro_with_enum_type_indentifier_for_all_value_types!(
253 implement_into_sparse_vector_for_value_type
254);
255
256macro_rules! implement_into_sparse_vector_for_value_type {
257 ($value_type_identifier:ident, $value_type:ty) => {
258 impl IntoSparseVectorAndClearValuesForValueType<$value_type> for $value_type {
259 fn into_sparse_vector_and_clear_values(
260 vertex_vector: &mut VertexVector,
261 ) -> Result<SparseVector<$value_type>, GraphComputingError> {
262 match vertex_vector.value_type_identifier_ref() {
263 &ValueTypeIdentifier::$value_type_identifier => unsafe {
264 let mut graphblas_vector = new_graphblas_vector(
265 &vertex_vector.graphblas_context,
266 vertex_vector.length()?,
267 <$value_type>::to_graphblas_type(),
268 )?;
269
270 mem::swap(&mut graphblas_vector, &mut vertex_vector.sparse_vector);
271
272 Ok(SparseVector::<$value_type>::from_graphblas_vector(
273 vertex_vector.context(),
274 graphblas_vector,
275 )?)
276 },
277 _ => {
278 let mut product_vector = SparseVector::<$value_type>::new(
279 vertex_vector.context(),
280 vertex_vector.length()?,
281 )?;
282
283 UnaryOperatorApplier::new().apply_to_vector(
284 &Identity::<$value_type>::new(),
285 vertex_vector,
286 &Assignment::<$value_type>::new(),
287 &mut product_vector,
288 &SelectEntireVector::new(vertex_vector.context()),
289 &OperatorOptions::new_default(),
290 )?;
291
292 return Ok(product_vector);
293 }
294 }
295 }
296 }
297 };
298}
299implement_1_type_macro_with_enum_type_indentifier_for_all_value_types!(
300 implement_into_sparse_vector_for_value_type
301);
302
303pub(crate) trait CreateSparseVectorForValueType<T: ValueType> {
304 fn new_sparse_vector(
305 graphblas_context: Arc<GraphBLASContext>,
306 initial_vertex_capacity: ElementCount,
307 ) -> Result<SparseVector<T>, GraphComputingError>;
308}
309
310macro_rules! implement_create_sparse_vector_for_value_type {
311 ($value_type:ty) => {
312 impl CreateSparseVectorForValueType<$value_type> for $value_type {
313 fn new_sparse_vector(
314 graphblas_context: Arc<GraphBLASContext>,
315 initial_vertex_capacity: ElementCount,
316 ) -> Result<SparseVector<$value_type>, GraphComputingError> {
317 Ok(SparseVector::<$value_type>::new(
318 graphblas_context,
319 initial_vertex_capacity,
320 )?)
321 }
322 }
323 };
324}
325implement_macro_for_all_native_value_types!(implement_create_sparse_vector_for_value_type);