ceed_vector.py (2bc797ab000477348efa69c987743393cf84ac4a) ceed_vector.py (7f1dc7b91d4f5ca67db10df8f4f0b60afe166f53)
1# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3# reserved. See files LICENSE and NOTICE for details.
4#
5# This file is part of CEED, a collection of benchmarks, miniapps, software
6# libraries and APIs for efficient high-order finite element and spectral
7# element discretizations for exascale applications. For more information and
8# source code availability see http://github.com/ceed.
9#
10# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11# a collaborative effort of two U.S. Department of Energy organizations (Office
12# of Science and the National Nuclear Security Administration) responsible for
13# the planning and preparation of a capable exascale ecosystem, including
14# software, applications, hardware, advanced system engineering and early
15# testbed platforms, in support of the nation's exascale computing imperative.
16
17from _ceed_cffi import ffi, lib
18import tempfile
19import numpy as np
1# Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2# the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3# reserved. See files LICENSE and NOTICE for details.
4#
5# This file is part of CEED, a collection of benchmarks, miniapps, software
6# libraries and APIs for efficient high-order finite element and spectral
7# element discretizations for exascale applications. For more information and
8# source code availability see http://github.com/ceed.
9#
10# The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11# a collaborative effort of two U.S. Department of Energy organizations (Office
12# of Science and the National Nuclear Security Administration) responsible for
13# the planning and preparation of a capable exascale ecosystem, including
14# software, applications, hardware, advanced system engineering and early
15# testbed platforms, in support of the nation's exascale computing imperative.
16
17from _ceed_cffi import ffi, lib
18import tempfile
19import numpy as np
20import numba.cuda as nbcuda
20import contextlib
21from .ceed_constants import MEM_HOST, COPY_VALUES, NORM_2
22
23# ------------------------------------------------------------------------------
24
25
26class Vector():
27 """Ceed Vector: storing and manipulating vectors."""

--- 40 unchanged lines hidden (view full) ---

