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