xref: /libCEED/rust/libceed/src/vector.rs (revision b7c9bbdafc9b91976b65f80ebb2c5357c2efd8bc)
1 // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3 // reserved. See files LICENSE and NOTICE for details.
4 //
5 // This file is part of CEED, a collection of benchmarks, miniapps, software
6 // libraries and APIs for efficient high-order finite element and spectral
7 // element discretizations for exascale applications. For more information and
8 // source code availability see http://github.com/ceed.
9 //
10 // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11 // a collaborative effort of two U.S. Department of Energy organizations (Office
12 // of Science and the National Nuclear Security Administration) responsible for
13 // the planning and preparation of a capable exascale ecosystem, including
14 // software, applications, hardware, advanced system engineering and early
15 // testbed platforms, in support of the nation's exascale computing imperative
16 
17 //! A Ceed Vector constitutes the main data structure and serves as input/output
18 //! for Ceed Operators.
19 
20 use std::{
21     ops::{Deref, DerefMut},
22     os::raw::c_char,
23 };
24 
25 use crate::prelude::*;
26 
27 // -----------------------------------------------------------------------------
28 // CeedVector option
29 // -----------------------------------------------------------------------------
30 #[derive(Debug)]
31 pub enum VectorOpt<'a> {
32     Some(&'a Vector<'a>),
33     Active,
34     None,
35 }
36 /// Construct a VectorOpt reference from a Vector reference
37 impl<'a> From<&'a Vector<'_>> for VectorOpt<'a> {
38     fn from(vec: &'a Vector) -> Self {
39         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE });
40         debug_assert!(vec.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE });
41         Self::Some(vec)
42     }
43 }
44 impl<'a> VectorOpt<'a> {
45     /// Transform a Rust libCEED VectorOpt into C libCEED CeedVector
46     pub(crate) fn to_raw(self) -> bind_ceed::CeedVector {
47         match self {
48             Self::Some(vec) => vec.ptr,
49             Self::Active => unsafe { bind_ceed::CEED_VECTOR_ACTIVE },
50             Self::None => unsafe { bind_ceed::CEED_VECTOR_NONE },
51         }
52     }
53 
54     /// Check if a VectorOpt is Some
55     ///
56     /// ```
57     /// # use libceed::prelude::*;
58     /// # fn main() -> Result<(), libceed::CeedError> {
59     /// # let ceed = libceed::Ceed::default_init();
60     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
61     /// let vec_opt = VectorOpt::from(&vec);
62     /// assert!(vec_opt.is_some(), "Incorrect VectorOpt");
63     ///
64     /// let vec_opt = VectorOpt::Active;
65     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
66     ///
67     /// let vec_opt = VectorOpt::None;
68     /// assert!(!vec_opt.is_some(), "Incorrect VectorOpt");
69     /// # Ok(())
70     /// # }
71     /// ```
72     pub fn is_some(&self) -> bool {
73         match self {
74             Self::Some(_) => true,
75             Self::Active => false,
76             Self::None => false,
77         }
78     }
79 
80     /// Check if a VectorOpt is Active
81     ///
82     /// ```
83     /// # use libceed::prelude::*;
84     /// # fn main() -> Result<(), libceed::CeedError> {
85     /// # let ceed = libceed::Ceed::default_init();
86     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
87     /// let vec_opt = VectorOpt::from(&vec);
88     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
89     ///
90     /// let vec_opt = VectorOpt::Active;
91     /// assert!(vec_opt.is_active(), "Incorrect VectorOpt");
92     ///
93     /// let vec_opt = VectorOpt::None;
94     /// assert!(!vec_opt.is_active(), "Incorrect VectorOpt");
95     /// # Ok(())
96     /// # }
97     /// ```
98     pub fn is_active(&self) -> bool {
99         match self {
100             Self::Some(_) => false,
101             Self::Active => true,
102             Self::None => false,
103         }
104     }
105 
106     /// Check if a VectorOpt is Some
107     ///
108     /// ```
109     /// # use libceed::prelude::*;
110     /// # fn main() -> Result<(), libceed::CeedError> {
111     /// # let ceed = libceed::Ceed::default_init();
112     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
113     /// let vec_opt = VectorOpt::from(&vec);
114     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
115     ///
116     /// let vec_opt = VectorOpt::Active;
117     /// assert!(!vec_opt.is_none(), "Incorrect VectorOpt");
118     ///
119     /// let vec_opt = VectorOpt::None;
120     /// assert!(vec_opt.is_none(), "Incorrect VectorOpt");
121     /// # Ok(())
122     /// # }
123     /// ```
124     pub fn is_none(&self) -> bool {
125         match self {
126             Self::Some(_) => false,
127             Self::Active => false,
128             Self::None => true,
129         }
130     }
131 }
132 
133 // -----------------------------------------------------------------------------
134 // CeedVector context wrapper
135 // -----------------------------------------------------------------------------
136 #[derive(Debug)]
137 pub struct Vector<'a> {
138     ceed: &'a crate::Ceed,
139     pub(crate) ptr: bind_ceed::CeedVector,
140 }
141 impl From<&'_ Vector<'_>> for bind_ceed::CeedVector {
142     fn from(vec: &Vector) -> Self {
143         vec.ptr
144     }
145 }
146 
147 // -----------------------------------------------------------------------------
148 // Destructor
149 // -----------------------------------------------------------------------------
150 impl<'a> Drop for Vector<'a> {
151     fn drop(&mut self) {
152         let not_none_and_active = self.ptr != unsafe { bind_ceed::CEED_VECTOR_NONE }
153             && self.ptr != unsafe { bind_ceed::CEED_VECTOR_ACTIVE };
154 
155         if not_none_and_active {
156             unsafe { bind_ceed::CeedVectorDestroy(&mut self.ptr) };
157         }
158     }
159 }
160 
161 // -----------------------------------------------------------------------------
162 // Display
163 // -----------------------------------------------------------------------------
164 impl<'a> fmt::Display for Vector<'a> {
165     /// View a Vector
166     ///
167     /// ```
168     /// # use libceed::prelude::*;
169     /// # fn main() -> Result<(), libceed::CeedError> {
170     /// # let ceed = libceed::Ceed::default_init();
171     /// let vec = libceed::vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
172     /// assert_eq!(
173     ///     vec.to_string(),
174     ///     "CeedVector length 3
175     ///     1.00000000
176     ///     2.00000000
177     ///     3.00000000
178     /// "
179     /// );
180     /// # Ok(())
181     /// # }
182     /// ```
183     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
184         let mut ptr = std::ptr::null_mut();
185         let mut sizeloc = crate::MAX_BUFFER_LENGTH;
186         let format = CString::new("%12.8f").expect("CString::new failed");
187         let format_c: *const c_char = format.into_raw();
188         let cstring = unsafe {
189             let file = bind_ceed::open_memstream(&mut ptr, &mut sizeloc);
190             bind_ceed::CeedVectorView(self.ptr, format_c, file);
191             bind_ceed::fclose(file);
192             CString::from_raw(ptr)
193         };
194         cstring.to_string_lossy().fmt(f)
195     }
196 }
197 
198 // -----------------------------------------------------------------------------
199 // Implementations
200 // -----------------------------------------------------------------------------
201 impl<'a> Vector<'a> {
202     // Constructors
203     pub fn create(ceed: &'a crate::Ceed, n: usize) -> crate::Result<Self> {
204         let n = i32::try_from(n).unwrap();
205         let mut ptr = std::ptr::null_mut();
206         let ierr = unsafe { bind_ceed::CeedVectorCreate(ceed.ptr, n, &mut ptr) };
207         ceed.check_error(ierr)?;
208         Ok(Self { ceed, ptr })
209     }
210 
211     pub(crate) fn from_raw(
212         ceed: &'a crate::Ceed,
213         ptr: bind_ceed::CeedVector,
214     ) -> crate::Result<Self> {
215         Ok(Self { ceed, ptr })
216     }
217 
218     /// Create a Vector from a slice
219     ///
220     /// # arguments
221     ///
222     /// * `slice` - values to initialize vector with
223     ///
224     /// ```
225     /// # use libceed::prelude::*;
226     /// # fn main() -> Result<(), libceed::CeedError> {
227     /// # let ceed = libceed::Ceed::default_init();
228     /// let vec = vector::Vector::from_slice(&ceed, &[1., 2., 3.])?;
229     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
230     /// # Ok(())
231     /// # }
232     /// ```
233     pub fn from_slice(ceed: &'a crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> {
234         let mut x = Self::create(ceed, v.len())?;
235         x.set_slice(v)?;
236         Ok(x)
237     }
238 
239     /// Create a Vector from a mutable array reference
240     ///
241     /// # arguments
242     ///
243     /// * `slice` - values to initialize vector with
244     ///
245     /// ```
246     /// # use libceed::prelude::*;
247     /// # fn main() -> Result<(), libceed::CeedError> {
248     /// # let ceed = libceed::Ceed::default_init();
249     /// let mut rust_vec = vec![1., 2., 3.];
250     /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?;
251     ///
252     /// assert_eq!(vec.length(), 3, "Incorrect length from slice");
253     /// # Ok(())
254     /// # }
255     /// ```
256     pub fn from_array(ceed: &'a crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> {
257         let x = Self::create(ceed, v.len())?;
258         let (host, user_pointer) = (
259             crate::MemType::Host as bind_ceed::CeedMemType,
260             crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode,
261         );
262         let v = v.as_ptr() as *mut crate::Scalar;
263         let ierr = unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) };
264         ceed.check_error(ierr)?;
265         Ok(x)
266     }
267 
268     /// Returns the length of a CeedVector
269     ///
270     /// ```
271     /// # use libceed::prelude::*;
272     /// # fn main() -> Result<(), libceed::CeedError> {
273     /// # let ceed = libceed::Ceed::default_init();
274     /// let vec = ceed.vector(10)?;
275     ///
276     /// let n = vec.length();
277     /// assert_eq!(n, 10, "Incorrect length");
278     /// # Ok(())
279     /// # }
280     /// ```
281     pub fn length(&self) -> usize {
282         let mut n = 0;
283         unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) };
284         usize::try_from(n).unwrap()
285     }
286 
287     /// Returns the length of a CeedVector
288     ///
289     /// ```
290     /// # use libceed::prelude::*;
291     /// # fn main() -> Result<(), libceed::CeedError> {
292     /// # let ceed = libceed::Ceed::default_init();
293     /// let vec = ceed.vector(10)?;
294     /// assert_eq!(vec.len(), 10, "Incorrect length");
295     /// # Ok(())
296     /// # }
297     /// ```
298     pub fn len(&self) -> usize {
299         self.length()
300     }
301 
302     /// Set the CeedVector to a constant value
303     ///
304     /// # arguments
305     ///
306     /// * `val` - Value to be used
307     ///
308     /// ```
309     /// # use libceed::prelude::*;
310     /// # fn main() -> Result<(), libceed::CeedError> {
311     /// # let ceed = libceed::Ceed::default_init();
312     /// let len = 10;
313     /// let mut vec = ceed.vector(len)?;
314     ///
315     /// let val = 42.0;
316     /// vec.set_value(val)?;
317     ///
318     /// vec.view().iter().for_each(|v| {
319     ///     assert_eq!(*v, val, "Value not set correctly");
320     /// });
321     /// # Ok(())
322     /// # }
323     /// ```
324     pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> {
325         let ierr = unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) };
326         self.ceed.check_error(ierr)
327     }
328 
329     /// Set values from a slice of the same length
330     ///
331     /// # arguments
332     ///
333     /// * `slice` - values to into self; length must match
334     ///
335     /// ```
336     /// # use libceed::prelude::*;
337     /// # fn main() -> Result<(), libceed::CeedError> {
338     /// # let ceed = libceed::Ceed::default_init();
339     /// let mut vec = ceed.vector(4)?;
340     /// vec.set_slice(&[10., 11., 12., 13.])?;
341     ///
342     /// vec.view().iter().enumerate().for_each(|(i, v)| {
343     ///     assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly");
344     /// });
345     /// # Ok(())
346     /// # }
347     /// ```
348     pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> {
349         assert_eq!(self.length(), slice.len());
350         let (host, copy_mode) = (
351             crate::MemType::Host as bind_ceed::CeedMemType,
352             crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode,
353         );
354         let ierr = unsafe {
355             bind_ceed::CeedVectorSetArray(
356                 self.ptr,
357                 host,
358                 copy_mode,
359                 slice.as_ptr() as *mut crate::Scalar,
360             )
361         };
362         self.ceed.check_error(ierr)
363     }
364 
365     /// Sync the CeedVector to a specified memtype
366     ///
367     /// # arguments
368     ///
369     /// * `mtype` - Memtype to be synced
370     ///
371     /// ```
372     /// # use libceed::prelude::*;
373     /// # fn main() -> Result<(), libceed::CeedError> {
374     /// # let ceed = libceed::Ceed::default_init();
375     /// let len = 10;
376     /// let mut vec = ceed.vector(len)?;
377     ///
378     /// let val = 42.0;
379     /// vec.set_value(val);
380     /// vec.sync(MemType::Host)?;
381     ///
382     /// vec.view().iter().for_each(|v| {
383     ///     assert_eq!(*v, val, "Value not set correctly");
384     /// });
385     /// # Ok(())
386     /// # }
387     /// ```
388     pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> {
389         let ierr =
390             unsafe { bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) };
391         self.ceed.check_error(ierr)
392     }
393 
394     /// Create an immutable view
395     ///
396     /// ```
397     /// # use libceed::prelude::*;
398     /// # fn main() -> Result<(), libceed::CeedError> {
399     /// # let ceed = libceed::Ceed::default_init();
400     /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
401     ///
402     /// let v = vec.view();
403     /// assert_eq!(v[0..2], [10., 11.]);
404     ///
405     /// // It is valid to have multiple immutable views
406     /// let w = vec.view();
407     /// assert_eq!(v[1..], w[1..]);
408     /// # Ok(())
409     /// # }
410     /// ```
411     pub fn view(&self) -> VectorView {
412         VectorView::new(self)
413     }
414 
415     /// Create an mutable view
416     ///
417     /// ```
418     /// # use libceed::prelude::*;
419     /// # fn main() -> Result<(), libceed::CeedError> {
420     /// # let ceed = libceed::Ceed::default_init();
421     /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?;
422     ///
423     /// {
424     ///     let mut v = vec.view_mut();
425     ///     v[2] = 9.;
426     /// }
427     ///
428     /// let w = vec.view();
429     /// assert_eq!(w[2], 9., "View did not mutate data");
430     /// # Ok(())
431     /// # }
432     /// ```
433     pub fn view_mut(&mut self) -> VectorViewMut {
434         VectorViewMut::new(self)
435     }
436 
437     /// Return the norm of a CeedVector
438     ///
439     /// # arguments
440     ///
441     /// * `ntype` - Norm type One, Two, or Max
442     ///
443     /// ```
444     /// # use libceed::prelude::*;
445     /// # fn main() -> Result<(), libceed::CeedError> {
446     /// # let ceed = libceed::Ceed::default_init();
447     /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?;
448     ///
449     /// let max_norm = vec.norm(NormType::Max)?;
450     /// assert_eq!(max_norm, 4.0, "Incorrect Max norm");
451     ///
452     /// let l1_norm = vec.norm(NormType::One)?;
453     /// assert_eq!(l1_norm, 10., "Incorrect L1 norm");
454     ///
455     /// let l2_norm = vec.norm(NormType::Two)?;
456     /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm");
457     /// # Ok(())
458     /// # }
459     /// ```
460     pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> {
461         let mut res: crate::Scalar = 0.0;
462         let ierr = unsafe {
463             bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res)
464         };
465         self.ceed.check_error(ierr)?;
466         Ok(res)
467     }
468 
469     /// Compute x = alpha x for a CeedVector
470     ///
471     /// # arguments
472     ///
473     /// * `alpha` - scaling factor
474     ///
475     /// ```
476     /// # use libceed::prelude::*;
477     /// # fn main() -> Result<(), libceed::CeedError> {
478     /// # let ceed = libceed::Ceed::default_init();
479     /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
480     ///
481     /// vec = vec.scale(-1.0)?;
482     /// vec.view().iter().enumerate().for_each(|(i, &v)| {
483     ///     assert_eq!(v, -(i as Scalar), "Value not set correctly");
484     /// });
485     /// # Ok(())
486     /// # }
487     /// ```
488     #[allow(unused_mut)]
489     pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> {
490         let ierr = unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) };
491         self.ceed.check_error(ierr)?;
492         Ok(self)
493     }
494 
495     /// Compute y = alpha x + y for a pair of CeedVectors
496     ///
497     /// # arguments
498     ///
499     /// * `alpha` - scaling factor
500     /// * `x`     - second vector, must be different than self
501     ///
502     /// ```
503     /// # use libceed::prelude::*;
504     /// # fn main() -> Result<(), libceed::CeedError> {
505     /// # let ceed = libceed::Ceed::default_init();
506     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
507     /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
508     ///
509     /// y = y.axpy(-0.5, &x)?;
510     /// y.view().iter().enumerate().for_each(|(i, &v)| {
511     ///     assert_eq!(v, (i as Scalar) / 2.0, "Value not set correctly");
512     /// });
513     /// # Ok(())
514     /// # }
515     /// ```
516     #[allow(unused_mut)]
517     pub fn axpy(mut self, alpha: crate::Scalar, x: &crate::Vector) -> crate::Result<Self> {
518         let ierr = unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) };
519         self.ceed.check_error(ierr)?;
520         Ok(self)
521     }
522 
523     /// Compute the pointwise multiplication w = x .* y for CeedVectors
524     ///
525     /// # arguments
526     ///
527     /// * `x` - first vector for product
528     /// * `y` - second vector for product
529     ///
530     /// ```
531     /// # use libceed::prelude::*;
532     /// # fn main() -> Result<(), libceed::CeedError> {
533     /// # let ceed = libceed::Ceed::default_init();
534     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
535     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
536     /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
537     ///
538     /// w = w.pointwise_mult(&x, &y)?;
539     /// w.view().iter().enumerate().for_each(|(i, &v)| {
540     ///     assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly");
541     /// });
542     /// # Ok(())
543     /// # }
544     /// ```
545     #[allow(unused_mut)]
546     pub fn pointwise_mult(mut self, x: &crate::Vector, y: &crate::Vector) -> crate::Result<Self> {
547         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) };
548         self.ceed.check_error(ierr)?;
549         Ok(self)
550     }
551 
552     /// Compute the pointwise multiplication w = w .* x for CeedVectors
553     ///
554     /// # arguments
555     ///
556     /// * `x` - second vector for product
557     ///
558     /// ```
559     /// # use libceed::prelude::*;
560     /// # fn main() -> Result<(), libceed::CeedError> {
561     /// # let ceed = libceed::Ceed::default_init();
562     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
563     /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
564     ///
565     /// w = w.pointwise_scale(&x)?;
566     /// w.view().iter().enumerate().for_each(|(i, &v)| {
567     ///     assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly");
568     /// });
569     /// # Ok(())
570     /// # }
571     /// ```
572     #[allow(unused_mut)]
573     pub fn pointwise_scale(mut self, x: &crate::Vector) -> crate::Result<Self> {
574         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) };
575         self.ceed.check_error(ierr)?;
576         Ok(self)
577     }
578 
579     /// Compute the pointwise multiplication w = w .* w for a CeedVector
580     ///
581     /// ```
582     /// # use libceed::prelude::*;
583     /// # fn main() -> Result<(), libceed::CeedError> {
584     /// # let ceed = libceed::Ceed::default_init();
585     /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?;
586     ///
587     /// w = w.pointwise_square()?;
588     /// w.view().iter().enumerate().for_each(|(i, &v)| {
589     ///     assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly");
590     /// });
591     /// # Ok(())
592     /// # }
593     /// ```
594     #[allow(unused_mut)]
595     pub fn pointwise_square(mut self) -> crate::Result<Self> {
596         let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) };
597         self.ceed.check_error(ierr)?;
598         Ok(self)
599     }
600 }
601 
602 // -----------------------------------------------------------------------------
603 // Vector Viewer
604 // -----------------------------------------------------------------------------
605 /// A (host) view of a Vector with Deref to slice.  We can't make
606 /// Vector itself Deref to slice because we can't handle the drop to
607 /// call bind_ceed::CeedVectorRestoreArrayRead().
608 #[derive(Debug)]
609 pub struct VectorView<'a> {
610     vec: &'a Vector<'a>,
611     array: *const crate::Scalar,
612 }
613 
614 impl<'a> VectorView<'a> {
615     /// Construct a VectorView from a Vector reference
616     fn new(vec: &'a Vector) -> Self {
617         let mut array = std::ptr::null();
618         unsafe {
619             bind_ceed::CeedVectorGetArrayRead(
620                 vec.ptr,
621                 crate::MemType::Host as bind_ceed::CeedMemType,
622                 &mut array,
623             );
624         }
625         Self {
626             vec: vec,
627             array: array,
628         }
629     }
630 }
631 
632 // Destructor
633 impl<'a> Drop for VectorView<'a> {
634     fn drop(&mut self) {
635         unsafe {
636             bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array);
637         }
638     }
639 }
640 
641 // Data access
642 impl<'a> Deref for VectorView<'a> {
643     type Target = [crate::Scalar];
644     fn deref(&self) -> &[crate::Scalar] {
645         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
646     }
647 }
648 
649 // Viewing
650 impl<'a> fmt::Display for VectorView<'a> {
651     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
652         write!(f, "VectorView({:?})", self.deref())
653     }
654 }
655 
656 // -----------------------------------------------------------------------------
657 // Vector Viewer Mutable
658 // -----------------------------------------------------------------------------
659 /// A mutable (host) view of a Vector with Deref to slice.
660 #[derive(Debug)]
661 pub struct VectorViewMut<'a> {
662     vec: &'a Vector<'a>,
663     array: *mut crate::Scalar,
664 }
665 
666 impl<'a> VectorViewMut<'a> {
667     /// Construct a VectorViewMut from a Vector reference
668     fn new(vec: &'a mut Vector) -> Self {
669         let mut ptr = std::ptr::null_mut();
670         unsafe {
671             bind_ceed::CeedVectorGetArray(
672                 vec.ptr,
673                 crate::MemType::Host as bind_ceed::CeedMemType,
674                 &mut ptr,
675             );
676         }
677         Self {
678             vec: vec,
679             array: ptr,
680         }
681     }
682 }
683 
684 // Destructor
685 impl<'a> Drop for VectorViewMut<'a> {
686     fn drop(&mut self) {
687         unsafe {
688             bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array);
689         }
690     }
691 }
692 
693 // Data access
694 impl<'a> Deref for VectorViewMut<'a> {
695     type Target = [crate::Scalar];
696     fn deref(&self) -> &[crate::Scalar] {
697         unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) }
698     }
699 }
700 
701 // Mutable data access
702 impl<'a> DerefMut for VectorViewMut<'a> {
703     fn deref_mut(&mut self) -> &mut [crate::Scalar] {
704         unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) }
705     }
706 }
707 
708 // Viewing
709 impl<'a> fmt::Display for VectorViewMut<'a> {
710     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
711         write!(f, "VectorViewMut({:?})", self.deref())
712     }
713 }
714 
715 // -----------------------------------------------------------------------------
716