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