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