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