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