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/backend.h> 9 #include <ceed/ceed.h> 10 #include <string.h> 11 12 #include "ceed-ref.h" 13 14 //------------------------------------------------------------------------------ 15 // Has Valid Array 16 //------------------------------------------------------------------------------ 17 static int CeedVectorHasValidArray_Ref(CeedVector vec, bool *has_valid_array) { 18 CeedVector_Ref *impl; 19 CeedCallBackend(CeedVectorGetData(vec, &impl)); 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, CeedMemType mem_type, bool *has_borrowed_array_of_type) { 30 CeedVector_Ref *impl; 31 CeedCallBackend(CeedVectorGetData(vec, &impl)); 32 Ceed ceed; 33 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 34 35 switch (mem_type) { 36 case CEED_MEM_HOST: 37 *has_borrowed_array_of_type = !!impl->array_borrowed; 38 break; 39 default: 40 // LCOV_EXCL_START 41 return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 42 // LCOV_EXCL_STOP 43 break; 44 } 45 46 return CEED_ERROR_SUCCESS; 47 } 48 49 //------------------------------------------------------------------------------ 50 // Vector Set Array 51 //------------------------------------------------------------------------------ 52 static int CeedVectorSetArray_Ref(CeedVector vec, CeedMemType mem_type, CeedCopyMode copy_mode, CeedScalar *array) { 53 CeedVector_Ref *impl; 54 CeedCallBackend(CeedVectorGetData(vec, &impl)); 55 CeedSize length; 56 CeedCallBackend(CeedVectorGetLength(vec, &length)); 57 Ceed ceed; 58 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 59 60 if (mem_type != CEED_MEM_HOST) { 61 // LCOV_EXCL_START 62 return CeedError(ceed, CEED_ERROR_BACKEND, "Can only set HOST memory for this backend"); 63 // LCOV_EXCL_STOP 64 } 65 66 switch (copy_mode) { 67 case CEED_COPY_VALUES: 68 if (!impl->array_owned) { 69 CeedCallBackend(CeedCalloc(length, &impl->array_owned)); 70 } 71 impl->array_borrowed = NULL; 72 impl->array = impl->array_owned; 73 if (array) memcpy(impl->array, array, length * sizeof(array[0])); 74 break; 75 case CEED_OWN_POINTER: 76 CeedCallBackend(CeedFree(&impl->array_owned)); 77 impl->array_owned = array; 78 impl->array_borrowed = NULL; 79 impl->array = array; 80 break; 81 case CEED_USE_POINTER: 82 CeedCallBackend(CeedFree(&impl->array_owned)); 83 impl->array_borrowed = array; 84 impl->array = array; 85 } 86 return CEED_ERROR_SUCCESS; 87 } 88 89 //------------------------------------------------------------------------------ 90 // Vector Take Array 91 //------------------------------------------------------------------------------ 92 static int CeedVectorTakeArray_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 93 CeedVector_Ref *impl; 94 CeedCallBackend(CeedVectorGetData(vec, &impl)); 95 Ceed ceed; 96 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 97 98 if (mem_type != CEED_MEM_HOST) { 99 // LCOV_EXCL_START 100 return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 101 // LCOV_EXCL_STOP 102 } 103 104 (*array) = impl->array_borrowed; 105 impl->array_borrowed = NULL; 106 impl->array = NULL; 107 108 return CEED_ERROR_SUCCESS; 109 } 110 111 //------------------------------------------------------------------------------ 112 // Vector Get Array 113 //------------------------------------------------------------------------------ 114 static int CeedVectorGetArrayCore_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 115 CeedVector_Ref *impl; 116 CeedCallBackend(CeedVectorGetData(vec, &impl)); 117 Ceed ceed; 118 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 119 120 if (mem_type != CEED_MEM_HOST) { 121 // LCOV_EXCL_START 122 return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 123 // LCOV_EXCL_STOP 124 } 125 126 *array = impl->array; 127 128 return CEED_ERROR_SUCCESS; 129 } 130 131 //------------------------------------------------------------------------------ 132 // Vector Get Array Read 133 //------------------------------------------------------------------------------ 134 static int CeedVectorGetArrayRead_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) { 135 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 136 } 137 138 //------------------------------------------------------------------------------ 139 // Vector Get Array 140 //------------------------------------------------------------------------------ 141 static int CeedVectorGetArray_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 142 return CeedVectorGetArrayCore_Ref(vec, mem_type, array); 143 } 144 145 //------------------------------------------------------------------------------ 146 // Vector Get Array Write 147 //------------------------------------------------------------------------------ 148 static int CeedVectorGetArrayWrite_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) { 149 CeedVector_Ref *impl; 150 CeedCallBackend(CeedVectorGetData(vec, &impl)); 151 152 if (!impl->array) { 153 if (!impl->array_owned && !impl->array_borrowed) { 154 // Allocate if array is not yet allocated 155 CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_HOST, CEED_COPY_VALUES, NULL)); 156 } else { 157 // Select dirty array for GetArrayWrite 158 if (impl->array_borrowed) impl->array = impl->array_borrowed; 159 else impl->array = impl->array_owned; 160 } 161 } 162 163 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 164 } 165 166 //------------------------------------------------------------------------------ 167 // Vector Restore Array 168 //------------------------------------------------------------------------------ 169 static int CeedVectorRestoreArray_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; } 170 171 static int CeedVectorRestoreArrayRead_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; } 172 173 //------------------------------------------------------------------------------ 174 // Vector Destroy 175 //------------------------------------------------------------------------------ 176 static int CeedVectorDestroy_Ref(CeedVector vec) { 177 CeedVector_Ref *impl; 178 CeedCallBackend(CeedVectorGetData(vec, &impl)); 179 180 CeedCallBackend(CeedFree(&impl->array_owned)); 181 CeedCallBackend(CeedFree(&impl)); 182 return CEED_ERROR_SUCCESS; 183 } 184 185 //------------------------------------------------------------------------------ 186 // Vector Create 187 //------------------------------------------------------------------------------ 188 int CeedVectorCreate_Ref(CeedSize n, CeedVector vec) { 189 CeedVector_Ref *impl; 190 Ceed ceed; 191 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 192 193 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Ref)); 194 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Ref)); 195 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Ref)); 196 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Ref)); 197 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Ref)); 198 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Ref)); 199 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Ref)); 200 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", CeedVectorRestoreArray_Ref)); 201 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", CeedVectorRestoreArrayRead_Ref)); 202 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Ref)); 203 204 CeedCallBackend(CeedCalloc(1, &impl)); 205 CeedCallBackend(CeedVectorSetData(vec, impl)); 206 207 return CEED_ERROR_SUCCESS; 208 } 209 //------------------------------------------------------------------------------ 210