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