xref: /libCEED/backends/ref/ceed-ref-vector.c (revision 13f28a1f297c33230ed3196f9946aaac3811bd77)
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