xref: /libCEED/backends/ref/ceed-ref-vector.c (revision edb2538e3dd6743c029967fc4e89c6fcafedb8c2)
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     default:
42       // LCOV_EXCL_START
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