xref: /libCEED/backends/ref/ceed-ref-vector.c (revision dd75fd25173ccc390ac3dae7b2b394bf6101854f)
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   if (mem_type != CEED_MEM_HOST) {
99     // LCOV_EXCL_START
100     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
101     // LCOV_EXCL_STOP
102   }
103 
104   (*array)             = impl->array_borrowed;
105   impl->array_borrowed = NULL;
106   impl->array          = NULL;
107 
108   return CEED_ERROR_SUCCESS;
109 }
110 
111 //------------------------------------------------------------------------------
112 // Vector Get Array
113 //------------------------------------------------------------------------------
114 static int CeedVectorGetArrayCore_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
115   CeedVector_Ref *impl;
116   CeedCallBackend(CeedVectorGetData(vec, &impl));
117   Ceed ceed;
118   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
119 
120   if (mem_type != CEED_MEM_HOST) {
121     // LCOV_EXCL_START
122     return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide HOST memory for this backend");
123     // LCOV_EXCL_STOP
124   }
125 
126   *array = impl->array;
127 
128   return CEED_ERROR_SUCCESS;
129 }
130 
131 //------------------------------------------------------------------------------
132 // Vector Get Array Read
133 //------------------------------------------------------------------------------
134 static int CeedVectorGetArrayRead_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) {
135   return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array);
136 }
137 
138 //------------------------------------------------------------------------------
139 // Vector Get Array
140 //------------------------------------------------------------------------------
141 static int CeedVectorGetArray_Ref(CeedVector vec, CeedMemType mem_type, CeedScalar **array) {
142   return CeedVectorGetArrayCore_Ref(vec, mem_type, array);
143 }
144 
145 //------------------------------------------------------------------------------
146 // Vector Get Array Write
147 //------------------------------------------------------------------------------
148 static int CeedVectorGetArrayWrite_Ref(CeedVector vec, CeedMemType mem_type, const CeedScalar **array) {
149   CeedVector_Ref *impl;
150   CeedCallBackend(CeedVectorGetData(vec, &impl));
151 
152   if (!impl->array) {
153     if (!impl->array_owned && !impl->array_borrowed) {
154       // Allocate if array is not yet allocated
155       CeedCallBackend(CeedVectorSetArray(vec, CEED_MEM_HOST, CEED_COPY_VALUES, NULL));
156     } else {
157       // Select dirty array for GetArrayWrite
158       if (impl->array_borrowed) impl->array = impl->array_borrowed;
159       else impl->array = impl->array_owned;
160     }
161   }
162 
163   return CeedVectorGetArrayCore_Ref(vec, mem_type, (CeedScalar **)array);
164 }
165 
166 //------------------------------------------------------------------------------
167 // Vector Restore Array
168 //------------------------------------------------------------------------------
169 static int CeedVectorRestoreArray_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; }
170 
171 static int CeedVectorRestoreArrayRead_Ref(CeedVector vec) { return CEED_ERROR_SUCCESS; }
172 
173 //------------------------------------------------------------------------------
174 // Vector Destroy
175 //------------------------------------------------------------------------------
176 static int CeedVectorDestroy_Ref(CeedVector vec) {
177   CeedVector_Ref *impl;
178   CeedCallBackend(CeedVectorGetData(vec, &impl));
179 
180   CeedCallBackend(CeedFree(&impl->array_owned));
181   CeedCallBackend(CeedFree(&impl));
182   return CEED_ERROR_SUCCESS;
183 }
184 
185 //------------------------------------------------------------------------------
186 // Vector Create
187 //------------------------------------------------------------------------------
188 int CeedVectorCreate_Ref(CeedSize n, CeedVector vec) {
189   CeedVector_Ref *impl;
190   Ceed            ceed;
191   CeedCallBackend(CeedVectorGetCeed(vec, &ceed));
192 
193   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasValidArray", CeedVectorHasValidArray_Ref));
194   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "HasBorrowedArrayOfType", CeedVectorHasBorrowedArrayOfType_Ref));
195   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "SetArray", CeedVectorSetArray_Ref));
196   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "TakeArray", CeedVectorTakeArray_Ref));
197   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArray", CeedVectorGetArray_Ref));
198   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayRead", CeedVectorGetArrayRead_Ref));
199   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "GetArrayWrite", CeedVectorGetArrayWrite_Ref));
200   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArray", CeedVectorRestoreArray_Ref));
201   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "RestoreArrayRead", CeedVectorRestoreArrayRead_Ref));
202   CeedCallBackend(CeedSetBackendFunction(ceed, "Vector", vec, "Destroy", CeedVectorDestroy_Ref));
203 
204   CeedCallBackend(CeedCalloc(1, &impl));
205   CeedCallBackend(CeedVectorSetData(vec, impl));
206 
207   return CEED_ERROR_SUCCESS;
208 }
209 //------------------------------------------------------------------------------
210