xref: /libCEED/interface/ceed-vector.c (revision 171f8ca999a3018c223f1fa900e2575333ef449d)
10436c2adSjeremylt // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
20436c2adSjeremylt // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
30436c2adSjeremylt // reserved. See files LICENSE and NOTICE for details.
40436c2adSjeremylt //
50436c2adSjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
60436c2adSjeremylt // libraries and APIs for efficient high-order finite element and spectral
70436c2adSjeremylt // element discretizations for exascale applications. For more information and
80436c2adSjeremylt // source code availability see http://github.com/ceed.
90436c2adSjeremylt //
100436c2adSjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
110436c2adSjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
120436c2adSjeremylt // of Science and the National Nuclear Security Administration) responsible for
130436c2adSjeremylt // the planning and preparation of a capable exascale ecosystem, including
140436c2adSjeremylt // software, applications, hardware, advanced system engineering and early
150436c2adSjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
160436c2adSjeremylt 
170436c2adSjeremylt #include <ceed-impl.h>
180436c2adSjeremylt #include <ceed-backend.h>
19547d9b97Sjeremylt #include <math.h>
200436c2adSjeremylt 
210436c2adSjeremylt /// @cond DOXYGEN_SKIP
220436c2adSjeremylt static struct CeedVector_private ceed_vector_active;
230436c2adSjeremylt static struct CeedVector_private ceed_vector_none;
240436c2adSjeremylt /// @endcond
250436c2adSjeremylt 
260436c2adSjeremylt /// @file
270436c2adSjeremylt /// Implementation of public CeedVector interfaces
280436c2adSjeremylt ///
290436c2adSjeremylt /// @addtogroup CeedVector
300436c2adSjeremylt /// @{
310436c2adSjeremylt 
320436c2adSjeremylt /**
330436c2adSjeremylt   @brief Create a CeedVector of the specified length (does not allocate memory)
340436c2adSjeremylt 
350436c2adSjeremylt   @param ceed      Ceed object where the CeedVector will be created
360436c2adSjeremylt   @param length    Length of vector
370436c2adSjeremylt   @param[out] vec  Address of the variable where the newly created
380436c2adSjeremylt                      CeedVector will be stored
390436c2adSjeremylt 
400436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
410436c2adSjeremylt 
420436c2adSjeremylt   @ref Basic
430436c2adSjeremylt **/
440436c2adSjeremylt int CeedVectorCreate(Ceed ceed, CeedInt length, CeedVector *vec) {
450436c2adSjeremylt   int ierr;
460436c2adSjeremylt 
470436c2adSjeremylt   if (!ceed->VectorCreate) {
480436c2adSjeremylt     Ceed delegate;
490436c2adSjeremylt     ierr = CeedGetObjectDelegate(ceed, &delegate, "Vector"); CeedChk(ierr);
500436c2adSjeremylt 
510436c2adSjeremylt     if (!delegate)
520436c2adSjeremylt       // LCOV_EXCL_START
530436c2adSjeremylt       return CeedError(ceed, 1, "Backend does not support VectorCreate");
540436c2adSjeremylt     // LCOV_EXCL_STOP
550436c2adSjeremylt 
560436c2adSjeremylt     ierr = CeedVectorCreate(delegate, length, vec); CeedChk(ierr);
570436c2adSjeremylt     return 0;
580436c2adSjeremylt   }
590436c2adSjeremylt 
600436c2adSjeremylt   ierr = CeedCalloc(1,vec); CeedChk(ierr);
610436c2adSjeremylt   (*vec)->ceed = ceed;
620436c2adSjeremylt   ceed->refcount++;
630436c2adSjeremylt   (*vec)->refcount = 1;
640436c2adSjeremylt   (*vec)->length = length;
650436c2adSjeremylt   (*vec)->state = 0;
660436c2adSjeremylt   ierr = ceed->VectorCreate(length, *vec); CeedChk(ierr);
670436c2adSjeremylt   return 0;
680436c2adSjeremylt }
690436c2adSjeremylt 
700436c2adSjeremylt /**
710436c2adSjeremylt   @brief Set the array used by a CeedVector, freeing any previously allocated
720436c2adSjeremylt     array if applicable
730436c2adSjeremylt 
740436c2adSjeremylt   @param vec   CeedVector
750436c2adSjeremylt   @param mtype Memory type of the array being passed
760436c2adSjeremylt   @param cmode Copy mode for the array
770436c2adSjeremylt   @param array Array to be used, or NULL with CEED_COPY_VALUES to have the
780436c2adSjeremylt                  library allocate
790436c2adSjeremylt 
800436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
810436c2adSjeremylt 
820436c2adSjeremylt   @ref Basic
830436c2adSjeremylt **/
840436c2adSjeremylt int CeedVectorSetArray(CeedVector vec, CeedMemType mtype, CeedCopyMode cmode,
850436c2adSjeremylt                        CeedScalar *array) {
860436c2adSjeremylt   int ierr;
870436c2adSjeremylt 
880436c2adSjeremylt   if (!vec->SetArray)
890436c2adSjeremylt     // LCOV_EXCL_START
900436c2adSjeremylt     return CeedError(vec->ceed, 1, "Backend does not support VectorSetArray");
910436c2adSjeremylt   // LCOV_EXCL_STOP
920436c2adSjeremylt 
930436c2adSjeremylt   if (vec->state % 2 == 1)
940436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the "
950436c2adSjeremylt                      "access lock is already in use");
960436c2adSjeremylt 
970436c2adSjeremylt   if (vec->numreaders > 0)
980436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, a "
990436c2adSjeremylt                      "process has read access");
1000436c2adSjeremylt 
1010436c2adSjeremylt   ierr = vec->SetArray(vec, mtype, cmode, array); CeedChk(ierr);
1020436c2adSjeremylt   vec->state += 2;
1030436c2adSjeremylt 
1040436c2adSjeremylt   return 0;
1050436c2adSjeremylt }
1060436c2adSjeremylt 
1070436c2adSjeremylt /**
1080436c2adSjeremylt   @brief Set the CeedVector to a constant value
1090436c2adSjeremylt 
1100436c2adSjeremylt   @param vec        CeedVector
1110436c2adSjeremylt   @param[in] value  Value to be used
1120436c2adSjeremylt 
1130436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
1140436c2adSjeremylt 
1150436c2adSjeremylt   @ref Basic
1160436c2adSjeremylt **/
1170436c2adSjeremylt int CeedVectorSetValue(CeedVector vec, CeedScalar value) {
1180436c2adSjeremylt   int ierr;
1190436c2adSjeremylt 
1200436c2adSjeremylt   if (vec->state % 2 == 1)
1210436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the "
1220436c2adSjeremylt                      "access lock is already in use");
1230436c2adSjeremylt 
1240436c2adSjeremylt   if (vec->SetValue) {
1250436c2adSjeremylt     ierr = vec->SetValue(vec, value); CeedChk(ierr);
1260436c2adSjeremylt   } else {
1270436c2adSjeremylt     CeedScalar *array;
1280436c2adSjeremylt     ierr = CeedVectorGetArray(vec, CEED_MEM_HOST, &array); CeedChk(ierr);
1290436c2adSjeremylt     for (int i=0; i<vec->length; i++) array[i] = value;
1300436c2adSjeremylt     ierr = CeedVectorRestoreArray(vec, &array); CeedChk(ierr);
1310436c2adSjeremylt   }
1320436c2adSjeremylt 
1330436c2adSjeremylt   vec->state += 2;
1340436c2adSjeremylt 
1350436c2adSjeremylt   return 0;
1360436c2adSjeremylt }
1370436c2adSjeremylt 
1380436c2adSjeremylt /**
1390436c2adSjeremylt   @brief Sync the CeedVector to a specified memtype
1400436c2adSjeremylt 
1410436c2adSjeremylt   @param vec        CeedVector
1420436c2adSjeremylt   @param mtype      Memtype to be synced
1430436c2adSjeremylt 
1440436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
1450436c2adSjeremylt 
1460436c2adSjeremylt   @ref Basic
1470436c2adSjeremylt **/
1480436c2adSjeremylt int CeedVectorSyncArray(CeedVector vec, CeedMemType mtype) {
1490436c2adSjeremylt   int ierr;
1500436c2adSjeremylt 
1510436c2adSjeremylt   if (vec->state % 2 == 1)
1520436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot sync CeedVector, the access lock is "
1530436c2adSjeremylt                      "already in use");
1540436c2adSjeremylt 
1550436c2adSjeremylt   if (vec->SyncArray) {
1560436c2adSjeremylt     ierr = vec->SyncArray(vec, mtype); CeedChk(ierr);
1570436c2adSjeremylt   } else {
1580436c2adSjeremylt     const CeedScalar *array;
1590436c2adSjeremylt     ierr = CeedVectorGetArrayRead(vec, mtype, &array); CeedChk(ierr);
1600436c2adSjeremylt     ierr = CeedVectorRestoreArrayRead(vec, &array); CeedChk(ierr);
1610436c2adSjeremylt   }
1620436c2adSjeremylt 
1630436c2adSjeremylt   return 0;
1640436c2adSjeremylt }
1650436c2adSjeremylt 
1660436c2adSjeremylt /**
1670436c2adSjeremylt   @brief Get read/write access to a CeedVector via the specified memory type
1680436c2adSjeremylt 
1690436c2adSjeremylt   @param vec        CeedVector to access
1700436c2adSjeremylt   @param mtype      Memory type on which to access the array.  If the backend
1710436c2adSjeremylt                     uses a different memory type, this will perform a copy and
1720436c2adSjeremylt                     CeedVectorRestoreArray() will copy back.
1730436c2adSjeremylt   @param[out] array Array on memory type mtype
1740436c2adSjeremylt 
1750436c2adSjeremylt   @note The CeedVectorGetArray* and CeedVectorRestoreArray* functions provide
1760436c2adSjeremylt     access to array pointers in the desired memory space. Pairing get/restore
1770436c2adSjeremylt     allows the Vector to track access, thus knowing if norms or other
1780436c2adSjeremylt     operations may need to be recomputed.
1790436c2adSjeremylt 
1800436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
1810436c2adSjeremylt 
1820436c2adSjeremylt   @ref Basic
1830436c2adSjeremylt **/
1840436c2adSjeremylt int CeedVectorGetArray(CeedVector vec, CeedMemType mtype, CeedScalar **array) {
1850436c2adSjeremylt   int ierr;
1860436c2adSjeremylt 
1870436c2adSjeremylt   if (!vec->GetArray)
1880436c2adSjeremylt     // LCOV_EXCL_START
1890436c2adSjeremylt     return CeedError(vec->ceed, 1, "Backend does not support GetArray");
1900436c2adSjeremylt   // LCOV_EXCL_STOP
1910436c2adSjeremylt 
1920436c2adSjeremylt   if (vec->state % 2 == 1)
1930436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, the "
1940436c2adSjeremylt                      "access lock is already in use");
1950436c2adSjeremylt 
1960436c2adSjeremylt   if (vec->numreaders > 0)
1970436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector array access, a "
1980436c2adSjeremylt                      "process has read access");
1990436c2adSjeremylt 
2000436c2adSjeremylt   ierr = vec->GetArray(vec, mtype, array); CeedChk(ierr);
2010436c2adSjeremylt   vec->state += 1;
2020436c2adSjeremylt 
2030436c2adSjeremylt   return 0;
2040436c2adSjeremylt }
2050436c2adSjeremylt 
2060436c2adSjeremylt /**
2070436c2adSjeremylt   @brief Get read-only access to a CeedVector via the specified memory type
2080436c2adSjeremylt 
2090436c2adSjeremylt   @param vec        CeedVector to access
2100436c2adSjeremylt   @param mtype      Memory type on which to access the array.  If the backend
2110436c2adSjeremylt                     uses a different memory type, this will perform a copy
2120436c2adSjeremylt                     (possibly cached).
2130436c2adSjeremylt   @param[out] array Array on memory type mtype
2140436c2adSjeremylt 
2150436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
2160436c2adSjeremylt 
2170436c2adSjeremylt   @ref Basic
2180436c2adSjeremylt **/
2190436c2adSjeremylt int CeedVectorGetArrayRead(CeedVector vec, CeedMemType mtype,
2200436c2adSjeremylt                            const CeedScalar **array) {
2210436c2adSjeremylt   int ierr;
2220436c2adSjeremylt 
2230436c2adSjeremylt   if (!vec->GetArrayRead)
2240436c2adSjeremylt     // LCOV_EXCL_START
2250436c2adSjeremylt     return CeedError(vec->ceed, 1, "Backend does not support GetArrayRead");
2260436c2adSjeremylt   // LCOV_EXCL_STOP
2270436c2adSjeremylt 
2280436c2adSjeremylt   if (vec->state % 2 == 1)
2290436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot grant CeedVector read-only array "
2300436c2adSjeremylt                      "access, the access lock is already in use");
2310436c2adSjeremylt 
2320436c2adSjeremylt   ierr = vec->GetArrayRead(vec, mtype, array); CeedChk(ierr);
2330436c2adSjeremylt   vec->numreaders++;
2340436c2adSjeremylt 
2350436c2adSjeremylt   return 0;
2360436c2adSjeremylt }
2370436c2adSjeremylt 
2380436c2adSjeremylt /**
2390436c2adSjeremylt   @brief Restore an array obtained using CeedVectorGetArray()
2400436c2adSjeremylt 
2410436c2adSjeremylt   @param vec     CeedVector to restore
2420436c2adSjeremylt   @param array   Array of vector data
2430436c2adSjeremylt 
2440436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
2450436c2adSjeremylt 
2460436c2adSjeremylt   @ref Basic
2470436c2adSjeremylt **/
2480436c2adSjeremylt int CeedVectorRestoreArray(CeedVector vec, CeedScalar **array) {
2490436c2adSjeremylt   int ierr;
2500436c2adSjeremylt 
2510436c2adSjeremylt   if (!vec->RestoreArray)
2520436c2adSjeremylt     // LCOV_EXCL_START
2530436c2adSjeremylt     return CeedError(vec->ceed, 1, "Backend does not support RestoreArray");
2540436c2adSjeremylt   // LCOV_EXCL_STOP
2550436c2adSjeremylt 
2560436c2adSjeremylt   if (vec->state % 2 != 1)
2570436c2adSjeremylt     return CeedError(vec->ceed, 1, "Cannot restore CeedVector array access, "
2580436c2adSjeremylt                      "access was not granted");
2590436c2adSjeremylt 
2600436c2adSjeremylt   ierr = vec->RestoreArray(vec); CeedChk(ierr);
2610436c2adSjeremylt   *array = NULL;
2620436c2adSjeremylt   vec->state += 1;
2630436c2adSjeremylt 
2640436c2adSjeremylt   return 0;
2650436c2adSjeremylt }
2660436c2adSjeremylt 
2670436c2adSjeremylt /**
2680436c2adSjeremylt   @brief Restore an array obtained using CeedVectorGetArrayRead()
2690436c2adSjeremylt 
2700436c2adSjeremylt   @param vec     CeedVector to restore
2710436c2adSjeremylt   @param array   Array of vector data
2720436c2adSjeremylt 
2730436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
2740436c2adSjeremylt 
2750436c2adSjeremylt   @ref Basic
2760436c2adSjeremylt **/
2770436c2adSjeremylt int CeedVectorRestoreArrayRead(CeedVector vec, const CeedScalar **array) {
2780436c2adSjeremylt   int ierr;
2790436c2adSjeremylt 
2800436c2adSjeremylt   if (!vec->RestoreArrayRead)
2810436c2adSjeremylt     // LCOV_EXCL_START
2820436c2adSjeremylt     return CeedError(vec->ceed, 1, "Backend does not support RestoreArrayRead");
2830436c2adSjeremylt   // LCOV_EXCL_STOP
2840436c2adSjeremylt 
2850436c2adSjeremylt   ierr = vec->RestoreArrayRead(vec); CeedChk(ierr);
2860436c2adSjeremylt   *array = NULL;
2870436c2adSjeremylt   vec->numreaders--;
2880436c2adSjeremylt 
2890436c2adSjeremylt   return 0;
2900436c2adSjeremylt }
2910436c2adSjeremylt 
2920436c2adSjeremylt /**
2930436c2adSjeremylt   @brief View a CeedVector
2940436c2adSjeremylt 
2950436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
2960436c2adSjeremylt 
2970436c2adSjeremylt   @ref Utility
2980436c2adSjeremylt **/
2990436c2adSjeremylt int CeedVectorView(CeedVector vec, const char *fpfmt, FILE *stream) {
3000436c2adSjeremylt   const CeedScalar *x;
3010436c2adSjeremylt 
3020436c2adSjeremylt   int ierr = CeedVectorGetArrayRead(vec, CEED_MEM_HOST, &x); CeedChk(ierr);
3030436c2adSjeremylt 
3040436c2adSjeremylt   char fmt[1024];
3050436c2adSjeremylt   fprintf(stream, "CeedVector length %ld\n", (long)vec->length);
3060436c2adSjeremylt   snprintf(fmt, sizeof fmt, "  %s\n", fpfmt ? fpfmt : "%g");
3070436c2adSjeremylt   for (CeedInt i=0; i<vec->length; i++)
3080436c2adSjeremylt     fprintf(stream, fmt, x[i]);
3090436c2adSjeremylt 
3100436c2adSjeremylt   ierr = CeedVectorRestoreArrayRead(vec, &x); CeedChk(ierr);
3110436c2adSjeremylt 
3120436c2adSjeremylt   return 0;
3130436c2adSjeremylt }
3140436c2adSjeremylt 
3150436c2adSjeremylt /**
3160436c2adSjeremylt   @brief Get the Ceed associated with a CeedVector
3170436c2adSjeremylt 
3180436c2adSjeremylt   @param vec           CeedVector to retrieve state
3190436c2adSjeremylt   @param[out] ceed     Variable to store ceed
3200436c2adSjeremylt 
3210436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
3220436c2adSjeremylt 
3230436c2adSjeremylt   @ref Advanced
3240436c2adSjeremylt **/
3250436c2adSjeremylt int CeedVectorGetCeed(CeedVector vec, Ceed *ceed) {
3260436c2adSjeremylt   *ceed = vec->ceed;
3270436c2adSjeremylt   return 0;
3280436c2adSjeremylt }
3290436c2adSjeremylt 
3300436c2adSjeremylt /**
3310436c2adSjeremylt   @brief Get the length of a CeedVector
3320436c2adSjeremylt 
3330436c2adSjeremylt   @param vec           CeedVector to retrieve length
3340436c2adSjeremylt   @param[out] length   Variable to store length
3350436c2adSjeremylt 
3360436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
3370436c2adSjeremylt 
3380436c2adSjeremylt   @ref Advanced
3390436c2adSjeremylt **/
3400436c2adSjeremylt int CeedVectorGetLength(CeedVector vec, CeedInt *length) {
3410436c2adSjeremylt   *length = vec->length;
3420436c2adSjeremylt   return 0;
3430436c2adSjeremylt }
3440436c2adSjeremylt 
3450436c2adSjeremylt /**
346*171f8ca9Sjeremylt   @brief Get the norm of a CeedVector.
347*171f8ca9Sjeremylt 
348*171f8ca9Sjeremylt   Note: This operation is local to the CeedVector. This function will likely
349*171f8ca9Sjeremylt           not provide the desired results for the norm of the libCEED portion
350*171f8ca9Sjeremylt           of a parallel vector or a CeedVector with duplicated or hanging nodes.
351547d9b97Sjeremylt 
352547d9b97Sjeremylt   @param vec           CeedVector to retrieve maximum value
353547d9b97Sjeremylt   @param type          Norm type CEED_NORM_1, CEED_NORM_2, or CEED_NORM_MAX
354547d9b97Sjeremylt   @param[out] norm     Variable to store norm value
355547d9b97Sjeremylt 
356547d9b97Sjeremylt   @return An error code: 0 - success, otherwise - failure
357547d9b97Sjeremylt 
358547d9b97Sjeremylt   @ref Advanced
359547d9b97Sjeremylt **/
360547d9b97Sjeremylt int CeedVectorNorm(CeedVector vec, CeedNormType type, CeedScalar *norm) {
361547d9b97Sjeremylt   int ierr;
362547d9b97Sjeremylt 
363547d9b97Sjeremylt   // Backend impl for GPU, if added
364547d9b97Sjeremylt   if (vec->Norm) {
365547d9b97Sjeremylt     ierr = vec->Norm(vec, type, norm); CeedChk(ierr);
366547d9b97Sjeremylt     return 0;
367547d9b97Sjeremylt   }
368547d9b97Sjeremylt 
369547d9b97Sjeremylt   const CeedScalar *array;
370547d9b97Sjeremylt   ierr = CeedVectorGetArrayRead(vec, CEED_MEM_HOST, &array); CeedChk(ierr);
371547d9b97Sjeremylt 
372547d9b97Sjeremylt   *norm = 0.;
373547d9b97Sjeremylt   switch (type) {
374547d9b97Sjeremylt   case CEED_NORM_1:
375547d9b97Sjeremylt     for (int i=0; i<vec->length; i++) {
376547d9b97Sjeremylt       *norm += fabs(array[i]);
377547d9b97Sjeremylt     }
378547d9b97Sjeremylt     break;
379547d9b97Sjeremylt   case CEED_NORM_2:
380547d9b97Sjeremylt     for (int i=0; i<vec->length; i++) {
381547d9b97Sjeremylt       *norm += fabs(array[i])*fabs(array[i]);
382547d9b97Sjeremylt     }
383547d9b97Sjeremylt     break;
384547d9b97Sjeremylt   case CEED_NORM_MAX:
385547d9b97Sjeremylt     for (int i=0; i<vec->length; i++) {
386547d9b97Sjeremylt       const CeedScalar absi = fabs(array[i]);
387547d9b97Sjeremylt       *norm = *norm > absi ? *norm : absi;
388547d9b97Sjeremylt     }
389547d9b97Sjeremylt   }
390547d9b97Sjeremylt   if (type == CEED_NORM_2)
391547d9b97Sjeremylt     *norm = sqrt(*norm);
392547d9b97Sjeremylt 
393547d9b97Sjeremylt   ierr = CeedVectorRestoreArrayRead(vec, &array); CeedChk(ierr);
394547d9b97Sjeremylt 
395547d9b97Sjeremylt   return 0;
396547d9b97Sjeremylt }
397547d9b97Sjeremylt 
398547d9b97Sjeremylt /**
3990436c2adSjeremylt   @brief Get the state of a CeedVector
4000436c2adSjeremylt 
4010436c2adSjeremylt   @param vec           CeedVector to retrieve state
4020436c2adSjeremylt   @param[out] state    Variable to store state
4030436c2adSjeremylt 
4040436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
4050436c2adSjeremylt 
4060436c2adSjeremylt   @ref Advanced
4070436c2adSjeremylt **/
4080436c2adSjeremylt int CeedVectorGetState(CeedVector vec, uint64_t *state) {
4090436c2adSjeremylt   *state = vec->state;
4100436c2adSjeremylt   return 0;
4110436c2adSjeremylt }
4120436c2adSjeremylt 
4130436c2adSjeremylt /**
4140436c2adSjeremylt   @brief Get the backend data of a CeedVector
4150436c2adSjeremylt 
4160436c2adSjeremylt   @param vec           CeedVector to retrieve state
4170436c2adSjeremylt   @param[out] data     Variable to store data
4180436c2adSjeremylt 
4190436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
4200436c2adSjeremylt 
4210436c2adSjeremylt   @ref Advanced
4220436c2adSjeremylt **/
4230436c2adSjeremylt int CeedVectorGetData(CeedVector vec, void **data) {
4240436c2adSjeremylt   *data = vec->data;
4250436c2adSjeremylt   return 0;
4260436c2adSjeremylt }
4270436c2adSjeremylt 
4280436c2adSjeremylt /**
4290436c2adSjeremylt   @brief Set the backend data of a CeedVector
4300436c2adSjeremylt 
4310436c2adSjeremylt   @param[out] vec     CeedVector to retrieve state
4320436c2adSjeremylt   @param data         Data to set
4330436c2adSjeremylt 
4340436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
4350436c2adSjeremylt 
4360436c2adSjeremylt   @ref Advanced
4370436c2adSjeremylt **/
4380436c2adSjeremylt int CeedVectorSetData(CeedVector vec, void **data) {
4390436c2adSjeremylt   vec->data = *data;
4400436c2adSjeremylt   return 0;
4410436c2adSjeremylt }
4420436c2adSjeremylt 
4430436c2adSjeremylt /**
4440436c2adSjeremylt   @brief Add a refrence to a CeedVector
4450436c2adSjeremylt 
4460436c2adSjeremylt   @param[out] vec     CeedVector to increment refrence counter
4470436c2adSjeremylt 
4480436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
4490436c2adSjeremylt 
4500436c2adSjeremylt   @ref Advanced
4510436c2adSjeremylt **/
4520436c2adSjeremylt int CeedVectorAddReference(CeedVector vec) {
4530436c2adSjeremylt   vec->refcount++;
4540436c2adSjeremylt   return 0;
4550436c2adSjeremylt }
4560436c2adSjeremylt 
4570436c2adSjeremylt /**
4580436c2adSjeremylt   @brief Destroy a CeedVector
4590436c2adSjeremylt 
4600436c2adSjeremylt   @param vec   CeedVector to destroy
4610436c2adSjeremylt 
4620436c2adSjeremylt   @return An error code: 0 - success, otherwise - failure
4630436c2adSjeremylt 
4640436c2adSjeremylt   @ref Basic
4650436c2adSjeremylt **/
4660436c2adSjeremylt int CeedVectorDestroy(CeedVector *vec) {
4670436c2adSjeremylt   int ierr;
4680436c2adSjeremylt 
4690436c2adSjeremylt   if (!*vec || --(*vec)->refcount > 0)
4700436c2adSjeremylt     return 0;
4710436c2adSjeremylt 
4720436c2adSjeremylt   if ((*vec) && ((*vec)->state % 2) == 1)
4730436c2adSjeremylt     return CeedError((*vec)->ceed, 1, "Cannot destroy CeedVector, the access "
4740436c2adSjeremylt                      "lock is in use");
4750436c2adSjeremylt 
4760436c2adSjeremylt   if ((*vec)->Destroy) {
4770436c2adSjeremylt     ierr = (*vec)->Destroy(*vec); CeedChk(ierr);
4780436c2adSjeremylt   }
4790436c2adSjeremylt 
4800436c2adSjeremylt   ierr = CeedDestroy(&(*vec)->ceed); CeedChk(ierr);
4810436c2adSjeremylt   ierr = CeedFree(vec); CeedChk(ierr);
4820436c2adSjeremylt 
4830436c2adSjeremylt   return 0;
4840436c2adSjeremylt }
4850436c2adSjeremylt 
4860436c2adSjeremylt /// @cond DOXYGEN_SKIP
4870436c2adSjeremylt // Indicate that vector will be provided as an explicit argument to
4880436c2adSjeremylt //   CeedOperatorApply().
4890436c2adSjeremylt CeedVector CEED_VECTOR_ACTIVE = &ceed_vector_active;
4900436c2adSjeremylt 
4910436c2adSjeremylt // Indicate that no vector is applicable (i.e., for CEED_EVAL_WEIGHTS).
4920436c2adSjeremylt CeedVector CEED_VECTOR_NONE = &ceed_vector_none;
4930436c2adSjeremylt /// @endcond
4940436c2adSjeremylt /// @}
495