68 return out_string
69
70 # Set Vector's data array
71 def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES):
72 """Set the array used by a Vector, freeing any previously allocated
73 array if applicable.
74
75 Args:
21import contextlib
22from .ceed_constants import MEM_HOST, COPY_VALUES, NORM_2
23
24# ------------------------------------------------------------------------------
25
26
27class Vector():
28 """Ceed Vector: storing and manipulating vectors."""

--- 40 unchanged lines hidden (view full) ---

69 return out_string
70
71 # Set Vector's data array
72 def set_array(self, array, memtype=MEM_HOST, cmode=COPY_VALUES):
73 """Set the array used by a Vector, freeing any previously allocated
74 array if applicable.
75
76 Args:
76 *array: Numpy array to be used
77 *array: Numpy or Numba array to be used
77 **memtype: memory type of the array being passed, default CEED_MEM_HOST
78 **cmode: copy mode for the array, default CEED_COPY_VALUES"""
79
80 # Setup the numpy array for the libCEED call
81 array_pointer = ffi.new("CeedScalar *")
78 **memtype: memory type of the array being passed, default CEED_MEM_HOST
79 **cmode: copy mode for the array, default CEED_COPY_VALUES"""
80
81 # Setup the numpy array for the libCEED call
82 array_pointer = ffi.new("CeedScalar *")
82 array_pointer = ffi.cast(
83 "CeedScalar *",
84 array.__array_interface__['data'][0])
83 if memtype == MEM_HOST:
84 array_pointer = ffi.cast(
85 "CeedScalar *",
86 array.__array_interface__['data'][0])
87 else:
88 array_pointer = ffi.cast(
89 "CeedScalar *",
90 array.__cuda_array_interface__['data'][0])
85
86 # libCEED call
87 lib.CeedVectorSetArray(self._pointer[0], memtype, cmode, array_pointer)
88
89 # Get Vector's data array
90 def get_array(self, memtype=MEM_HOST):
91 """Get read/write access to a Vector via the specified memory type.
92
93 Args:
94 **memtype: memory type of the array being passed, default CEED_MEM_HOST
95
96 Returns:
91
92 # libCEED call
93 lib.CeedVectorSetArray(self._pointer[0], memtype, cmode, array_pointer)
94
95 # Get Vector's data array
96 def get_array(self, memtype=MEM_HOST):
97 """Get read/write access to a Vector via the specified memory type.
98
99 Args:
100 **memtype: memory type of the array being passed, default CEED_MEM_HOST
101
102 Returns:
97 *array: Numpy array"""
103 *array: Numpy or Numba array"""
98
99 # Retrieve the length of the array
100 length_pointer = ffi.new("CeedInt *")
101 lib.CeedVectorGetLength(self._pointer[0], length_pointer)
102
103 # Setup the pointer's pointer
104 array_pointer = ffi.new("CeedScalar **")
105
106 # libCEED call
107 lib.CeedVectorGetArray(self._pointer[0], memtype, array_pointer)
108
104
105 # Retrieve the length of the array
106 length_pointer = ffi.new("CeedInt *")
107 lib.CeedVectorGetLength(self._pointer[0], length_pointer)
108
109 # Setup the pointer's pointer
110 array_pointer = ffi.new("CeedScalar **")
111
112 # libCEED call
113 lib.CeedVectorGetArray(self._pointer[0], memtype, array_pointer)
114
109 # Create buffer object from returned pointer
110 buff = ffi.buffer(
111 array_pointer[0],
112 ffi.sizeof("CeedScalar") *
113 length_pointer[0])
114 # Return numpy array created from buffer
115 return np.frombuffer(buff, dtype="float64")
115 # Return array created from buffer
116 if memtype == MEM_HOST:
117 # Create buffer object from returned pointer
118 buff = ffi.buffer(
119 array_pointer[0],
120 ffi.sizeof("CeedScalar") *
121 length_pointer[0])
122 # return Numpy array
123 return np.frombuffer(buff, dtype="float64")
124 else:
125 # CUDA array interface
126 # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html
127 desc = {
128 'shape': (length_pointer[0]),
129 'typestr': '>f8',
130 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False),
131 'version': 2
132 }
133 # return Numba array
134 return nbcuda.from_cuda_array_interface(desc)
116
117 # Get Vector's data array in read-only mode
118 def get_array_read(self, memtype=MEM_HOST):
119 """Get read-only access to a Vector via the specified memory type.
120
121 Args:
122 **memtype: memory type of the array being passed, default CEED_MEM_HOST
123
124 Returns:
135
136 # Get Vector's data array in read-only mode
137 def get_array_read(self, memtype=MEM_HOST):
138 """Get read-only access to a Vector via the specified memory type.
139
140 Args:
141 **memtype: memory type of the array being passed, default CEED_MEM_HOST
142
143 Returns:
125 *array: Numpy array"""
144 *array: Numpy or Numba array"""
126
127 # Retrieve the length of the array
128 length_pointer = ffi.new("CeedInt *")
129 lib.CeedVectorGetLength(self._pointer[0], length_pointer)
130
131 # Setup the pointer's pointer
132 array_pointer = ffi.new("CeedScalar **")
133
134 # libCEED call
135 lib.CeedVectorGetArrayRead(self._pointer[0], memtype, array_pointer)
136
145
146 # Retrieve the length of the array
147 length_pointer = ffi.new("CeedInt *")
148 lib.CeedVectorGetLength(self._pointer[0], length_pointer)
149
150 # Setup the pointer's pointer
151 array_pointer = ffi.new("CeedScalar **")
152
153 # libCEED call
154 lib.CeedVectorGetArrayRead(self._pointer[0], memtype, array_pointer)
155
137 # Create buffer object from returned pointer
138 buff = ffi.buffer(
139 array_pointer[0],
140 ffi.sizeof("CeedScalar") *
141 length_pointer[0])
142 # Create numpy array from buffer
143 ret = np.frombuffer(buff, dtype="float64")
144 # Make the numpy array read-only
145 ret.flags['WRITEABLE'] = False
146 return ret
156 # Return array created from buffer
157 if memtype == MEM_HOST:
158 # Create buffer object from returned pointer
159 buff = ffi.buffer(
160 array_pointer[0],
161 ffi.sizeof("CeedScalar") *
162 length_pointer[0])
163 # return read only Numpy array
164 ret = np.frombuffer(buff, dtype="float64")
165 ret.flags['WRITEABLE'] = False
166 return ret
167 else:
168 # CUDA array interface
169 # https://numba.pydata.org/numba-doc/latest/cuda/cuda_array_interface.html
170 desc = {
171 'shape': (length_pointer[0]),
172 'typestr': '>f8',
173 'data': (int(ffi.cast("intptr_t", array_pointer[0])), False),
174 'version': 2
175 }
176 # return read only Numba array
177 return nbcuda.from_cuda_array_interface(desc)
147
148 # Restore the Vector's data array
149 def restore_array(self):
150 """Restore an array obtained using get_array()."""
151
152 # Setup the pointer's pointer
153 array_pointer = ffi.new("CeedScalar **")
154

