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 (*array) = impl->array_borrowed; 99 impl->array_borrowed = NULL; 100 impl->array = NULL; 101 102 return CEED_ERROR_SUCCESS; 103 } 104 105 //------------------------------------------------------------------------------ 106 // Vector Get Array 107 //------------------------------------------------------------------------------ 108 static int CeedVectorGetArrayCore_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 109 CeedVector_Ref *impl; 110 CeedCallBackend(CeedVectorGetData(vec, &impl)); 111 Ceed ceed; 112 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 113 114 if (mem_type != CEED_MEM_HOST) { 115 // LCOV_EXCL_START 116 return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend"); 117 // LCOV_EXCL_STOP 118 } 119 120 *array = impl->array; 121 122 return CEED_ERROR_SUCCESS; 123 } 124 125 //------------------------------------------------------------------------------ 126 // Vector Get Array Read 127 //------------------------------------------------------------------------------ 128 static int CeedVectorGetArrayRead_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) { 129 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 130 } 131 132 //------------------------------------------------------------------------------ 133 // Vector Get Array 134 //------------------------------------------------------------------------------ 135 static int CeedVectorGetArray_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) { 136 return CeedVectorGetArrayCore_Ref(vec, mem_type, array); 137 } 138 139 //------------------------------------------------------------------------------ 140 // Vector Get Array Write 141 //------------------------------------------------------------------------------ 142 static int CeedVectorGetArrayWrite_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) { 143 CeedVector_Ref *impl; 144 CeedCallBackend(CeedVectorGetData(vec, &impl)); 145 146 if (!impl->array) { 147 if (!impl->array_owned && !impl->array_borrowed) { 148 // Allocate if array is not yet allocated 149 CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_HOST, CEED_COPY_VALUES, NULL)); 150 } else { 151 // Select dirty array for GetArrayWrite 152 if (impl->array_borrowed) impl->array = impl->array_borrowed; 153 else impl->array = impl->array_owned; 154 } 155 } 156 157 return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array); 158 } 159 160 //------------------------------------------------------------------------------ 161 // Vector Restore Array 162 //------------------------------------------------------------------------------ 163 static int CeedVectorRestoreArray_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; } 164 165 static int CeedVectorRestoreArrayRead_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; } 166 167 //------------------------------------------------------------------------------ 168 // Vector Destroy 169 //------------------------------------------------------------------------------ 170 static int CeedVectorDestroy_Ref(CeedVector vec) { 171 CeedVector_Ref *impl; 172 CeedCallBackend(CeedVectorGetData(vec, &impl)); 173 174 CeedCallBackend(CeedFree(&impl->array_owned)); 175 CeedCallBackend(CeedFree(&impl)); 176 return CEED_ERROR_SUCCESS; 177 } 178 179 //------------------------------------------------------------------------------ 180 // Vector Create 181 //------------------------------------------------------------------------------ 182 int CeedVectorCreate_Ref(CeedSize n, CeedVector vec) { 183 CeedVector_Ref *impl; 184 Ceed ceed; 185 CeedCallBackend(CeedVectorGetCeed(vec, &ceed)); 186 187 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Ref)); 188 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Ref)); 189 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Ref)); 190 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Ref)); 191 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Ref)); 192 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Ref)); 193 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Ref)); 194 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", CeedVectorRestoreArray_Ref)); 195 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", CeedVectorRestoreArrayRead_Ref)); 196 CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Ref)); 197 198 CeedCallBackend(CeedCalloc(1, &impl)); 199 CeedCallBackend(CeedVectorSetData(vec, impl)); 200 201 return CEED_ERROR_SUCCESS; 202 } 203 //------------------------------------------------------------------------------ 204