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