--- 6 unchanged lines hidden (view full) ---

161
162 # Setup the pointer's pointer
163 array_pointer = ffi.new("CeedScalar **")
164
165 # libCEED call
166 lib.CeedVectorRestoreArrayRead(self._pointer[0], array_pointer)
167
168 @contextlib.contextmanager
178
179 # Restore the Vector's data array
180 def restore_array(self):
181 """Restore an array obtained using get_array()."""
182
183 # Setup the pointer's pointer
184 array_pointer = ffi.new("CeedScalar **")
185

--- 6 unchanged lines hidden (view full) ---

192
193 # Setup the pointer's pointer
194 array_pointer = ffi.new("CeedScalar **")
195
196 # libCEED call
197 lib.CeedVectorRestoreArrayRead(self._pointer[0], array_pointer)
198
199 @contextlib.contextmanager
169 def array(self, *shape):
200 def array(self, *shape, memtype=MEM_HOST):
170 """Context manager for array access.
171
172 Args:
173 shape (tuple): shape of returned numpy.array
201 """Context manager for array access.
202
203 Args:
204 shape (tuple): shape of returned numpy.array
205 **memtype: memory type of the array being passed, default CEED_MEM_HOST
174
206
207
175 Returns:
176 np.array: writable view of vector
177
178 Examples:
179 Constructing the identity inside a libceed.Vector:
180
181 >>> vec = ceed.Vector(16)
182 >>> with vec.array(4, 4) as x:
183 >>> x[...] = np.eye(4)
184 """
208 Returns:
209 np.array: writable view of vector
210
211 Examples:
212 Constructing the identity inside a libceed.Vector:
213
214 >>> vec = ceed.Vector(16)
215 >>> with vec.array(4, 4) as x:
216 >>> x[...] = np.eye(4)
217 """
185 x = self.get_array()
218 x = self.get_array(memtype=memtype)
186 if shape:
187 x = x.reshape(shape)
188 yield x
189 self.restore_array()
190
191 @contextlib.contextmanager
219 if shape:
220 x = x.reshape(shape)
221 yield x
222 self.restore_array()
223
224 @contextlib.contextmanager
192 def array_read(self, *shape):
225 def array_read(self, *shape, memtype=MEM_HOST):
193 """Context manager for read-only array access.
194
195 Args:
196 shape (tuple): shape of returned numpy.array
226 """Context manager for read-only array access.
227
228 Args:
229 shape (tuple): shape of returned numpy.array
230 **memtype: memory type of the array being passed, default CEED_MEM_HOST
197
198 Returns:
199 np.array: read-only view of vector
200
201 Examples:
202 Constructing the identity inside a libceed.Vector:
203
204 >>> vec = ceed.Vector(6)
205 >>> vec.set_value(1.3)
206 >>> with vec.array_read(2, 3) as x:
207 >>> print(x)
208 """
231
232 Returns:
233 np.array: read-only view of vector
234
235 Examples:
236 Constructing the identity inside a libceed.Vector:
237
238 >>> vec = ceed.Vector(6)
239 >>> vec.set_value(1.3)
240 >>> with vec.array_read(2, 3) as x:
241 >>> print(x)
242 """
209 x = self.get_array_read()
243 x = self.get_array_read(memtype=memtype)
210 if shape:
211 x = x.reshape(shape)
212 yield x
213 self.restore_array_read()
214
215 # Get the length of a Vector
216 def get_length(self):
217 """Get the length of a Vector.

--- 74 unchanged lines hidden ---
244 if shape:
245 x = x.reshape(shape)
246 yield x
247 self.restore_array_read()
248
249 # Get the length of a Vector
250 def get_length(self):
251 """Get the length of a Vector.

--- 74 unchanged lines hidden ---