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