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