1 // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC. 2 // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707. 3 // All Rights 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/ceed.h> 18 #include <ceed/backend.h> 19 #include <string.h> 20 #include "ceed-ref.h" 21 22 //------------------------------------------------------------------------------ 23 // Has Valid Array 24 //------------------------------------------------------------------------------ 25 static int CeedVectorHasValidArray_Ref(CeedVector vec, bool *has_valid_array) { 26 int ierr; 27 CeedVector_Ref *impl; 28 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 29 30 *has_valid_array = !!impl->array; 31 32 return CEED_ERROR_SUCCESS; 33 } 34 35 //------------------------------------------------------------------------------ 36 // Check if has borrowed array of given type 37 //------------------------------------------------------------------------------ 38 static inline int CeedVectorHasBorrowedArrayOfType_Ref(const CeedVector vec, 39 CeedMemType mem_type, bool *has_borrowed_array_of_type) { 40 int ierr; 41 CeedVector_Ref *impl; 42 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 43 Ceed ceed; 44 ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 45 46 switch (mem_type) { 47 case CEED_MEM_HOST: 48 *has_borrowed_array_of_type = !!impl->array_borrowed; 49 break; 50 default: 51 // LCOV_EXCL_START 52 return CeedError(ceed, CEED_ERROR_BACKEND, 53 "Can only set HOST memory for this backend"); 54 // LCOV_EXCL_STOP 55 break; 56 } 57 58 return CEED_ERROR_SUCCESS; 59 } 60 61 //------------------------------------------------------------------------------ 62 // Vector Set Array 63 //------------------------------------------------------------------------------ 64 static int CeedVectorSetArray_Ref(CeedVector vec, CeedMemType mem_type, 65 CeedCopyMode copy_mode, CeedScalar *array) { 66 int ierr; 67 CeedVector_Ref *impl; 68 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 69 CeedSize length; 70 ierr = CeedVectorGetLength(vec, &length); CeedChkBackend(ierr); 71 Ceed ceed; 72 ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 73 74 if (mem_type != CEED_MEM_HOST) 75 // LCOV_EXCL_START 76 return CeedError(ceed, CEED_ERROR_BACKEND, 77 "Can only set HOST memory for this backend"); 78 // LCOV_EXCL_STOP 79 80 switch (copy_mode) { 81 case CEED_COPY_VALUES: 82 if (!impl->array_owned) { 83 ierr = CeedCalloc(length, &impl->array_owned); CeedChkBackend(ierr); 84 } 85 impl->array_borrowed = NULL; 86 impl->array = impl->array_owned; 87 if (array) 88 memcpy(impl->array, array, length * sizeof(array[0])); 89 break; 90 case CEED_OWN_POINTER: 91 ierr = CeedFree(&impl->array_owned); CeedChkBackend(ierr); 92 impl->array_owned = array; 93 impl->array_borrowed = NULL; 94 impl->array = array; 95 break; 96 case CEED_USE_POINTER: 97 ierr = CeedFree(&impl->array_owned); CeedChkBackend(ierr); 98 impl->array_borrowed = array; 99 impl->array = array; 100 } 101 return CEED_ERROR_SUCCESS; 102 } 103 104 //------------------------------------------------------------------------------ 105 // Vector Take Array 106 //------------------------------------------------------------------------------ 107 static int CeedVectorTakeArray_Ref(CeedVector vec, CeedMemType mem_type, 108 CeedScalar **array) { 109 int ierr; 110 CeedVector_Ref *impl; 111 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 112 Ceed ceed; 113 ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 114 115 (*array) = impl->array_borrowed; 116 impl->array_borrowed = NULL; 117 impl->array = NULL; 118 119 return CEED_ERROR_SUCCESS; 120 } 121 122 //------------------------------------------------------------------------------ 123 // Vector Get Array 124 //------------------------------------------------------------------------------ 125 static int CeedVectorGetArrayCore_Ref(CeedVector vec, CeedMemType mem_type, 126 CeedScalar **array) { 127 int ierr; 128 CeedVector_Ref *impl; 129 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 130 Ceed ceed; 131 ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 132 133 if (mem_type != CEED_MEM_HOST) 134 // LCOV_EXCL_START 135 return CeedError(ceed, CEED_ERROR_BACKEND, 136 "Can only provide HOST memory for this backend"); 137 // LCOV_EXCL_STOP 138 139 *array = impl->array; 140 141 return CEED_ERROR_SUCCESS; 142 } 143 144 //------------------------------------------------------------------------------ 145 // Vector Get Array Read 146 //------------------------------------------------------------------------------ 147 static int CeedVectorGetArrayRead_Ref(CeedVector vec, CeedMemType mem_type, 148 const CeedScalar **array) { 149 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 150 } 151 152 //------------------------------------------------------------------------------ 153 // Vector Get Array 154 //------------------------------------------------------------------------------ 155 static int CeedVectorGetArray_Ref(CeedVector vec, CeedMemType mem_type, 156 CeedScalar **array) { 157 return CeedVectorGetArrayCore_Ref(vec, mem_type, array); 158 } 159 160 //------------------------------------------------------------------------------ 161 // Vector Get Array Write 162 //------------------------------------------------------------------------------ 163 static int CeedVectorGetArrayWrite_Ref(CeedVector vec, CeedMemType mem_type, 164 const CeedScalar **array) { 165 int ierr; 166 CeedVector_Ref *impl; 167 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 168 169 if (!impl->array) { 170 if (!impl->array_owned && !impl->array_borrowed) { 171 // Allocate if array is not yet allocated 172 ierr = CeedVectorSetArray(vec, CEED_MEM_HOST, CEED_COPY_VALUES, NULL); 173 CeedChkBackend(ierr); 174 } else { 175 // Select dirty array for GetArrayWrite 176 if (impl->array_borrowed) 177 impl->array = impl->array_borrowed; 178 else 179 impl->array = impl->array_owned; 180 } 181 } 182 183 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 184 } 185 186 //------------------------------------------------------------------------------ 187 // Vector Restore Array 188 //------------------------------------------------------------------------------ 189 static int CeedVectorRestoreArray_Ref(CeedVector vec) { 190 return CEED_ERROR_SUCCESS; 191 } 192 193 static int CeedVectorRestoreArrayRead_Ref(CeedVector vec) { 194 return CEED_ERROR_SUCCESS; 195 } 196 197 //------------------------------------------------------------------------------ 198 // Vector Destroy 199 //------------------------------------------------------------------------------ 200 static int CeedVectorDestroy_Ref(CeedVector vec) { 201 int ierr; 202 CeedVector_Ref *impl; 203 ierr = CeedVectorGetData(vec, &impl); CeedChkBackend(ierr); 204 205 ierr = CeedFree(&impl->array_owned); CeedChkBackend(ierr); 206 ierr = CeedFree(&impl); CeedChkBackend(ierr); 207 return CEED_ERROR_SUCCESS; 208 } 209 210 //------------------------------------------------------------------------------ 211 // Vector Create 212 //------------------------------------------------------------------------------ 213 int CeedVectorCreate_Ref(CeedSize n, CeedVector vec) { 214 int ierr; 215 CeedVector_Ref *impl; 216 Ceed ceed; 217 ierr = CeedVectorGetCeed(vec, &ceed); CeedChkBackend(ierr); 218 219 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", 220 CeedVectorHasValidArray_Ref); CeedChkBackend(ierr); 221 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", 222 CeedVectorHasBorrowedArrayOfType_Ref); 223 CeedChkBackend(ierr); 224 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", 225 CeedVectorSetArray_Ref); CeedChkBackend(ierr); 226 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", 227 CeedVectorTakeArray_Ref); CeedChkBackend(ierr); 228 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", 229 CeedVectorGetArray_Ref); CeedChkBackend(ierr); 230 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", 231 CeedVectorGetArrayRead_Ref); CeedChkBackend(ierr); 232 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", 233 CeedVectorGetArrayWrite_Ref); CeedChkBackend(ierr); 234 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", 235 CeedVectorRestoreArray_Ref); CeedChkBackend(ierr); 236 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", 237 CeedVectorRestoreArrayRead_Ref); CeedChkBackend(ierr); 238 ierr = CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", 239 CeedVectorDestroy_Ref); CeedChkBackend(ierr); 240 241 ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 242 ierr = CeedVectorSetData(vec, impl); CeedChkBackend(ierr); 243 244 return CEED_ERROR_SUCCESS; 245 } 246 //------------------------------------------------------------------------------ 247