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() -> libceed::Result<()> { 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() -> libceed::Result<()> { 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() -> libceed::Result<()> { 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 pub(crate) ptr: bind_ceed::CeedVector, 139 _lifeline: PhantomData<&'a ()>, 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() -> libceed::Result<()> { 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 { 209 ptr, 210 _lifeline: PhantomData, 211 }) 212 } 213 214 pub(crate) fn from_raw(ptr: bind_ceed::CeedVector) -> crate::Result<Self> { 215 Ok(Self { 216 ptr, 217 _lifeline: PhantomData, 218 }) 219 } 220 221 /// Create a Vector from a slice 222 /// 223 /// # arguments 224 /// 225 /// * `slice` - values to initialize vector with 226 /// 227 /// ``` 228 /// # use libceed::prelude::*; 229 /// # fn main() -> libceed::Result<()> { 230 /// # let ceed = libceed::Ceed::default_init(); 231 /// let vec = vector::Vector::from_slice(&ceed, &[1., 2., 3.])?; 232 /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 233 /// # Ok(()) 234 /// # } 235 /// ``` 236 pub fn from_slice(ceed: &'a crate::Ceed, v: &[crate::Scalar]) -> crate::Result<Self> { 237 let mut x = Self::create(ceed, v.len())?; 238 x.set_slice(v)?; 239 Ok(x) 240 } 241 242 /// Create a Vector from a mutable array reference 243 /// 244 /// # arguments 245 /// 246 /// * `slice` - values to initialize vector with 247 /// 248 /// ``` 249 /// # use libceed::prelude::*; 250 /// # fn main() -> libceed::Result<()> { 251 /// # let ceed = libceed::Ceed::default_init(); 252 /// let mut rust_vec = vec![1., 2., 3.]; 253 /// let vec = libceed::vector::Vector::from_array(&ceed, &mut rust_vec)?; 254 /// 255 /// assert_eq!(vec.length(), 3, "Incorrect length from slice"); 256 /// # Ok(()) 257 /// # } 258 /// ``` 259 pub fn from_array(ceed: &'a crate::Ceed, v: &mut [crate::Scalar]) -> crate::Result<Self> { 260 let x = Self::create(ceed, v.len())?; 261 let (host, user_pointer) = ( 262 crate::MemType::Host as bind_ceed::CeedMemType, 263 crate::CopyMode::UsePointer as bind_ceed::CeedCopyMode, 264 ); 265 let v = v.as_ptr() as *mut crate::Scalar; 266 let ierr = unsafe { bind_ceed::CeedVectorSetArray(x.ptr, host, user_pointer, v) }; 267 ceed.check_error(ierr)?; 268 Ok(x) 269 } 270 271 // Error handling 272 #[doc(hidden)] 273 fn check_error(&self, ierr: i32) -> crate::Result<i32> { 274 let mut ptr = std::ptr::null_mut(); 275 unsafe { 276 bind_ceed::CeedVectorGetCeed(self.ptr, &mut ptr); 277 } 278 crate::check_error(ptr, ierr) 279 } 280 281 /// Returns the length of a CeedVector 282 /// 283 /// ``` 284 /// # use libceed::prelude::*; 285 /// # fn main() -> libceed::Result<()> { 286 /// # let ceed = libceed::Ceed::default_init(); 287 /// let vec = ceed.vector(10)?; 288 /// 289 /// let n = vec.length(); 290 /// assert_eq!(n, 10, "Incorrect length"); 291 /// # Ok(()) 292 /// # } 293 /// ``` 294 pub fn length(&self) -> usize { 295 let mut n = 0; 296 unsafe { bind_ceed::CeedVectorGetLength(self.ptr, &mut n) }; 297 usize::try_from(n).unwrap() 298 } 299 300 /// Returns the length of a CeedVector 301 /// 302 /// ``` 303 /// # use libceed::prelude::*; 304 /// # fn main() -> libceed::Result<()> { 305 /// # let ceed = libceed::Ceed::default_init(); 306 /// let vec = ceed.vector(10)?; 307 /// assert_eq!(vec.len(), 10, "Incorrect length"); 308 /// # Ok(()) 309 /// # } 310 /// ``` 311 pub fn len(&self) -> usize { 312 self.length() 313 } 314 315 /// Set the CeedVector to a constant value 316 /// 317 /// # arguments 318 /// 319 /// * `val` - Value to be used 320 /// 321 /// ``` 322 /// # use libceed::prelude::*; 323 /// # fn main() -> libceed::Result<()> { 324 /// # let ceed = libceed::Ceed::default_init(); 325 /// let len = 10; 326 /// let mut vec = ceed.vector(len)?; 327 /// 328 /// let val = 42.0; 329 /// vec.set_value(val)?; 330 /// 331 /// vec.view()?.iter().for_each(|v| { 332 /// assert_eq!(*v, val, "Value not set correctly"); 333 /// }); 334 /// # Ok(()) 335 /// # } 336 /// ``` 337 pub fn set_value(&mut self, value: crate::Scalar) -> crate::Result<i32> { 338 let ierr = unsafe { bind_ceed::CeedVectorSetValue(self.ptr, value) }; 339 self.check_error(ierr) 340 } 341 342 /// Set values from a slice of the same length 343 /// 344 /// # arguments 345 /// 346 /// * `slice` - values to into self; length must match 347 /// 348 /// ``` 349 /// # use libceed::prelude::*; 350 /// # fn main() -> libceed::Result<()> { 351 /// # let ceed = libceed::Ceed::default_init(); 352 /// let mut vec = ceed.vector(4)?; 353 /// vec.set_slice(&[10., 11., 12., 13.])?; 354 /// 355 /// vec.view()?.iter().enumerate().for_each(|(i, v)| { 356 /// assert_eq!(*v, 10. + i as Scalar, "Slice not set correctly"); 357 /// }); 358 /// # Ok(()) 359 /// # } 360 /// ``` 361 pub fn set_slice(&mut self, slice: &[crate::Scalar]) -> crate::Result<i32> { 362 assert_eq!(self.length(), slice.len()); 363 let (host, copy_mode) = ( 364 crate::MemType::Host as bind_ceed::CeedMemType, 365 crate::CopyMode::CopyValues as bind_ceed::CeedCopyMode, 366 ); 367 let ierr = unsafe { 368 bind_ceed::CeedVectorSetArray( 369 self.ptr, 370 host, 371 copy_mode, 372 slice.as_ptr() as *mut crate::Scalar, 373 ) 374 }; 375 self.check_error(ierr) 376 } 377 378 /// Sync the CeedVector to a specified memtype 379 /// 380 /// # arguments 381 /// 382 /// * `mtype` - Memtype to be synced 383 /// 384 /// ``` 385 /// # use libceed::prelude::*; 386 /// # fn main() -> libceed::Result<()> { 387 /// # let ceed = libceed::Ceed::default_init(); 388 /// let len = 10; 389 /// let mut vec = ceed.vector(len)?; 390 /// 391 /// let val = 42.0; 392 /// vec.set_value(val); 393 /// vec.sync(MemType::Host)?; 394 /// 395 /// vec.view()?.iter().for_each(|v| { 396 /// assert_eq!(*v, val, "Value not set correctly"); 397 /// }); 398 /// # Ok(()) 399 /// # } 400 /// ``` 401 pub fn sync(&self, mtype: crate::MemType) -> crate::Result<i32> { 402 let ierr = 403 unsafe { bind_ceed::CeedVectorSyncArray(self.ptr, mtype as bind_ceed::CeedMemType) }; 404 self.check_error(ierr) 405 } 406 407 /// Create an immutable view 408 /// 409 /// ``` 410 /// # use libceed::prelude::*; 411 /// # fn main() -> libceed::Result<()> { 412 /// # let ceed = libceed::Ceed::default_init(); 413 /// let vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 414 /// 415 /// let v = vec.view()?; 416 /// assert_eq!(v[0..2], [10., 11.]); 417 /// 418 /// // It is valid to have multiple immutable views 419 /// let w = vec.view()?; 420 /// assert_eq!(v[1..], w[1..]); 421 /// # Ok(()) 422 /// # } 423 /// ``` 424 pub fn view(&self) -> crate::Result<VectorView> { 425 VectorView::new(self) 426 } 427 428 /// Create an mutable view 429 /// 430 /// ``` 431 /// # use libceed::prelude::*; 432 /// # fn main() -> libceed::Result<()> { 433 /// # let ceed = libceed::Ceed::default_init(); 434 /// let mut vec = ceed.vector_from_slice(&[10., 11., 12., 13.])?; 435 /// 436 /// { 437 /// let mut v = vec.view_mut()?; 438 /// v[2] = 9.; 439 /// } 440 /// 441 /// let w = vec.view()?; 442 /// assert_eq!(w[2], 9., "View did not mutate data"); 443 /// # Ok(()) 444 /// # } 445 /// ``` 446 pub fn view_mut(&mut self) -> crate::Result<VectorViewMut> { 447 VectorViewMut::new(self) 448 } 449 450 /// Return the norm of a CeedVector 451 /// 452 /// # arguments 453 /// 454 /// * `ntype` - Norm type One, Two, or Max 455 /// 456 /// ``` 457 /// # use libceed::prelude::*; 458 /// # fn main() -> libceed::Result<()> { 459 /// # let ceed = libceed::Ceed::default_init(); 460 /// let vec = ceed.vector_from_slice(&[1., 2., 3., 4.])?; 461 /// 462 /// let max_norm = vec.norm(NormType::Max)?; 463 /// assert_eq!(max_norm, 4.0, "Incorrect Max norm"); 464 /// 465 /// let l1_norm = vec.norm(NormType::One)?; 466 /// assert_eq!(l1_norm, 10., "Incorrect L1 norm"); 467 /// 468 /// let l2_norm = vec.norm(NormType::Two)?; 469 /// assert!((l2_norm - 5.477) < 1e-3, "Incorrect L2 norm"); 470 /// # Ok(()) 471 /// # } 472 /// ``` 473 pub fn norm(&self, ntype: crate::NormType) -> crate::Result<crate::Scalar> { 474 let mut res: crate::Scalar = 0.0; 475 let ierr = unsafe { 476 bind_ceed::CeedVectorNorm(self.ptr, ntype as bind_ceed::CeedNormType, &mut res) 477 }; 478 self.check_error(ierr)?; 479 Ok(res) 480 } 481 482 /// Compute x = alpha x for a CeedVector 483 /// 484 /// # arguments 485 /// 486 /// * `alpha` - scaling factor 487 /// 488 /// ``` 489 /// # use libceed::prelude::*; 490 /// # fn main() -> libceed::Result<()> { 491 /// # let ceed = libceed::Ceed::default_init(); 492 /// let mut vec = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 493 /// 494 /// vec = vec.scale(-1.0)?; 495 /// vec.view()?.iter().enumerate().for_each(|(i, &v)| { 496 /// assert_eq!(v, -(i as Scalar), "Value not set correctly"); 497 /// }); 498 /// # Ok(()) 499 /// # } 500 /// ``` 501 #[allow(unused_mut)] 502 pub fn scale(mut self, alpha: crate::Scalar) -> crate::Result<Self> { 503 let ierr = unsafe { bind_ceed::CeedVectorScale(self.ptr, alpha) }; 504 self.check_error(ierr)?; 505 Ok(self) 506 } 507 508 /// Compute y = alpha x + y for a pair of CeedVectors 509 /// 510 /// # arguments 511 /// 512 /// * `alpha` - scaling factor 513 /// * `x` - second vector, must be different than self 514 /// 515 /// ``` 516 /// # use libceed::prelude::*; 517 /// # fn main() -> libceed::Result<()> { 518 /// # let ceed = libceed::Ceed::default_init(); 519 /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 520 /// let mut y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 521 /// 522 /// y = y.axpy(-0.5, &x)?; 523 /// y.view()?.iter().enumerate().for_each(|(i, &v)| { 524 /// assert_eq!(v, (i as Scalar) / 2.0, "Value not set correctly"); 525 /// }); 526 /// # Ok(()) 527 /// # } 528 /// ``` 529 #[allow(unused_mut)] 530 pub fn axpy(mut self, alpha: crate::Scalar, x: &crate::Vector) -> crate::Result<Self> { 531 let ierr = unsafe { bind_ceed::CeedVectorAXPY(self.ptr, alpha, x.ptr) }; 532 self.check_error(ierr)?; 533 Ok(self) 534 } 535 536 /// Compute the pointwise multiplication w = x .* y for CeedVectors 537 /// 538 /// # arguments 539 /// 540 /// * `x` - first vector for product 541 /// * `y` - second vector for product 542 /// 543 /// ``` 544 /// # use libceed::prelude::*; 545 /// # fn main() -> libceed::Result<()> { 546 /// # let ceed = libceed::Ceed::default_init(); 547 /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 548 /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 549 /// let y = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 550 /// 551 /// w = w.pointwise_mult(&x, &y)?; 552 /// w.view()?.iter().enumerate().for_each(|(i, &v)| { 553 /// assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly"); 554 /// }); 555 /// # Ok(()) 556 /// # } 557 /// ``` 558 #[allow(unused_mut)] 559 pub fn pointwise_mult(mut self, x: &crate::Vector, y: &crate::Vector) -> crate::Result<Self> { 560 let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, x.ptr, y.ptr) }; 561 self.check_error(ierr)?; 562 Ok(self) 563 } 564 565 /// Compute the pointwise multiplication w = w .* x for CeedVectors 566 /// 567 /// # arguments 568 /// 569 /// * `x` - second vector for product 570 /// 571 /// ``` 572 /// # use libceed::prelude::*; 573 /// # fn main() -> libceed::Result<()> { 574 /// # let ceed = libceed::Ceed::default_init(); 575 /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 576 /// let x = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 577 /// 578 /// w = w.pointwise_scale(&x)?; 579 /// w.view()?.iter().enumerate().for_each(|(i, &v)| { 580 /// assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly"); 581 /// }); 582 /// # Ok(()) 583 /// # } 584 /// ``` 585 #[allow(unused_mut)] 586 pub fn pointwise_scale(mut self, x: &crate::Vector) -> crate::Result<Self> { 587 let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, x.ptr) }; 588 self.check_error(ierr)?; 589 Ok(self) 590 } 591 592 /// Compute the pointwise multiplication w = w .* w for a CeedVector 593 /// 594 /// ``` 595 /// # use libceed::prelude::*; 596 /// # fn main() -> libceed::Result<()> { 597 /// # let ceed = libceed::Ceed::default_init(); 598 /// let mut w = ceed.vector_from_slice(&[0., 1., 2., 3., 4.])?; 599 /// 600 /// w = w.pointwise_square()?; 601 /// w.view()?.iter().enumerate().for_each(|(i, &v)| { 602 /// assert_eq!(v, (i as Scalar).powf(2.0), "Value not set correctly"); 603 /// }); 604 /// # Ok(()) 605 /// # } 606 /// ``` 607 #[allow(unused_mut)] 608 pub fn pointwise_square(mut self) -> crate::Result<Self> { 609 let ierr = unsafe { bind_ceed::CeedVectorPointwiseMult(self.ptr, self.ptr, self.ptr) }; 610 self.check_error(ierr)?; 611 Ok(self) 612 } 613 } 614 615 // ----------------------------------------------------------------------------- 616 // Vector Viewer 617 // ----------------------------------------------------------------------------- 618 /// A (host) view of a Vector with Deref to slice. We can't make 619 /// Vector itself Deref to slice because we can't handle the drop to 620 /// call bind_ceed::CeedVectorRestoreArrayRead(). 621 #[derive(Debug)] 622 pub struct VectorView<'a> { 623 vec: &'a Vector<'a>, 624 array: *const crate::Scalar, 625 } 626 627 impl<'a> VectorView<'a> { 628 /// Construct a VectorView from a Vector reference 629 fn new(vec: &'a Vector) -> crate::Result<Self> { 630 let mut array = std::ptr::null(); 631 let ierr = unsafe { 632 bind_ceed::CeedVectorGetArrayRead( 633 vec.ptr, 634 crate::MemType::Host as bind_ceed::CeedMemType, 635 &mut array, 636 ) 637 }; 638 vec.check_error(ierr)?; 639 Ok(Self { 640 vec: vec, 641 array: array, 642 }) 643 } 644 } 645 646 // Destructor 647 impl<'a> Drop for VectorView<'a> { 648 fn drop(&mut self) { 649 unsafe { 650 bind_ceed::CeedVectorRestoreArrayRead(self.vec.ptr, &mut self.array); 651 } 652 } 653 } 654 655 // Data access 656 impl<'a> Deref for VectorView<'a> { 657 type Target = [crate::Scalar]; 658 fn deref(&self) -> &[crate::Scalar] { 659 unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) } 660 } 661 } 662 663 // Viewing 664 impl<'a> fmt::Display for VectorView<'a> { 665 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 666 write!(f, "VectorView({:?})", self.deref()) 667 } 668 } 669 670 // ----------------------------------------------------------------------------- 671 // Vector Viewer Mutable 672 // ----------------------------------------------------------------------------- 673 /// A mutable (host) view of a Vector with Deref to slice. 674 #[derive(Debug)] 675 pub struct VectorViewMut<'a> { 676 vec: &'a Vector<'a>, 677 array: *mut crate::Scalar, 678 } 679 680 impl<'a> VectorViewMut<'a> { 681 /// Construct a VectorViewMut from a Vector reference 682 fn new(vec: &'a mut Vector) -> crate::Result<Self> { 683 let mut ptr = std::ptr::null_mut(); 684 let ierr = unsafe { 685 bind_ceed::CeedVectorGetArray( 686 vec.ptr, 687 crate::MemType::Host as bind_ceed::CeedMemType, 688 &mut ptr, 689 ) 690 }; 691 vec.check_error(ierr)?; 692 Ok(Self { 693 vec: vec, 694 array: ptr, 695 }) 696 } 697 } 698 699 // Destructor 700 impl<'a> Drop for VectorViewMut<'a> { 701 fn drop(&mut self) { 702 unsafe { 703 bind_ceed::CeedVectorRestoreArray(self.vec.ptr, &mut self.array); 704 } 705 } 706 } 707 708 // Data access 709 impl<'a> Deref for VectorViewMut<'a> { 710 type Target = [crate::Scalar]; 711 fn deref(&self) -> &[crate::Scalar] { 712 unsafe { std::slice::from_raw_parts(self.array, self.vec.len()) } 713 } 714 } 715 716 // Mutable data access 717 impl<'a> DerefMut for VectorViewMut<'a> { 718 fn deref_mut(&mut self) -> &mut [crate::Scalar] { 719 unsafe { std::slice::from_raw_parts_mut(self.array, self.vec.len()) } 720 } 721 } 722 723 // Viewing 724 impl<'a> fmt::Display for VectorViewMut<'a> { 725 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 726 write!(f, "VectorViewMut({:?})", self.deref()) 727 } 728 } 729 730 // ----------------------------------------------------------------------------- 731