LvArray
PyArrayOfArrays.hpp
Go to the documentation of this file.
1 /*
2  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3  * Copyright (c) 2019, Lawrence Livermore National Security, LLC.
4  *
5  * Produced at the Lawrence Livermore National Laboratory
6  *
7  * LLNL-CODE-746361
8  *
9  * All rights reserved. See COPYRIGHT for details.
10  *
11  * This file is part of the GEOSX Simulation Framework.
12  *
13  * GEOSX is a free software; you can redistribute it and/or modify it under
14  * the terms of the GNU Lesser General Public License (as published by the
15  * Free Software Foundation) version 2.1 dated February 1999.
16  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17  */
18 
23 #pragma once
24 
25 // Source includes
27 #include "numpyHelpers.hpp"
28 #include "../ArrayOfArrays.hpp"
29 #include "../Macros.hpp"
30 #include "../limits.hpp"
31 #include "../output.hpp"
32 
33 // System includes
34 #include <string>
35 #include <memory>
36 #include <typeindex>
37 
38 namespace LvArray
39 {
40 namespace python
41 {
42 namespace internal
43 {
44 
50 {
51 public:
52 
56  virtual ~PyArrayOfArraysWrapperBase() = default;
57 
62  virtual int getAccessLevel() const
63  { return m_accessLevel; }
64 
69  virtual void setAccessLevel( int const accessLevel ) = 0;
70 
75  virtual std::string repr() const = 0;
76 
82  virtual long long size() const = 0;
83 
90  virtual long long sizeOfArray( long long arrayIndex ) const = 0;
91 
98  virtual PyObject * operator[]( long long arrayIndex ) = 0;
99 
104  virtual std::type_index valueType() const = 0;
105 
111  virtual void eraseArray( long long arrayIndex ) = 0;
112 
119  virtual void eraseFromArray( long long arrayIndex, long long valueIndex ) = 0;
120 
128  virtual void insertArray( long long arrayIndex, void const * values, long long numVals ) = 0;
129 
138  virtual void insertIntoArray( long long arrayIndex,
139  long long valueIndex,
140  void const * values,
141  long long numVals ) = 0;
142 
143 protected:
144 
149  m_accessLevel( static_cast< int >( LvArray::python::PyModify::READ_ONLY ) )
150  {}
151 
154 };
155 
165 template< typename T,
166  typename INDEX_TYPE,
167  template< typename > class BUFFER_TYPE >
169 {
170 public:
171 
178  m_arrayOfArrays( arrayOfArrays )
179  {}
180 
182  virtual ~PyArrayOfArraysWrapper() = default;
183 
185  virtual void setAccessLevel( int accessLevel ) final override
186  {
187  if( accessLevel >= static_cast< int >( LvArray::python::PyModify::RESIZEABLE ) )
188  {
189  // touch
190  }
191  m_accessLevel = accessLevel;
192  }
193 
195  virtual std::string repr() const final override
196  { return system::demangleType< ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > >(); }
197 
199  virtual long long size() const final override
200  { return integerConversion< long long >( m_arrayOfArrays.size() ); }
201 
203  virtual long long sizeOfArray( long long arrayIndex ) const final override
204  {
205  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( arrayIndex );
206  return integerConversion< long long >( m_arrayOfArrays.sizeOfArray( convertedIndex ) );
207  }
208 
210  virtual PyObject * operator[]( long long arrayIndex ) final override
211  {
212  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( arrayIndex );
213  ArraySlice< T, 1, 0, INDEX_TYPE > slice = m_arrayOfArrays[ convertedIndex ];
214  T * data = slice;
215  constexpr INDEX_TYPE strides = 1;
216  INDEX_TYPE size = slice.size();
217  return createNumPyArray( data, getAccessLevel() >= static_cast< int >( LvArray::python::PyModify::MODIFIABLE ), 1, &size, &strides );
218  }
219 
221  virtual std::type_index valueType() const final override
222  { return std::type_index( typeid( T ) ); }
223 
225  virtual void eraseArray( long long arrayIndex ) final override
226  {
227  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( arrayIndex );
228  m_arrayOfArrays.eraseArray( convertedIndex );
229  }
230 
232  virtual void eraseFromArray( long long arrayIndex, long long valueIndex ) final override
233  {
234  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( arrayIndex );
235  INDEX_TYPE convertedBegin = integerConversion< INDEX_TYPE >( valueIndex );
236  m_arrayOfArrays.eraseFromArray( convertedIndex, convertedBegin );
237  }
238 
240  virtual void insertArray( long long arrayIndex, void const * values, long long numVals ) final override
241  {
242  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( arrayIndex );
243  T const * begin = static_cast< T const * >( values );
244  T const * end = begin + numVals;
245  m_arrayOfArrays.insertArray( convertedIndex, begin, end );
246  }
247 
249  virtual void insertIntoArray( long long arrayIndex,
250  long long valueIndex,
251  void const * values,
252  long long numVals ) final override
253  {
254  INDEX_TYPE convertedArray = integerConversion< INDEX_TYPE >( arrayIndex );
255  INDEX_TYPE convertedIndex = integerConversion< INDEX_TYPE >( valueIndex );
256  T const * begin = static_cast< T const * >( values );
257  T const * end = begin + numVals;
258  m_arrayOfArrays.insertIntoArray( convertedArray, convertedIndex, begin, end );
259  }
260 
261 private:
264 };
265 
271 PyObject * create( std::unique_ptr< internal::PyArrayOfArraysWrapperBase > && arrayOfArrays );
272 
273 } // namespace internal
274 
285 template< typename T, typename INDEX_TYPE, template< typename > class BUFFER_TYPE >
286 std::enable_if_t< internal::canExportToNumpy< T >, PyObject * >
288 {
289  auto tmp = std::make_unique< internal::PyArrayOfArraysWrapper< T, INDEX_TYPE, BUFFER_TYPE > >( arrayOfArrays );
290  return internal::create( std::move( tmp ) );
291 }
292 
297 PyTypeObject * getPyArrayOfArraysType();
298 
299 } // namespace python
300 } // namespace LvArray
virtual void setAccessLevel(int accessLevel) final override
Set the access level for the ArrayOfArrays.
Definition: PyArrayOfArrays.hpp:185
std::enable_if_t< internal::canExportToNumpy< T >, PyObject *> create(T &value)
Create a NumPy 1D array of length 1 containing the scalar value.
Definition: numpyHelpers.hpp:147
PyModify
An enumeration of the various access policies for Python objects.
Definition: pythonHelpers.hpp:136
virtual int getAccessLevel() const
Return the access level for the ArrayOfArrays.
Definition: PyArrayOfArrays.hpp:62
virtual ~PyArrayOfArraysWrapperBase()=default
Default destructor.
This class serves to provide a sliced multidimensional interface to the family of LvArray classes...
Definition: ArraySlice.hpp:89
ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > & m_arrayOfArrays
The wrapped ArrayOfArrays.
Definition: PyArrayOfArrays.hpp:263
PyArrayOfArraysWrapper(ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > &arrayOfArrays)
Construct a new Python wrapper around arrayOfArrays.
Definition: PyArrayOfArrays.hpp:176
virtual long long size() const =0
Return the size of the array (number of sub-arrays).
virtual std::type_index valueType() const =0
Return the type of the values stored in the sub-arrays.
std::enable_if_t< internal::canExportToNumpy< T >, PyObject *> create(ArrayOfArrays< T, INDEX_TYPE, BUFFER_TYPE > &arrayOfArrays)
Create a Python object corresponding to arrayOfArrays.
Definition: PyArrayOfArrays.hpp:287
This class implements an array of arrays like object with contiguous storage.
Definition: ArrayOfArrays.hpp:33
virtual std::string repr() const final override
Return a string representing the underlying ArrayOfArrays type.
Definition: PyArrayOfArrays.hpp:195
virtual PyObject * operator[](long long arrayIndex) final override
Return a 1D numpy array representing the array at index arrayIndex.
Definition: PyArrayOfArrays.hpp:210
virtual std::string repr() const =0
Return a string representing the underlying ArrayOfArrays type.
virtual long long sizeOfArray(long long arrayIndex) const =0
Return the size of the array at index arrayIndex.
virtual void eraseArray(long long arrayIndex) final override
Erase the array at index arrayIndex.
Definition: PyArrayOfArrays.hpp:225
Forward declarations of Python Objects.
Provides a virtual Python wrapper around an ArrayOfArrays.
Definition: PyArrayOfArrays.hpp:49
virtual void eraseFromArray(long long arrayIndex, long long valueIndex)=0
Erase a value from an array.
virtual void setAccessLevel(int const accessLevel)=0
Set the access level for the ArrayOfArrays.
virtual void insertArray(long long arrayIndex, void const *values, long long numVals) final override
Insert a new array.
Definition: PyArrayOfArrays.hpp:240
virtual void insertIntoArray(long long arrayIndex, long long valueIndex, void const *values, long long numVals)=0
Insert new values into an existing array.
The top level namespace.
Definition: Array.hpp:24
virtual PyObject * operator[](long long arrayIndex)=0
Return a 1D numpy array representing the array at index arrayIndex.
Contains methods to help with conversion to python objects.
virtual void insertArray(long long arrayIndex, void const *values, long long numVals)=0
Insert a new array.
PyTypeObject * getPyArrayOfArraysType()
Return the Python type object for the ArrayOfArrays.
Provides a concrete implementation of PyArrayOfArraysWrapperBase.
Definition: PyArrayOfArrays.hpp:168
int m_accessLevel
access level for the ArrayOfArrays.
Definition: PyArrayOfArrays.hpp:153
virtual void insertIntoArray(long long arrayIndex, long long valueIndex, void const *values, long long numVals) final override
Insert new values into an existing array.
Definition: PyArrayOfArrays.hpp:249
virtual long long size() const final override
Return the size of the array (number of sub-arrays).
Definition: PyArrayOfArrays.hpp:199
virtual void eraseArray(long long arrayIndex)=0
Erase the array at index arrayIndex.
virtual void eraseFromArray(long long arrayIndex, long long valueIndex) final override
Erase a value from an array.
Definition: PyArrayOfArrays.hpp:232
PyArrayOfArraysWrapperBase()
Construct an empty PyArrayOfArraysWrapperBase.
Definition: PyArrayOfArrays.hpp:148
virtual std::type_index valueType() const final override
Return the type of the values stored in the sub-arrays.
Definition: PyArrayOfArrays.hpp:221
std::enable_if_t< internal::canExportToNumpy< T >, PyObject *> createNumPyArray(T *const data, bool const modify, int const ndim, INDEX_TYPE const *const dimsPtr, INDEX_TYPE const *const stridesPtr)
Return a NumPy ndarray view of data.
Definition: numpyHelpers.hpp:107
virtual long long sizeOfArray(long long arrayIndex) const final override
Return the size of the array at index arrayIndex.
Definition: PyArrayOfArrays.hpp:203