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 #include <ceed-impl.h> 18 #include <ceed-backend.h> 19 20 /// @file 21 /// Implementation of backend CeedTensorContract interfaces 22 /// 23 /// @addtogroup CeedBasis 24 /// @{ 25 26 /** 27 @brief Create a CeedTensorContract object for a CeedBasis 28 29 @param ceed A Ceed object where the CeedTensorContract will be created 30 @param basis CeedBasis for which the tensor contraction will be used 31 @param[out] contract Address of the variable where the newly created 32 CeedTensorContract will be stored. 33 34 @return An error code: 0 - success, otherwise - failure 35 36 @ref Advanced 37 **/ 38 int CeedTensorContractCreate(Ceed ceed, CeedBasis basis, 39 CeedTensorContract *contract) { 40 int ierr; 41 42 if (!ceed->TensorContractCreate) { 43 Ceed delegate; 44 ierr = CeedGetObjectDelegate(ceed, &delegate, "TensorContract"); 45 CeedChk(ierr); 46 47 if (!delegate) 48 // LCOV_EXCL_START 49 return CeedError(ceed, 1, 50 "Backend does not support TensorContractCreate"); 51 // LCOV_EXCL_STOP 52 53 ierr = CeedTensorContractCreate(delegate, basis, contract); 54 CeedChk(ierr); 55 return 0; 56 } 57 58 ierr = CeedCalloc(1,contract); CeedChk(ierr); 59 60 (*contract)->ceed = ceed; 61 ceed->refcount++; 62 ierr = ceed->TensorContractCreate(basis, *contract); 63 CeedChk(ierr); 64 return 0; 65 }; 66 67 /** 68 @brief Apply tensor contraction 69 70 Contracts on the middle index 71 NOTRANSPOSE: v_ajc = t_jb u_abc 72 TRANSPOSE: v_ajc = t_bj u_abc 73 If add != 0, "=" is replaced by "+=" 74 75 @param contract CeedTensorContract to use 76 @param A First index of u, v 77 @param B Middle index of u, one index of t 78 @param C Last index of u, v 79 @param J Middle index of v, one index of t 80 @param[in] t Tensor array to contract against 81 @param tmode Transpose mode for t, \ref CEED_NOTRANSPOSE for t_jb 82 \ref CEED_TRANSPOSE for t_bj 83 @param add Add mode 84 @param[in] u Input array 85 @param[out] v Output array 86 87 @return An error code: 0 - success, otherwise - failure 88 89 @ref Advanced 90 **/ 91 int CeedTensorContractApply(CeedTensorContract contract, CeedInt A, CeedInt B, 92 CeedInt C, CeedInt J, const CeedScalar *restrict t, 93 CeedTransposeMode tmode, const CeedInt add, 94 const CeedScalar *restrict u, 95 CeedScalar *restrict v) { 96 int ierr; 97 98 ierr = contract->Apply(contract, A, B, C, J, t, tmode, add, u, v); 99 CeedChk(ierr); 100 return 0; 101 }; 102 103 /** 104 @brief Get Ceed associated with a CeedTensorContract 105 106 @param contract CeedTensorContract 107 @param[out] ceed Variable to store Ceed 108 109 @return An error code: 0 - success, otherwise - failure 110 111 @ref Advanced 112 **/ 113 int CeedTensorContractGetCeed(CeedTensorContract contract, Ceed *ceed) { 114 *ceed = contract->ceed; 115 116 return 0; 117 }; 118 119 /** 120 @brief Get backend data of a CeedTensorContract 121 122 @param contract CeedTensorContract 123 @param[out] data Variable to store data 124 125 @return An error code: 0 - success, otherwise - failure 126 127 @ref Advanced 128 **/ 129 int CeedTensorContractGetData(CeedTensorContract contract, void* *data) { 130 *data = contract->data; 131 return 0; 132 } 133 134 /** 135 @brief Set backend data of a CeedTensorContract 136 137 @param[out] contract CeedTensorContract 138 @param data Data to set 139 140 @return An error code: 0 - success, otherwise - failure 141 142 @ref Advanced 143 **/ 144 int CeedTensorContractSetData(CeedTensorContract contract, void* *data) { 145 contract->data = *data; 146 return 0; 147 } 148 149 /** 150 @brief Destroy a CeedTensorContract 151 152 @param contract CeedTensorContract to destroy 153 154 @return An error code: 0 - success, otherwise - failure 155 156 @ref Advanced 157 **/ 158 int CeedTensorContractDestroy(CeedTensorContract *contract) { 159 int ierr; 160 161 if (!*contract || --(*contract)->refcount > 0) return 0; 162 if ((*contract)->Destroy) { 163 ierr = (*contract)->Destroy(*contract); CeedChk(ierr); 164 } 165 ierr = CeedDestroy(&(*contract)->ceed); CeedChk(ierr); 166 ierr = CeedFree(contract); CeedChk(ierr); 167 return 0; 168 }; 169 170 /// @} 171