diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bPartition.h b/libNeonDomain/include/Neon/domain/details/bGrid/bPartition.h index 48b85165..65990653 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bPartition.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bPartition.h @@ -177,6 +177,26 @@ class bPartition helpGetNghIdx(const Idx& idx, const typename Idx::DataBlockIdx* blockConnectivity) const -> Idx; +#if !defined(NEON_WARP_COMPILATION) + inline static void getOffsets(size_t* offsets, size_t* length) { + static std::vector cpp_offsets = { + offsetof(bPartition, mCardinality), + offsetof(bPartition, mMem), + offsetof(bPartition, mStencilNghIndex), + offsetof(bPartition, mBlockConnectivity), + offsetof(bPartition, mMask), + offsetof(bPartition, mOrigin), + offsetof(bPartition, mSetIdx), + offsetof(bPartition, mMultiResDiscreteIdxSpacing), + offsetof(bPartition, mDomainSize), + }; + + *length = cpp_offsets.size(); + for (size_t i = 0; i < cpp_offsets.size(); ++i) { + offsets[i] = cpp_offsets[i]; + } + } +#endif int mCardinality; T* mMem; diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h index 34ec5def..b04b8b43 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h @@ -44,7 +44,11 @@ class bSpan NEON_CUDA_HOST_DEVICE inline auto setAndValidateGPUDevice( Idx& bidx) const -> bool; - + #if !defined(NEON_WARP_COMPILATION) + // Function to get offsets of member variables + static void getOffsets(size_t* offsets, size_t* length); + #endif + // We don't need to have a count on active blocks typename Idx::DataBlockCount mFirstDataBlockOffset; typename SBlock::BitMask const* NEON_RESTRICT mActiveMask; diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h index 61b9f8c9..821b54e3 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h @@ -1,3 +1,5 @@ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" #include "Neon/domain/details/bGrid/bSpan.h" namespace Neon::domain::details::bGrid { @@ -29,7 +31,7 @@ bSpan::setAndValidateCPUDevice(Idx& bidx, uint32_t const& z) const -> bool { - bidx.mDataBlockIdx = dataBlockIdx + mFirstDataBlockOffset; + bidx.mDataBlockIdx = dataBlockIdx; bidx.mInDataBlockIdx.x = static_cast(x); bidx.mInDataBlockIdx.y = static_cast(y); bidx.mInDataBlockIdx.z = static_cast(z); @@ -47,42 +49,22 @@ bSpan::bSpan(typename Idx::DataBlockCount firstDataBloc { } - -// #if !defined(NEON_WARP_COMPILATION) -// template -// // std::vector bSpan::getOffsets() { -// // return { -// // // can't use the `offsetof` macro here since bSpan is a template type -// // 0, -// // sizeof(Idx::DataBlockCount), -// // sizeof(Idx::DataBlockCount) + sizeof(SBlock::BitMask*) -// // }; -// // } -// std::vector bSpan::getOffsets() { -// std::vector offsets; -// bSpan temp(typename Idx::DataBlockCount(), nullptr, Neon::DataView()); - -// offsets.push_back(reinterpret_cast(&(temp.mFirstDataBlockOffset)) - reinterpret_cast(&temp)); -// offsets.push_back(reinterpret_cast(&(temp.mActiveMask)) - reinterpret_cast(&temp)); -// offsets.push_back(reinterpret_cast(&(temp.mDataView)) - reinterpret_cast(&temp)); - -// return offsets; -// } -// #endif - #if !defined(NEON_WARP_COMPILATION) template -inline std::vector bSpan::getOffsets() { - bSpan temp({0}, nullptr, {}); - - // Calculate offsets directly - std::vector offsets; - offsets.push_back(reinterpret_cast(&(temp.mFirstDataBlockOffset)) - reinterpret_cast(&temp)); - offsets.push_back(reinterpret_cast(&(temp.mActiveMask)) - reinterpret_cast(&temp)); - offsets.push_back(reinterpret_cast(&(temp.mDataView)) - reinterpret_cast(&temp)); +inline void bSpan::getOffsets(size_t* offsets, size_t* length) { + static std::vector cpp_offsets = { + offsetof(bSpan, mFirstDataBlockOffset), + offsetof(bSpan, mActiveMask), + offsetof(bSpan, mDataView) + }; - return offsets; + *length = cpp_offsets.size(); + for (size_t i = 0; i < cpp_offsets.size(); ++i) { + offsets[i] = cpp_offsets[i]; + } } #endif -} // namespace Neon::domain::details::bGrid \ No newline at end of file +} // namespace Neon::domain::details::bGrid + +#pragma GCC diagnostic pop diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h b/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h index b324cddb..2ed747f5 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h @@ -487,6 +487,34 @@ class dPartition return s.str(); } +#if !defined(NEON_WARP_COMPILATION) + inline static void getOffsets(size_t* offsets, size_t* length) { + // std::cout << "dGrid_dField_dPartition cpp offsets: " << offsetof(dSpan, mDataView) << " " << offsetof(dSpan, mZghostRadius) << " " << offsetof(dSpan, mZboundaryRadius) << " " << offsetof(dSpan, mMaxZInDomain) << " " << offsetof(dSpan, mSpanDim) << " " << std::endl; + static std::vector cpp_offsets = { + offsetof(dPartition, mDataView), + offsetof(dPartition, mDim), + offsetof(dPartition, mMem), + offsetof(dPartition, mZHaloRadius), + offsetof(dPartition, mZBoundaryRadius), + offsetof(dPartition, mPitch.x), + offsetof(dPartition, mPitch.y), + offsetof(dPartition, mPitch.z), + offsetof(dPartition, mPitch.w), + offsetof(dPartition, mPrtID), + offsetof(dPartition, mOrigin), + offsetof(dPartition, mCardinality), + offsetof(dPartition, mFullGridSize), + offsetof(dPartition, mPeriodicZ), + offsetof(dPartition, mStencil), + }; + + *length = cpp_offsets.size(); + for (size_t i = 0; i < cpp_offsets.size(); ++i) { + offsets[i] = cpp_offsets[i]; + } + } +#endif + private: Neon::DataView mDataView; Neon::index_3d mDim; diff --git a/libNeonDomain/include/Neon/domain/details/mGrid/mPartition.h b/libNeonDomain/include/Neon/domain/details/mGrid/mPartition.h index 4080bc7d..f9c0f620 100644 --- a/libNeonDomain/include/Neon/domain/details/mGrid/mPartition.h +++ b/libNeonDomain/include/Neon/domain/details/mGrid/mPartition.h @@ -1,3 +1,5 @@ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Winvalid-offsetof" #pragma once @@ -184,6 +186,36 @@ class mPartition : public Neon::domain::details::bGrid::bPartition cpp_offsets = { + offsetof(mPartition, mCardinality), + offsetof(mPartition, mMem), + offsetof(mPartition, mStencilNghIndex), + offsetof(mPartition, mBlockConnectivity), + offsetof(mPartition, mMask), + offsetof(mPartition, mOrigin), + offsetof(mPartition, mSetIdx), + offsetof(mPartition, mMultiResDiscreteIdxSpacing), + offsetof(mPartition, mDomainSize), + offsetof(mPartition, mLevel), + offsetof(mPartition, mMemParent), + offsetof(mPartition, mMemChild), + offsetof(mPartition, mParentBlockID), + offsetof(mPartition, mMaskLowerLevel), + offsetof(mPartition, mMaskUpperLevel), + offsetof(mPartition, mChildBlockID), + offsetof(mPartition, mParentNeighbourBlocks), + offsetof(mPartition, mRefFactors), + offsetof(mPartition, mSpacing), + }; + + *length = cpp_offsets.size(); + for (size_t i = 0; i < cpp_offsets.size(); ++i) { + offsets[i] = cpp_offsets[i]; + } + } +#endif private: inline NEON_CUDA_HOST_DEVICE auto childID(const Idx& gidx) const -> uint32_t; @@ -202,4 +234,6 @@ class mPartition : public Neon::domain::details::bGrid::bPartitionspanTable.getSpan(execution, setIdx, dataView); } - auto dGrid::helpGetPartitionDim() const -> const Neon::set::DataSet { diff --git a/libNeonPy/include/Neon/py/bGrid.h b/libNeonPy/include/Neon/py/bGrid.h index 9e3944de..c525cb71 100644 --- a/libNeonPy/include/Neon/py/bGrid.h +++ b/libNeonPy/include/Neon/py/bGrid.h @@ -5,11 +5,12 @@ /** * Initialize a new grid object on the heap. * NOTE: some parameters are still not exposed - */ /* TODOMATT fix the constructor to have correct arguments */ + */ extern "C" auto bGrid_new( uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim) + uint64_t& backendPtr, + const Neon::int32_3d* dim, + int* sparsity_pattern) -> int; /** @@ -19,12 +20,18 @@ extern "C" auto bGrid_delete( uint64_t& handle) -> int; +extern "C" auto bGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int; + /** * Generates a new field object on the heap. */ extern "C" auto bGrid_bField_new( - uint64_t& handle, - uint64_t& grid) + uint64_t& fieldHandle, + uint64_t& gridHandle, + int cardinality) -> int; /** @@ -60,24 +67,24 @@ extern "C" auto bGrid_bField_partition_size( extern "C" auto bGrid_get_properties( /* TODOMATT verify what the return of this method should be */ uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* idx) -> int; extern "C" auto bGrid_is_inside_domain( uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> bool; extern "C" auto bGrid_bField_read( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality) + const Neon::index_3d* idx, + const int cardinality) -> int; extern "C" auto bGrid_bField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality, + const Neon::index_3d* idx, + const int cardinality, int newValue) -> int; @@ -91,5 +98,9 @@ extern "C" auto bGrid_bField_update_device_data( int streamSetId) -> int; -extern "C" auto dGrid_dSpan_get_member_field_offsets(std::size_t* length) - -> std::size_t*; \ No newline at end of file +extern "C" auto bGrid_bSpan_get_member_field_offsets(size_t* offsets, size_t* length) + -> void; + + +extern "C" auto bGrid_bField_bPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void; \ No newline at end of file diff --git a/libNeonPy/include/Neon/py/backend.h b/libNeonPy/include/Neon/py/backend.h index 09a5a391..6c7ba563 100644 --- a/libNeonPy/include/Neon/py/backend.h +++ b/libNeonPy/include/Neon/py/backend.h @@ -2,35 +2,16 @@ #include #include "Neon/set/Backend.h" - -///** -// * Empty constructor -// */ -//extern "C" auto dBackend_new1( -// uint64_t& handle) -// -> int; -// -///** -// * Creating a Backend object with the first nGpus devices. -// */ -//extern "C" auto dBackend_new2( -// uint64_t& handle, -// int nGpus /*! Number of devices. The devices are selected in the order specifies by CUDA */, -// int runtime /*! Type of runtime to use */) -// -> int; - /** * */ extern "C" auto dBackend_new( uint64_t& handle, - int runtime /*! Type of runtime to use */, - int numDecices /*! Number of devices */, - const int* devIds /*! Vectors of device ids. There are CUDA device ids */ - ) + int runtime /*! Type of runtime to use */, + int numDecices /*! Number of devices */, + const int* devIds /*! Vectors of device ids. There are CUDA device ids */) -> int; - /** * Delete a backend object on the heap. */ @@ -38,6 +19,6 @@ extern "C" auto dBackend_delete( uint64_t& handle) -> int; - extern "C" auto dBackend_get_string(uint64_t& handle) -> const char*; +extern "C" auto dBackend_sync(uint64_t& handle) -> int; diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index 201a24ae..8adc41a6 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -9,13 +9,9 @@ extern "C" auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d* dim) + const Neon::int32_3d* dim, + int* sparsity_pattern) -> int; -// extern "C" auto dGrid_new( -// uint64_t& handle, -// uint64_t& backendPtr, -// Neon::index_3d dim) -// -> int; /** * Delete a grid object on the heap. @@ -24,12 +20,18 @@ extern "C" auto dGrid_delete( uint64_t& handle) -> int; +extern "C" auto dGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int; + /** * Generates a new field object on the heap. */ extern "C" auto dGrid_dField_new( uint64_t& handle, - uint64_t& grid) + uint64_t& grid, + int cardinality) -> int; /** @@ -63,26 +65,26 @@ extern "C" auto dGrid_dField_partition_size( Neon::dGrid::Partition* partitionPtr) -> int; -extern "C" auto dGrid_get_properties( /* TODOMATT verify what the return of this method should be */ +extern "C" auto dGrid_get_properties( uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> int; extern "C" auto dGrid_is_inside_domain( uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> bool; extern "C" auto dGrid_dField_read( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality) + const Neon::index_3d* idx, + int cardinality) -> int; extern "C" auto dGrid_dField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality, + const Neon::index_3d* idx, + int cardinality, int newValue) -> int; @@ -96,5 +98,8 @@ extern "C" auto dGrid_dField_update_device_data( int streamSetId) -> int; -extern "C" auto bGrid_bSpan_get_member_field_offsets(size_t* offsets, size_t* length) - -> void; \ No newline at end of file +extern "C" auto dGrid_dSpan_get_member_field_offsets(size_t* offsets, size_t* length) + -> void; + +extern "C" auto dGrid_dField_dPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void; diff --git a/libNeonPy/include/Neon/py/mGrid.h b/libNeonPy/include/Neon/py/mGrid.h index 4af9a507..b633d2bd 100644 --- a/libNeonPy/include/Neon/py/mGrid.h +++ b/libNeonPy/include/Neon/py/mGrid.h @@ -8,9 +8,10 @@ */ /* TODOMATT fix the constructor to have correct arguments */ extern "C" auto mGrid_new( uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim, - uint32_t& depth) + uint64_t& backendPtr, + const Neon::index_3d* dim, + int* sparsity_pattern, + uint32_t depth) -> int; /** @@ -20,12 +21,18 @@ extern "C" auto mGrid_delete( uint64_t& handle) -> int; +extern "C" auto dGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int; + /** * Generates a new field object on the heap. */ extern "C" auto mGrid_mField_new( uint64_t& handle, - uint64_t& grid) + uint64_t& grid, + int cardinality) -> int; /** @@ -38,7 +45,7 @@ extern "C" auto mGrid_mField_delete( extern "C" auto mGrid_mField_get_partition( uint64_t& field_handle, Neon::domain::mGrid::Partition* partition_handle, - uint64_t& field_level, + uint64_t field_level, Neon::Execution execution, int device, Neon::DataView data_view) @@ -46,7 +53,7 @@ extern "C" auto mGrid_mField_get_partition( extern "C" auto mGrid_get_span( uint64_t& gridHandle, - uint64_t& grid_level, + uint64_t grid_level, Neon::domain::mGrid::Span* spanRes, int execution, int device, @@ -63,28 +70,28 @@ extern "C" auto mGrid_mField_partition_size( extern "C" auto mGrid_get_properties( /* TODOMATT verify what the return of this method should be */ uint64_t& gridHandle, - uint64_t& grid_level, - const Neon::index_3d& idx) + uint64_t grid_level, + const Neon::index_3d* idx) -> int; extern "C" auto mGrid_is_inside_domain( uint64_t& gridHandle, - uint64_t& grid_level, - const Neon::index_3d& idx) + uint64_t grid_level, + const Neon::index_3d* idx) -> bool; extern "C" auto mGrid_mField_read( uint64_t& fieldHandle, - uint64_t& field_level, - const Neon::index_3d& idx, - const int& cardinality) + uint64_t field_level, + const Neon::index_3d* idx, + const int cardinality) -> int; extern "C" auto mGrid_mField_write( uint64_t& fieldHandle, - uint64_t& field_level, - const Neon::index_3d& idx, - const int& cardinality, + uint64_t field_level, + const Neon::index_3d* idx, + const int cardinality, int newValue) -> int; @@ -96,4 +103,9 @@ extern "C" auto mGrid_mField_update_host_data( extern "C" auto mGrid_mField_update_device_data( uint64_t& fieldHandle, int streamSetId) - -> int; \ No newline at end of file + -> int; + +extern "C" auto mGrid_mField_mPartition_get_member_field_offsets( + size_t* offsets, + size_t* length) + -> void; diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index 04143e82..30759578 100644 --- a/libNeonPy/src/Neon/py/bGrid.cpp +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -6,7 +6,8 @@ auto bGrid_new( uint64_t& handle, uint64_t& backendPtr, - Neon::index_3d dim) + const Neon::index_3d* dim, + int* sparsity_pattern) -> int { std::cout << "bGrid_new - BEGIN" << std::endl; @@ -15,8 +16,15 @@ auto bGrid_new( Neon::init(); using Grid = Neon::bGrid; + + Neon::Backend* backend = reinterpret_cast(backendPtr); + if (backend == nullptr) { + std::cerr << "Invalid backend pointer" << std::endl; + return -1; + } + Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); - Grid g(*reinterpret_cast(backendPtr), dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); + Grid g(*backend, *dim, [=](Neon::index_3d const& idx) { return sparsity_pattern[idx.x * (dim->x * dim->y) + idx.y * dim->z + idx.z ]; }, d3q19); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); @@ -50,6 +58,34 @@ auto bGrid_delete( return 0; } +extern "C" auto bGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int +{ + std::cout << "bGrid_get_dimension - BEGIN" << std::endl; + std::cout << "bGrid_get_dimension - gridHandle " << gridHandle << std::endl; + + + using Grid = Neon::bGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + + if (gridPtr == nullptr) { + std::cout << "NeonPy: gridHandle is invalid " << std::endl; + return -1; + } + + auto dimension = gridPtr->getDimension(); + dim->x = dimension.x; + dim->y = dimension.y; + dim->z = dimension.z; + + std::cout << "bGrid_get_dimension - END" << std::endl; + + // g.ioDomainToVtk("") + return 0; +} + auto bGrid_get_span( uint64_t& gridHandle, Neon::bGrid::Span* spanRes, @@ -82,13 +118,14 @@ auto bGrid_get_span( } auto bGrid_bField_new( - uint64_t& handle, - uint64_t& gridHandle) + uint64_t& fieldHandle, + uint64_t& gridHandle, + int cardinality) -> int { std::cout << "bGrid_bField_new - BEGIN" << std::endl; std::cout << "bGrid_bField_new - gridHandle " << gridHandle << std::endl; - std::cout << "bGrid_bField_new - handle " << handle << std::endl; + std::cout << "bGrid_bField_new - fieldHandle " << fieldHandle << std::endl; using Grid = Neon::bGrid; Grid* gridPtr = reinterpret_cast(gridHandle); @@ -96,7 +133,7 @@ auto bGrid_bField_new( if (gridPtr != nullptr) { using Field = Grid::Field; - Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); + Field field = grid.newField("test", cardinality, 0, Neon::DataUse::HOST_DEVICE); std::cout << field.toString() << std::endl; Field* fieldPtr = new (std::nothrow) Field(field); AllocationCounter::Allocation(); @@ -105,8 +142,9 @@ auto bGrid_bField_new( std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; return -1; } - handle = (uint64_t)fieldPtr; - std::cout << "bGrid_bField_new - END " << handle << std::endl; + + fieldHandle = (uint64_t)fieldPtr; + std::cout << "bGrid_bField_new - END " << fieldHandle << std::endl; return 0; } @@ -165,6 +203,8 @@ auto bGrid_bField_delete( delete fieldPtr; AllocationCounter::Deallocation(); } + + handle = 0; std::cout << "bGrid_bField_delete - END" << std::endl; return 0; @@ -186,14 +226,14 @@ auto bGrid_bField_partition_size( auto bGrid_get_properties( /* TODOMATT verify what the return of this method should be */ uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* idx) -> int { std::cout << "bGrid_get_properties begin" << std::endl; using Grid = Neon::bGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - int returnValue = int(gridPtr->getProperties(idx).getDataView()); + int returnValue = int(gridPtr->getProperties(*idx).getDataView()); std::cout << "bGrid_get_properties end" << std::endl; return returnValue; @@ -201,14 +241,14 @@ auto bGrid_get_properties( /* TODOMATT verify what the return of this method sho auto bGrid_is_inside_domain( uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> bool { std::cout << "bGrid_is_inside_domain begin" << std::endl; using Grid = Neon::bGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - bool returnValue = gridPtr->isInsideDomain(idx); + bool returnValue = gridPtr->isInsideDomain(*idx); std::cout << "bGrid_is_inside_domain end" << std::endl; @@ -218,8 +258,8 @@ auto bGrid_is_inside_domain( auto bGrid_bField_read( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality) + const Neon::index_3d* idx, + const int cardinality) -> int { std::cout << "bGrid_bField_read begin" << std::endl; @@ -233,7 +273,7 @@ auto bGrid_bField_read( std::cout << "invalid field" << std::endl; } - auto returnValue = (*fieldPtr)(idx, cardinality); + auto returnValue = (*fieldPtr)(*idx, cardinality); std::cout << "bGrid_bField_read end" << std::endl; @@ -242,8 +282,8 @@ auto bGrid_bField_read( auto bGrid_bField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality, + const Neon::index_3d* idx, + const int cardinality, int newValue) -> int { @@ -258,8 +298,8 @@ auto bGrid_bField_write( std::cout << "invalid field" << std::endl; return -1; } - - fieldPtr->getReference(idx, cardinality) = newValue; + + fieldPtr->getReference(*idx, cardinality) = newValue; std::cout << "bGrid_bField_write end" << std::endl; return 0; @@ -311,10 +351,14 @@ auto bGrid_bField_update_device_data( return 0; } -extern "C" auto bGrid_bSpan_get_member_field_offsets(std::size_t* length) - -> std::size_t* +extern "C" auto bGrid_bSpan_get_member_field_offsets(size_t* offsets, size_t* length) + -> void { - std::vector offsets = Neon::domain::details::bGrid::bSpan::getOffsets(); // @TODOMATT I am not sure if it should be templated with or with something else, but I think so? - *length = offsets.size(); - return offsets.data(); -} \ No newline at end of file + Neon::domain::details::bGrid::bSpan::getOffsets(offsets, length); +} + +extern "C" auto bGrid_bField_bPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void +{ + Neon::domain::details::bGrid::bPartition::getOffsets(offsets, length); +} diff --git a/libNeonPy/src/Neon/py/backend.cpp b/libNeonPy/src/Neon/py/backend.cpp index 351d5caa..406ce47f 100644 --- a/libNeonPy/src/Neon/py/backend.cpp +++ b/libNeonPy/src/Neon/py/backend.cpp @@ -2,6 +2,7 @@ #include "Neon/set/Backend.h" #include "Neon/py/AllocationCounter.h" #include "Neon/Neon.h" + void backend_constructor_prologue(uint64_t& handle) { std::cout << "dBackend_new - BEGIN" << std::endl; std::cout << "dBackend handle" << handle << std::endl; @@ -18,35 +19,6 @@ int backend_constructor_epilogue(uint64_t& handle, Neon::Backend* backendPtr) { return 0; } -//auto dBackend_new1( -// uint64_t& handle) -// -> int -//{ -// std::cout << "first constructor" << std::endl; -// AllocationCounter::Allocation(); -// -// backend_constructor_prologue(handle); -// -// auto backendPtr = new (std::nothrow) Neon::Backend(); -// -// return backend_constructor_epilogue(handle, backendPtr); -//} -// -//auto dBackend_new2( -// uint64_t& handle, -// int nGpus, -// int runtime) -// -> int -//{ -// std::cout << "second constructor" << std::endl; -// AllocationCounter::Allocation(); -// backend_constructor_prologue(handle); -// -// auto backendPtr = new (std::nothrow) Neon::Backend(nGpus, Neon::Runtime(runtime)); -// -// return backend_constructor_epilogue(handle, backendPtr); -//} - auto dBackend_new( uint64_t& handle, int runtime, @@ -90,6 +62,25 @@ auto dBackend_get_string(uint64_t& handle) -> const char* { using Backend = Neon::Backend; Backend* backendPtr = (Backend*)handle; + if (backendPtr == nullptr) { + return "Backend handle is invalid"; + } return backendPtr->toString().c_str(); + std::cout << "get_string - END" << std::endl; +} + +auto dBackend_sync(uint64_t& handle) -> int { + std::cout << "dBackend_sync - BEGIN" << std::endl; + std::cout << "backendHandle " << handle << std::endl; + + using Backend = Neon::Backend; + Backend* backendPtr = (Backend*)handle; + if (backendPtr == nullptr) { + return -1; + } + backendPtr->syncAll(); + + return 0; + std::cout << "dBackend_sync - END" << std::endl; } diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index 3d67bc49..214d16b8 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -6,7 +6,8 @@ auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d* dim) + const Neon::index_3d* dim, + int* sparsity_pattern) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -21,11 +22,10 @@ auto dGrid_new( std::cerr << "Invalid backend pointer" << std::endl; return -1; } - std::cerr << dim->x << " " << dim->y << " " << dim->z << std::endl; - // Neon::int32_3d dim{x,y,z}; + // Neon::index_3d dim{x,y,z}; Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); - Grid g(*backend, *dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); + Grid g(*backend, *dim, [=](Neon::index_3d const& idx) { return sparsity_pattern[idx.x * (dim->x * dim->y) + idx.y * dim->z + idx.z ]; }, d3q19); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); @@ -39,40 +39,6 @@ auto dGrid_new( // g.ioDomainToVtk("") return 0; } -// auto dGrid_new( -// uint64_t& handle, -// uint64_t& backendPtr) -// Neon::index_3d dim, -// -> int -// { -// std::cout << "dGrid_new - BEGIN" << std::endl; -// std::cout << "dGrid_new - gridHandle " << handle << std::endl; - -// Neon::init(); - -// using Grid = Neon::dGrid; - -// Neon::Backend* backend = reinterpret_cast(backendPtr); -// if (backend == nullptr) { -// std::cerr << "Invalid backend pointer" << std::endl; -// return -1; -// } -// std::cerr << dim.x << " " << dim.y << " " << dim.z << std::endl; -// Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); -// Grid g(*backend, dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); -// auto gridPtr = new (std::nothrow) Grid(g); -// AllocationCounter::Allocation(); - -// if (gridPtr == nullptr) { -// std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; -// return -1; -// } -// handle = reinterpret_cast(gridPtr); -// std::cout << "grid_new - END" << std::endl; - -// // g.ioDomainToVtk("") -// return 0; -// } auto dGrid_delete( uint64_t& handle) @@ -93,6 +59,34 @@ auto dGrid_delete( return 0; } +extern "C" auto dGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int +{ + std::cout << "dGrid_get_dimension - BEGIN" << std::endl; + std::cout << "dGrid_get_dimension - gridHandle " << gridHandle << std::endl; + + + using Grid = Neon::dGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + + if (gridPtr == nullptr) { + std::cout << "NeonPy: gridHandle is invalid " << std::endl; + return -1; + } + + auto dimension = gridPtr->getDimension(); + dim->x = dimension.x; + dim->y = dimension.y; + dim->z = dimension.z; + + std::cout << "dGrid_get_dimension - END" << std::endl; + + // g.ioDomainToVtk("") + return 0; +} + auto dGrid_get_span( uint64_t& gridHandle, Neon::dGrid::Span* spanRes, @@ -126,7 +120,8 @@ auto dGrid_get_span( auto dGrid_dField_new( uint64_t& handle, - uint64_t& gridHandle) + uint64_t& gridHandle, + int cardinality) -> int { std::cout << "dGrid_dField_new - BEGIN" << std::endl; @@ -139,7 +134,7 @@ auto dGrid_dField_new( if (gridPtr != nullptr) { using Field = Grid::Field; - Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); + Field field = grid.newField("test", cardinality, 0, Neon::DataUse::HOST_DEVICE); std::cout << field.toString() << std::endl; Field* fieldPtr = new (std::nothrow) Field(field); AllocationCounter::Allocation(); @@ -211,6 +206,8 @@ auto dGrid_dField_delete( delete fieldPtr; AllocationCounter::Deallocation(); } + + handle = 0; std::cout << "dGrid_dField_delete - END" << std::endl; return 0; @@ -232,29 +229,31 @@ auto dGrid_dField_partition_size( auto dGrid_get_properties( /* TODOMATT verify what the return of this method should be */ uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> int { std::cout << "dGrid_get_properties begin" << std::endl; using Grid = Neon::dGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - int returnValue = int(gridPtr->getProperties(idx).getDataView()); + + int result = static_cast(gridPtr->getProperties(*idx).getDataView()); std::cout << "dGrid_get_properties end" << std::endl; - return returnValue; + return result; } auto dGrid_is_inside_domain( uint64_t& gridHandle, - const Neon::index_3d& idx) + const Neon::index_3d* const idx) -> bool { std::cout << "dGrid_is_inside_domain begin" << std::endl; using Grid = Neon::dGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - bool returnValue = gridPtr->isInsideDomain(idx); + + bool returnValue = gridPtr->isInsideDomain(*idx); std::cout << "dGrid_is_inside_domain end" << std::endl; @@ -264,8 +263,8 @@ auto dGrid_is_inside_domain( auto dGrid_dField_read( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality) + const Neon::index_3d* idx, + const int cardinality) -> int { std::cout << "dGrid_dField_read begin" << std::endl; @@ -279,7 +278,7 @@ auto dGrid_dField_read( std::cout << "invalid field" << std::endl; } - auto returnValue = (*fieldPtr)(idx, cardinality); + auto returnValue = (*fieldPtr)(*idx, cardinality); std::cout << "dGrid_dField_read end" << std::endl; @@ -288,8 +287,8 @@ auto dGrid_dField_read( auto dGrid_dField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, - const int& cardinality, + const Neon::index_3d* idx, + int cardinality, int newValue) -> int { @@ -305,7 +304,7 @@ auto dGrid_dField_write( return -1; } - fieldPtr->getReference(idx, cardinality) = newValue; + fieldPtr->getReference(*idx, cardinality) = newValue; std::cout << "dGrid_dField_write end" << std::endl; return 0; @@ -363,3 +362,8 @@ extern "C" auto dGrid_dSpan_get_member_field_offsets(size_t* offsets, size_t* le Neon::domain::details::dGrid::dSpan::getOffsets(offsets, length); } +extern "C" auto dGrid_dField_dPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void +{ + Neon::domain::details::dGrid::dPartition::getOffsets(offsets, length); +} diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp index 9983031d..093ce32e 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -4,9 +4,10 @@ auto mGrid_new( uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim, - uint32_t& depth) + uint64_t& backendPtr, + const Neon::index_3d* dim, + int* sparsity_pattern, + uint32_t depth) -> int { std::cout << "mGrid_new - BEGIN" << std::endl; @@ -15,9 +16,16 @@ auto mGrid_new( Neon::init(); using Grid = Neon::domain::mGrid; + + Neon::Backend* backend = reinterpret_cast(backendPtr); + if (backend == nullptr) { + std::cerr << "Invalid backend pointer" << std::endl; + return -1; + } + Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); // @TODOMATT define/use a multiresolution constructor for Grid g (talk to max about this) - Grid g(*backendPtr, dim, std::vector>{[](Neon::index_3d const& /*idx*/) { return true; }}, d3q19, Grid::Descriptor(depth)); + Grid g(*backend, *dim, std::vector>{[=](Neon::index_3d const& idx) { return sparsity_pattern[idx.x * (dim->x * dim->y) + idx.y * dim->z + idx.z ]; }}, d3q19, Grid::Descriptor(depth)); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); @@ -53,9 +61,37 @@ auto mGrid_delete( return 0; } +extern "C" auto mGrid_get_dimensions( + uint64_t& gridHandle, + Neon::index_3d* dim) + -> int +{ + std::cout << "mGrid_get_dimension - BEGIN" << std::endl; + std::cout << "mGrid_get_dimension - gridHandle " << gridHandle << std::endl; + + + using Grid = Neon::domain::mGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + + if (gridPtr == nullptr) { + std::cout << "NeonPy: gridHandle is invalid " << std::endl; + return -1; + } + + auto dimension = gridPtr->getDimension(); + dim->x = dimension.x; + dim->y = dimension.y; + dim->z = dimension.z; + + std::cout << "mGrid_get_dimension - END" << std::endl; + + // g.ioDomainToVtk("") + return 0; +} + auto mGrid_get_span( uint64_t& gridHandle, - uint64_t& grid_level, + uint64_t grid_level, Neon::domain::mGrid::Span* spanRes, int execution, int device, @@ -90,29 +126,30 @@ auto mGrid_get_span( } auto mGrid_mField_new( - uint64_t& handle, - uint64_t& gridHandle) + uint64_t& fieldHandle, + uint64_t& gridHandle, + int cardinality) -> int { std::cout << "mGrid_mField_new - BEGIN" << std::endl; - std::cout << "mGrid_mField_new - gridHandle " << gridHandle << std::endl; - std::cout << "mGrid_mField_new - handle " << handle << std::endl; + std::cout << "mGrid_mField_new - fieldHandle: " << fieldHandle << std::endl; + std::cout << "mGrid_mField_new - gridHandle: " << gridHandle << std::endl; using Grid = Neon::domain::mGrid; using Field = Grid::Field; - Grid* gridPtr = reinterpret_cast(handle); + Grid* gridPtr = reinterpret_cast(gridHandle); Grid& grid = *gridPtr; if (gridPtr != nullptr) { - Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); + Field field = grid.newField("test", cardinality, 0, Neon::DataUse::HOST_DEVICE); Field* fieldPtr = new (std::nothrow) Field(field); if (fieldPtr == nullptr) { std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; return -1; } AllocationCounter::Allocation(); - handle = (uint64_t)fieldPtr; - std::cout << "mGrid_mField_new - END " << handle << std::endl; + fieldHandle = (uint64_t)fieldPtr; + std::cout << "mGrid_mField_new - END fieldHandle: " << fieldHandle << std::endl; return 0; } @@ -124,7 +161,7 @@ auto mGrid_mField_new( auto mGrid_mField_get_partition( uint64_t& field_handle, [[maybe_unused]] Neon::domain::mGrid::Partition* partitionPtr, - uint64_t& field_level, + uint64_t field_level, Neon::Execution execution, int device, Neon::DataView data_view) @@ -178,8 +215,9 @@ auto mGrid_mField_delete( if (fieldPtr != nullptr) { delete fieldPtr; - AllocationCounter::Allocation(); + AllocationCounter::Deallocation(); } + handle = 0; std::cout << "mGrid_mField_delete - END" << std::endl; return 0; @@ -201,8 +239,8 @@ auto mGrid_mField_partition_size( auto mGrid_get_properties( /* TODOMATT verify what the return of this method should be */ uint64_t& gridHandle, - uint64_t& grid_level, - const Neon::index_3d& idx) + uint64_t grid_level, + const Neon::index_3d* idx) -> int { std::cout << "mGrid_get_properties begin" << std::endl; @@ -212,7 +250,8 @@ auto mGrid_get_properties( /* TODOMATT verify what the return of this method sho if (grid_level >= gridPtr->getGridCount()) { std::cout << "grid_level out of range in mGrid_get_properties" << std::endl; } - int returnValue = int((*gridPtr)(grid_level).getProperties(idx).getDataView()); + + int returnValue = int((*gridPtr)(grid_level).getProperties(*idx).getDataView()); std::cout << "mGrid_get_properties end" << std::endl; return returnValue; @@ -220,8 +259,8 @@ auto mGrid_get_properties( /* TODOMATT verify what the return of this method sho auto mGrid_is_inside_domain( uint64_t& gridHandle, - uint64_t& grid_level, - const Neon::index_3d& idx + uint64_t grid_level, + const Neon::index_3d* idx ) -> bool { @@ -229,19 +268,19 @@ auto mGrid_is_inside_domain( using Grid = Neon::domain::mGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - bool returnValue = gridPtr->isInsideDomain(idx, grid_level); - - std::cout << "mGrid_is_inside_domain end" << std::endl; + bool returnValue = gridPtr->isInsideDomain(*idx, grid_level); + std::cout << "mGrid_is_inside_domain end" << std::endl; + return returnValue; } auto mGrid_mField_read( uint64_t& fieldHandle, - uint64_t& field_level, - const Neon::index_3d& idx, - const int& cardinality) + uint64_t field_level, + const Neon::index_3d* idx, + const int cardinality) -> int { std::cout << "mGrid_mField_read begin" << std::endl; @@ -255,7 +294,7 @@ auto mGrid_mField_read( std::cout << "invalid field" << std::endl; } - auto returnValue = (*fieldPtr)(idx, cardinality, field_level); + auto returnValue = (*fieldPtr)(*idx, cardinality, field_level); std::cout << "mGrid_mField_read end" << std::endl; @@ -264,9 +303,9 @@ auto mGrid_mField_read( auto mGrid_mField_write( uint64_t& fieldHandle, - uint64_t& field_level, - const Neon::index_3d& idx, - const int& cardinality, + uint64_t field_level, + const Neon::index_3d* idx, + const int cardinality, int newValue) -> int { @@ -282,7 +321,7 @@ auto mGrid_mField_write( return -1; } - fieldPtr->getReference(idx, cardinality, field_level) = newValue; + fieldPtr->getReference(*idx, cardinality, field_level) = newValue; std::cout << "mGrid_mField_write end" << std::endl; return 0; @@ -332,4 +371,10 @@ auto mGrid_mField_update_device_data( std::cout << "mGrid_mField_update_device_data end" << std::endl; return 0; -} \ No newline at end of file +} + +extern "C" auto mGrid_mField_mPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void +{ + Neon::domain::mGrid::Partition::getOffsets(offsets, length); +} diff --git a/py_neon/__init__.py b/py_neon/__init__.py index e97f00dc..31126aad 100644 --- a/py_neon/__init__.py +++ b/py_neon/__init__.py @@ -8,6 +8,9 @@ from .index_3d import Index_3d from .dense.__init__ import * +from .block.__init__ import * +from .multires.__init__ import * + # # diff --git a/py_neon/allocationCounter.py b/py_neon/allocationCounter.py index 28d3a06c..d860e9f8 100644 --- a/py_neon/allocationCounter.py +++ b/py_neon/allocationCounter.py @@ -15,13 +15,12 @@ def __init__(self): except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() + self._help_load_api() - def help_load_api(self): + def _help_load_api(self): # Importing new functions self.py_neon.lib.get_allocation_counter.argtypes = [] self.py_neon.lib.get_allocation_counter.restype = ctypes.c_int def get_allocation_count(self): return self.py_neon.lib.get_allocation_counter() - \ No newline at end of file diff --git a/py_neon/backend.py b/py_neon/backend.py index 436baf6d..d7780615 100644 --- a/py_neon/backend.py +++ b/py_neon/backend.py @@ -1,11 +1,12 @@ import ctypes from enum import Enum -from typing import List +from typing import List, Optional import numpy as np from py_neon import Py_neon +# TODOMATT why are these functions called dBackend_XXX, it should just be Backend_XXX class Backend(object): class Runtime(Enum): @@ -17,7 +18,11 @@ class Runtime(Enum): def __init__(self, runtime: Runtime = Runtime.openmp, n_dev: int = 1, - dev_idx_list: List[int] = [0]): + dev_idx_list: Optional[List[int]] = None): + + # having a default list specified in the constructor might cause problems + if dev_idx_list is None: + dev_idx_list = [0] self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) try: @@ -25,15 +30,16 @@ def __init__(self, except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() - self.help_backend_new(runtime, n_dev, dev_idx_list) + + self._help_load_api() + self._help_backend_new(runtime, n_dev, dev_idx_list) def __del__(self): if self.handle == 0: return self.help_backend_delete() - def help_load_api(self): + def _help_load_api(self): # # backend_new # self.py_neon.lib.dBackend_new1.argtypes = [self.py_neon.handle_type] @@ -61,10 +67,13 @@ def help_load_api(self): self.py_neon.lib.dBackend_get_string.argtypes = [self.py_neon.handle_type] self.py_neon.lib.dBackend_get_string.restype = ctypes.c_char_p + self.py_neon.lib.dBackend_sync.argtypes = [self.py_neon.handle_type] + self.py_neon.lib.dBackend_sync.restype = ctypes.c_int + # TODOMATT get num devices # TODOMATT get device type - def help_backend_new(self, + def _help_backend_new(self, runtime: Runtime, n_dev: int, dev_idx_list: List[int]): @@ -92,6 +101,9 @@ def help_backend_delete(self): res = self.py_neon.lib.dBackend_delete(self.handle) if res != 0: raise Exception('Failed to delete backend') + + def sync(self): + return self.py_neon.lib.dBackend_sync(ctypes.byref(self.handle)) def __str__(self): return ctypes.cast(self.py_neon.lib.get_string(self.handle), ctypes.c_char_p).value.decode('utf-8') diff --git a/py_neon/block/__init__.py b/py_neon/block/__init__.py index e69de29b..5c893fce 100644 --- a/py_neon/block/__init__.py +++ b/py_neon/block/__init__.py @@ -0,0 +1,8 @@ +from py_neon.backend import Backend + +from .bGrid import bGrid +from .bField import bField +from .bSpan import bSpan +from .bPartition import bPartitionInt + +from py_neon.allocationCounter import allocationCounter diff --git a/py_neon/block/bField.py b/py_neon/block/bField.py index e7febaf1..9d114b01 100644 --- a/py_neon/block/bField.py +++ b/py_neon/block/bField.py @@ -2,35 +2,37 @@ import ctypes from enum import Enum import py_neon +from py_neon import Py_neon from .bPartition import bPartitionInt as NeBPartitionInt from py_neon.execution import Execution as NeExecution from py_neon.dataview import DataView as NeDataView from py_neon.py_ne import Py_neon as NePy_neon from py_neon.index_3d import Index_3d -# TODOMATT ask Max how to reconcile our new partitions with the wpne partitions -# from wpne.dense.partition import NeonDensePartitionInt as Wpne_NeonDensePartitionInt - class bField(object): def __init__(self, - py_neon: NePy_neon, - grid_handle: ctypes.c_uint64 + grid_handle: ctypes.c_uint64, + cardinality: ctypes.c_int ): if grid_handle == 0: - raise Exception('bField: Invalid handle') - - self.py_neon = py_neon + raise Exception('DField: Invalid handle') + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) self.handle_type = ctypes.POINTER(ctypes.c_uint64) self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.grid_handle = grid_handle - self.help_load_api() - self.help_new() + self.cardinality = cardinality + self._help_load_api() + self._help_field_new() def __del__(self): self.help_delete() - def help_load_api(self): + def _help_load_api(self): # Importing new functions ## new_field self.py_neon.lib.bGrid_bField_new.argtypes = [self.handle_type, @@ -56,13 +58,13 @@ def help_load_api(self): # field read self.py_neon.lib.bGrid_bField_read.argtypes = [self.handle_type, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int] self.py_neon.lib.bGrid_bField_read.restype = ctypes.c_int # field write self.py_neon.lib.bGrid_bField_write.argtypes = [self.handle_type, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int, ctypes.c_int] self.py_neon.lib.bGrid_bField_write.restype = ctypes.c_int @@ -77,20 +79,18 @@ def help_load_api(self): ctypes.c_int] self.py_neon.lib.bGrid_bField_update_device_data.restype = ctypes.c_int - - - def help_new(self): + def _help_field_new(self): if self.handle == 0: raise Exception('bGrid: Invalid handle') - res = self.py_neon.lib.bGrid_bField_new(self.handle, self.grid_handle) + res = self.py_neon.lib.bGrid_bField_new(ctypes.byref(self.handle), ctypes.byref(self.grid_handle), self.cardinality) if res != 0: raise Exception('bGrid: Failed to initialize field') def help_delete(self): if self.handle == 0: return - res = self.py_neon.lib.bGrid_bField_delete(self.handle) + res = self.py_neon.lib.bGrid_bField_delete(ctypes.byref(self.handle)) if res != 0: raise Exception('Failed to delete field') @@ -124,15 +124,15 @@ def help_delete(self): # wpne_partition = Wpne_NeonDensePartitionInt(partition) # return wpne_partition - def read(self, idx: Index_3d, cardinality: int): - return self.py_neon.lib.bGrid_bField_read(self.handle, idx, cardinality) + def read(self, idx: Index_3d, cardinality: ctypes.c_int): + return self.py_neon.lib.bGrid_bField_read(ctypes.byref(self.handle), idx, cardinality) - def write(self, idx: Index_3d, cardinality: int, newValue: int): - return self.py_neon.lib.bGrid_bField_write(self.handle, idx, cardinality, newValue) + def write(self, idx: Index_3d, cardinality: ctypes.c_int, newValue: ctypes.c_int): + return self.py_neon.lib.bGrid_bField_write(ctypes.byref(self.handle), idx, cardinality, newValue) def updateHostData(self, streamSetId: int): - return self.py_neon.lib.bGrid_bField_update_host_data(self.handle, streamSetId) + return self.py_neon.lib.bGrid_bField_update_host_data(ctypes.byref(self.handle), streamSetId) def updateDeviceData(self, streamSetId: int): - return self.py_neon.lib.bGrid_bField_update_device_data(self.handle, streamSetId) + return self.py_neon.lib.bGrid_bField_update_device_data(ctypes.byref(self.handle), streamSetId) \ No newline at end of file diff --git a/py_neon/block/bGrid.py b/py_neon/block/bGrid.py index ca75034b..c006b161 100644 --- a/py_neon/block/bGrid.py +++ b/py_neon/block/bGrid.py @@ -8,43 +8,58 @@ from py_neon import Py_neon from py_neon.dataview import DataView from .bSpan import bSpan -from .backend import Backend +from ..backend import Backend from py_neon.index_3d import Index_3d +import numpy as np class bGrid(object): + def __init__(self, backend = None, dim = None, sparsity_pattern: np.ndarray = None): + if sparsity_pattern is None: + sparsity_pattern = np.ones((dim.x,dim.y,dim.z)) + if backend is None: + # raise exception + raise Exception('dGrid: backend pamrameter is missing') + if sparsity_pattern.shape[0] != dim.x or sparsity_pattern.shape[1] != dim.y or sparsity_pattern.shape[2] != dim.z: + raise Exception('dGrid: sparsity_pattern\'s shape does not match the dim') - - def __init__(self, backend = None, dim = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend self.dim = dim + self.sparsity_pattern = sparsity_pattern + try: self.py_neon: Py_neon = Py_neon() except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() - self.help_grid_new() + + self._help_load_api() + self._help_grid_new() def __del__(self): if self.handle == 0: return - self.help_grid_delete() + self._help_grid_delete() - def help_load_api(self): + def _help_load_api(self): # grid_new self.py_neon.lib.bGrid_new.argtypes = [self.py_neon.handle_type, - ctypes.POINTER(Backend), - py_neon.Index_3d] + self.py_neon.handle_type, + ctypes.POINTER(py_neon.Index_3d), + ctypes.POINTER(ctypes.c_int)] self.py_neon.lib.bGrid_new.restype = ctypes.c_int # grid_delete self.py_neon.lib.bGrid_delete.argtypes = [self.py_neon.handle_type] self.py_neon.lib.bGrid_delete.restype = ctypes.c_int + self.py_neon.lib.bGrid_get_dimensions.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(py_neon.Index_3d)] + self.py_neon.lib.bGrid_get_dimensions.restype = ctypes.c_int + self.py_neon.lib.bGrid_get_span.argtypes = [self.py_neon.handle_type, - ctypes.POINTER(Span), # the span object + ctypes.POINTER(bSpan), # the span object py_neon.Execution, # the execution type ctypes.c_int, # the device id py_neon.DataView, # the data view @@ -56,36 +71,44 @@ def help_load_api(self): self.py_neon.lib.bGrid_get_properties.argtypes = [self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.bGrid_get_properties.restype = ctypes.c_int self.py_neon.lib.bGrid_is_inside_domain.argtypes = [self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.bGrid_is_inside_domain.restype = ctypes.c_bool - def help_grid_new(self): - if self.handle == 0: - raise Exception('bGrid: Invalid handle') - - if self.backend is None: - self.backend = Backend() - if self.dim is None: - self.dim = py_neon.Index_3d(10,10,10) + def _help_grid_new(self): + if self.backend.handle.value == 0: # Check backend handle validity + raise Exception('bGrid: Invalid backend handle') - res = self.py_neon.lib.bGrid_new(self.handle, self.backend.handle, self.dim) + if self.handle.value != 0: # Ensure the grid handle is uninitialized + raise Exception('bGrid: Grid handle already initialized') + + sparsity_pattern_array = self.sparsity_pattern.ctypes.data_as(ctypes.POINTER(ctypes.c_int)) + res = self.py_neon.lib.bGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim, sparsity_pattern_array) if res != 0: raise Exception('bGrid: Failed to initialize grid') + print(f"bGrid initialized with handle {self.handle.value}") - def help_grid_delete(self): - if self.handle == 0: - return - res = self.py_neon.lib.bGrid_delete(self.handle) - if res != 0: + def _help_grid_delete(self): + if self.py_neon.lib.bGrid_delete(ctypes.byref(self.handle)) != 0: raise Exception('Failed to delete grid') - def new_field(self) -> bField: - field = bField(self.py_neon, self.handle) + def get_python_dimensions(self): + return self.dim + + def get_cpp_dimensions(self): + cpp_dim = Index_3d(0,0,0) + res = self.py_neon.lib.bGrid_get_dimensions(ctypes.byref(self.handle), cpp_dim) + if res != 0: + raise Exception('bGrid: Failed to obtain grid dimension') + + return cpp_dim + + def new_field(self, cardinality: ctypes.c_int) -> bField: + field = bField(self.handle, cardinality) return field def get_span(self, @@ -96,7 +119,7 @@ def get_span(self, raise Exception('bGrid: Invalid handle') span = bSpan() - res = self.py_neon.lib.bGrid_get_span(self.handle, span, execution, c, data_view) + res = self.py_neon.lib.bGrid_get_span(ctypes.byref(self.handle), span, execution, c, data_view) if res != 0: raise Exception('Failed to get span') @@ -109,7 +132,10 @@ def get_span(self, return span def getProperties(self, idx: Index_3d): - return DataView.from_int(self.py_neon.lib.bGrid_get_properties(self.handle, idx)) - + return DataView(self.py_neon.lib.bGrid_get_properties(ctypes.byref(self.handle), idx)) + + # for some reason, negative numbers in the index will return true for bGrids. def isInsideDomain(self, idx: Index_3d): - return self.py_neon.lib.bGrid_is_inside_domain(self.handle, idx) + if idx.x < 0 or idx.y < 0 or idx.z < 0: + raise Exception(f'can\'t access negative indices in mGrid') # @TODOMATT make sure that this is a valid requirement + return self.py_neon.lib.bGrid_is_inside_domain(ctypes.byref(self.handle), idx) diff --git a/py_neon/block/bPartition.py b/py_neon/block/bPartition.py index 966db495..17938b99 100644 --- a/py_neon/block/bPartition.py +++ b/py_neon/block/bPartition.py @@ -3,32 +3,54 @@ from enum import Enum import py_neon - +from py_neon import Py_neon class bPartitionInt(ctypes.Structure): _fields_ = [ - ("setIdx", ctypes.c_int), ("mCardinality", ctypes.c_int), ("mMem", ctypes.POINTER(ctypes.c_int)), + ("mStencilNghIndex", ctypes.POINTER(ctypes.c_int)), ("mBlockConnectivity", ctypes.POINTER(ctypes.c_uint32)), ("mMask", ctypes.POINTER(ctypes.c_uint32)), ("mOrigin", ctypes.POINTER(py_neon.Index_3d)), - ("mStencilNghIndex", ctypes.POINTER(ctypes.c_int)), + ("mSetIdx", ctypes.c_int), + ("mMultiResDiscreteIdxSpacing", ctypes.c_int), ("mDomainSize", py_neon.Index_3d) + ] - def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(bPartitionInt, field_name) + def __init__(self): + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) + self._help_load_api() + + def _help_load_api(self): + self.py_neon.lib.bGrid_bField_bPartition_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.bGrid_bField_bPartition_get_member_field_offsets.restype = None + def get_cpp_field_offsets(self): + length = ctypes.c_size_t() + offsets = (ctypes.c_size_t * 9)() # Since there are 9 offsets + self.py_neon.lib.bGrid_bField_bPartition_get_member_field_offsets(offsets, ctypes.byref(length)) + return [offsets[i] for i in range(length.value)] + + def __str__(self): str_repr = f"" - str_repr += f"\n\tsetIdx: {self.setIdx} (offset: {get_offset('setIdx')})" - str_repr += f"\n\tmCardinality: {self.mCardinality} (offset: {get_offset('mCardinality')})" - str_repr += f"\n\tmMem: {self.mMem} (offset: {get_offset('mMem')})" - str_repr += f"\n\tmBlockConnectivity: {self.mBlockConnectivity} (offset: {get_offset('mBlockConnectivity')})" - str_repr += f"\n\tmMask: {self.mMask} (offset: {get_offset('mMask')})" - str_repr += f"\n\tmOrigin: {self.mOrigin} (offset: {get_offset('mOrigin')})" - str_repr += f"\n\tmStencilNghIndex: {self.mStencilNghIndex} (offset: {get_offset('mStencilNghIndex')})" - str_repr += f"\n\tmDomainSize: {self.mDomainSize} (offset: {get_offset('mDomainSize')})" + str_repr += f"\n\tmCardinality: {self.mCardinality} (offset: {bPartitionInt.mCardinality.offset})" + str_repr += f"\n\tmMem: {self.mMem} (offset: {bPartitionInt.mMem.offset})" + str_repr += f"\n\tmStencilNghIndex: {self.mStencilNghIndex} (offset: {bPartitionInt.mStencilNghIndex.offset})" + str_repr += f"\n\tmBlockConnectivity: {self.mBlockConnectivity} (offset: {bPartitionInt.mBlockConnectivity.offset})" + str_repr += f"\n\tmMask: {self.mMask} (offset: {bPartitionInt.mMask.offset})" + str_repr += f"\n\tmOrigin: {self.mOrigin} (offset: {bPartitionInt.mOrigin.offset})" + str_repr += f"\n\tmSetIdx: {self.mSetIdx} (offset: {bPartitionInt.mSetIdx.offset})" + str_repr += f"\n\tmMultiResDiscreteIdxSpacing: {self.mMultiResDiscreteIdxSpacing} (offset: {bPartitionInt.mMultiResDiscreteIdxSpacing.offset})" + str_repr += f"\n\tmDomainSize: {self.mDomainSize} (offset: {bPartitionInt.mDomainSize.offset})" return str_repr + def get_offsets(self): + return [bPartitionInt.mCardinality.offset, bPartitionInt.mMem.offset, bPartitionInt.mStencilNghIndex.offset, + bPartitionInt.mBlockConnectivity.offset, bPartitionInt.mMask.offset, bPartitionInt.mOrigin.offset, + bPartitionInt.mSetIdx.offset, bPartitionInt.mMultiResDiscreteIdxSpacing.offset, bPartitionInt.mDomainSize.offset] diff --git a/py_neon/block/bSpan.py b/py_neon/block/bSpan.py index 5b694b35..91539e6f 100644 --- a/py_neon/block/bSpan.py +++ b/py_neon/block/bSpan.py @@ -6,45 +6,41 @@ from py_neon import DataView class bSpan(ctypes.Structure): + _fields_ = [ + ("vtablePtr", ctypes.c_uint64), + ("mFirstDataBlockOffset", ctypes.c_uint32), + ("mActiveMask", ctypes.POINTER(ctypes.c_uint32)), + ("mDataView", DataView) + ] + def __init__(self): try: self.py_neon: Py_neon = Py_neon() except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() - - def help_load_api(self): + self._help_load_api() - # grid_new - self.py_neon.lib.bGrid_bSpan_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t)] - self.py_neon.lib.bGrid_bSpan_get_member_field_offsets.restype = ctypes.POINTER(ctypes.c_size_t) + def _help_load_api(self): + self.py_neon.lib.bGrid_bSpan_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.bGrid_bSpan_get_member_field_offsets.restype = None - def get_member_field_offsets(self): + def get_cpp_field_offsets(self): length = ctypes.c_size_t() - offsets = self.py_neon.lib.bGrid_bSpan_get_member_field_offsets(ctypes.byref(length)) + offsets = (ctypes.c_size_t * 3)() # Assuming there are 3 offsets + self.py_neon.lib.bGrid_bSpan_get_member_field_offsets(offsets, ctypes.byref(length)) return [offsets[i] for i in range(length.value)] - _fields_ = [ - ("mFirstDataBlockOffset", ctypes.c_uint32), - ("mActiveMask", ctypes.POINTER(ctypes.c_uint32)), - ("mDataView", DataView) - ] def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(bSpan, field_name) - str_repr = f"" - str_repr += f"\n\tmFirstDataBlockOffset: {self.mFirstDataBlockOffset} (offset: {get_offset('mFirstDataBlockOffset')})" - str_repr += f"\n\tmActiveMask: {self.mActiveMask} (offset: {get_offset('mActiveMask')})" - str_repr += f"\n\tmDataView: {self.mDataView} (offset: {get_offset('mDataView')})" + str_repr += f"\n\tmFirstDataBlockOffset: {self.mFirstDataBlockOffset} (offset: {bSpan.mFirstDataBlockOffset.offset})" + str_repr += f"\n\tmActiveMask: {self.mActiveMask} (offset: {bSpan.mActiveMask.offset})" + str_repr += f"\n\tmDataView: {self.mDataView} (offset: {bSpan.mDataView.offset})" return str_repr def get_offsets(self): - def get_offset(field_name): - return ctypes.offsetof(bSpan, field_name) - return [get_offset('mFirstDataBlockOffset'), get_offset('mActiveMask'), get_offset('mDataView')] + return [bSpan.mFirstDataBlockOffset.offset, bSpan.mActiveMask.offset, bSpan.mDataView.offset] @staticmethod def fields_(): diff --git a/py_neon/dataview.py b/py_neon/dataview.py index 895177fd..99ec2fd6 100644 --- a/py_neon/dataview.py +++ b/py_neon/dataview.py @@ -3,7 +3,7 @@ from enum import Enum class DataView(ctypes.Structure): - _fields_ = [("data_view", ctypes.c_uint8)] + _fields_ = [("data_view", ctypes.c_char)] class Values(Enum): standard = 0 @@ -47,4 +47,9 @@ def __str__(self): if self.value == DataView.Values.boundary: str += f"\n\tdataView: {'boundary'}" return str + + def __eq__(self, other): + if not isinstance(other, DataView): + return NotImplemented + return self.data_view == other.data_view diff --git a/py_neon/dense/__init__.py b/py_neon/dense/__init__.py index 1b0b54d4..fac3c129 100644 --- a/py_neon/dense/__init__.py +++ b/py_neon/dense/__init__.py @@ -3,12 +3,5 @@ from .dField import dField from .dSpan import dSpan from .dPartition import dPartitionInt -# from .bGrid import bGrid -# from .bField import bField -# from .bSpan import bSpan -# from .bPartition import bPartitionInt -# from .mGrid import mGrid -# from .mField import mField -# from .mPartition import mPartitionInt + from py_neon.allocationCounter import allocationCounter -# from .partition import PartitionInt \ No newline at end of file diff --git a/py_neon/dense/dField.py b/py_neon/dense/dField.py index 2911323d..1f7f4f6d 100644 --- a/py_neon/dense/dField.py +++ b/py_neon/dense/dField.py @@ -2,7 +2,8 @@ import ctypes from enum import Enum import py_neon -from .dPartition import dPartitionInt as NeDPartition +from py_neon import Py_neon +from .dPartition import dPartitionInt as NeDPartitionInt from py_neon.execution import Execution as NeExecution from py_neon.dataview import DataView as NeDataView from py_neon.py_ne import Py_neon as NePy_neon @@ -11,28 +12,34 @@ class dField(object): def __init__(self, - py_neon: NePy_neon, - grid_handle: ctypes.c_uint64 + grid_handle: ctypes.c_uint64, + cardinality: ctypes.c_int ): if grid_handle == 0: raise Exception('DField: Invalid handle') - self.py_neon = py_neon + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) self.handle_type = ctypes.POINTER(ctypes.c_uint64) self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.grid_handle = grid_handle - self.help_load_api() - self.help_new() + self.cardinality = cardinality + self._help_load_api() + self._help_field_new() def __del__(self): self.help_delete() - def help_load_api(self): + def _help_load_api(self): # Importing new functions ## new_field self.py_neon.lib.dGrid_dField_new.argtypes = [self.handle_type, - self.handle_type] + self.handle_type, + ctypes.c_int] self.py_neon.lib.dGrid_dField_new.restype = ctypes.c_int ## delete_field @@ -41,7 +48,7 @@ def help_load_api(self): ## get_partition self.py_neon.lib.dGrid_dField_get_partition.argtypes = [self.handle_type, - ctypes.POINTER(NeDPartition), # the span object + ctypes.POINTER(NeDPartitionInt), # the span object NeExecution, # the execution type ctypes.c_int, # the device id NeDataView, # the data view @@ -49,18 +56,18 @@ def help_load_api(self): self.py_neon.lib.dGrid_dField_get_partition.restype = ctypes.c_int # size partition - self.py_neon.lib.dGrid_dField_partition_size.argtypes = [ctypes.POINTER(NeDPartition)] + self.py_neon.lib.dGrid_dField_partition_size.argtypes = [ctypes.POINTER(NeDPartitionInt)] self.py_neon.lib.dGrid_dField_partition_size.restype = ctypes.c_int # field read self.py_neon.lib.dGrid_dField_read.argtypes = [self.handle_type, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int] self.py_neon.lib.dGrid_dField_read.restype = ctypes.c_int # field write self.py_neon.lib.dGrid_dField_write.argtypes = [self.handle_type, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int, ctypes.c_int] self.py_neon.lib.dGrid_dField_write.restype = ctypes.c_int @@ -77,18 +84,18 @@ def help_load_api(self): - def help_new(self): + def _help_field_new(self): if self.handle == 0: - raise Exception('DGrid: Invalid handle') + raise Exception('dGrid: Invalid handle') - res = self.py_neon.lib.dGrid_dField_new(self.handle, self.grid_handle) + res = self.py_neon.lib.dGrid_dField_new(ctypes.byref(self.handle), ctypes.byref(self.grid_handle), self.cardinality) if res != 0: - raise Exception('DGrid: Failed to initialize field') + raise Exception('dGrid: Failed to initialize field') def help_delete(self): if self.handle == 0: return - res = self.py_neon.lib.dGrid_dField_delete(self.handle) + res = self.py_neon.lib.dGrid_dField_delete(ctypes.byref(self.handle)) if res != 0: raise Exception('Failed to delete field') @@ -96,12 +103,12 @@ def get_partition(self, execution: NeExecution, c: ctypes.c_int, data_view: NeDataView - ) -> NeDPartition: + ) -> NeDPartitionInt: if self.handle == 0: - raise Exception('DField: Invalid handle') + raise Exception('dField: Invalid handle') - partition = NeDPartition() + partition = NeDPartitionInt() res = self.py_neon.lib.dGrid_dField_get_partition(self.handle, partition, @@ -109,7 +116,7 @@ def get_partition(self, c, data_view) if res != 0: - raise Exception('Failed to get span') + raise Exception('Failed to get partition') ccp_size = self.py_neon.lib.dGrid_dField_partition_size(partition) ctypes_size = ctypes.sizeof(partition) @@ -120,15 +127,15 @@ def get_partition(self, print(f"Partition {partition}") return partition - def read(self, idx: Index_3d, cardinality: int): - return self.py_neon.lib.dGrid_dField_read(self.handle, idx, cardinality) + def read(self, idx: Index_3d, cardinality: ctypes.c_int): + return self.py_neon.lib.dGrid_dField_read(ctypes.byref(self.handle), idx, cardinality) - def write(self, idx: Index_3d, cardinality: int, newValue: int): - return self.py_neon.lib.dGrid_dField_write(self.handle, idx, cardinality, newValue) + def write(self, idx: Index_3d, cardinality: ctypes.c_int, newValue: ctypes.c_int): + return self.py_neon.lib.dGrid_dField_write(ctypes.byref(self.handle), idx, cardinality, newValue) - def updateHostData(self, streamSetId: int): - return self.py_neon.lib.dGrid_dField_update_host_data(self.handle, streamSetId) + def updateHostData(self, streamSetId: ctypes.c_int): + return self.py_neon.lib.dGrid_dField_update_host_data(ctypes.byref(self.handle), streamSetId) - def updateDeviceData(self, streamSetId: int): - return self.py_neon.lib.dGrid_dField_update_device_data(self.handle, streamSetId) + def updateDeviceData(self, streamSetId: ctypes.c_int): + return self.py_neon.lib.dGrid_dField_update_device_data(ctypes.byref(self.handle), streamSetId) \ No newline at end of file diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index a1bfa938..c143006f 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -8,7 +8,7 @@ from py_neon import Py_neon from py_neon.dataview import DataView from .dSpan import dSpan -from py_neon.backend import Backend +from ..backend import Backend from py_neon.index_3d import Index_3d import numpy as np @@ -16,25 +16,26 @@ class dGrid(object): + def __init__(self, backend: Backend = None, dim: Index_3d = Index_3d(10,10,10), sparsity_pattern: np.ndarray = None): + if sparsity_pattern is None: + sparsity_pattern = np.ones((dim.x,dim.y,dim.z)) + if backend is None: + # raise exception + raise Exception('dGrid: backend pamrameter is missing') + if sparsity_pattern.shape[0] != dim.x or sparsity_pattern.shape[1] != dim.y or sparsity_pattern.shape[2] != dim.z: + raise Exception('dGrid: sparsity_pattern\'s shape does not match the dim') - def __init__(self, backend = None, dim = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend self.dim = dim - - if backend is None: - # rise exception - raise Exception('dGrid: backend pamrameter is missing') - if dim is None: - # raise exception - raise Exception('dGrid: dim parameter is missing') + self.sparsity_pattern = sparsity_pattern try: self.py_neon: Py_neon = Py_neon() except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - + self._help_load_api() self._help_grid_new() @@ -44,19 +45,19 @@ def __del__(self): def _help_load_api(self): - # grid_new - # self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type, - # self.py_neon.handle_type, - # py_neon.Index_3d] self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type, self.py_neon.handle_type, - ctypes.POINTER(py_neon.Index_3d)] + ctypes.POINTER(py_neon.Index_3d), + ctypes.POINTER(ctypes.c_int)] self.py_neon.lib.dGrid_new.restype = ctypes.c_int # grid_delete self.py_neon.lib.dGrid_delete.argtypes = [self.py_neon.handle_type] self.py_neon.lib.dGrid_delete.restype = ctypes.c_int + self.py_neon.lib.dGrid_get_dimensions.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(py_neon.Index_3d)] + self.py_neon.lib.dGrid_get_dimensions.restype = ctypes.c_int self.py_neon.lib.dGrid_get_span.argtypes = [self.py_neon.handle_type, ctypes.POINTER(dSpan), # the span object py_neon.Execution, # the execution type @@ -70,37 +71,44 @@ def _help_load_api(self): self.py_neon.lib.dGrid_get_properties.argtypes = [self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.dGrid_get_properties.restype = ctypes.c_int self.py_neon.lib.dGrid_is_inside_domain.argtypes = [self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.dGrid_is_inside_domain.restype = ctypes.c_bool def _help_grid_new(self): if self.backend.handle.value == 0: # Check backend handle validity - raise Exception('DGrid: Invalid backend handle') + raise Exception('dGrid: Invalid backend handle') if self.handle.value != 0: # Ensure the grid handle is uninitialized - raise Exception('DGrid: Grid handle already initialized') + raise Exception('dGrid: Grid handle already initialized') - print(f"Initializing grid with handle {self.handle.value} and backend handle {self.backend.handle.value}") - sys.stdout.flush() # Ensure the print statement is flushed to the console - # idx3d = Index_3d(10,10,10) - # res = self.py_neon.lib.dGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), idx3d) - # res = self.py_neon.lib.dGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim.x, self.dim.y, self.dim.z) - res = self.py_neon.lib.dGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim) + sparsity_pattern_array = self.sparsity_pattern.ctypes.data_as(ctypes.POINTER(ctypes.c_int)) + res = self.py_neon.lib.dGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim, sparsity_pattern_array) if res != 0: - raise Exception('DGrid: Failed to initialize grid') - print(f"Grid initialized with handle {self.handle.value}") + raise Exception('dGrid: Failed to initialize grid') + print(f"dGrid initialized with handle {self.handle.value}") def _help_grid_delete(self): if self.py_neon.lib.dGrid_delete(ctypes.byref(self.handle)) != 0: raise Exception('Failed to delete grid') + + def get_python_dimensions(self): + return self.dim + + def get_cpp_dimensions(self): + cpp_dim = Index_3d(0,0,0) + res = self.py_neon.lib.dGrid_get_dimensions(ctypes.byref(self.handle), cpp_dim) + if res != 0: + raise Exception('DGrid: Failed to obtain grid dimension') + + return cpp_dim - def new_field(self) -> dField: - field = dField(self.py_neon, self.handle) + def new_field(self, cardinality: ctypes.c_int) -> dField: + field = dField(self.handle, cardinality) return field def get_span(self, @@ -111,7 +119,7 @@ def get_span(self, raise Exception('DGrid: Invalid handle') span = dSpan() - res = self.py_neon.lib.dGrid_get_span(self.handle, span, execution, c, data_view) + res = self.py_neon.lib.dGrid_get_span(ctypes.byref(self.handle), span, execution, c, data_view) if res != 0: raise Exception('Failed to get span') @@ -124,7 +132,7 @@ def get_span(self, return span def getProperties(self, idx: Index_3d): - return DataView.from_int(self.py_neon.lib.dGrid_get_properties(self.handle, idx)) + return DataView(self.py_neon.lib.dGrid_get_properties(ctypes.byref(self.handle), idx)) def isInsideDomain(self, idx: Index_3d): - return self.py_neon.lib.dGrid_is_inside_domain(self.handle, idx) + return self.py_neon.lib.dGrid_is_inside_domain(ctypes.byref(self.handle), idx) diff --git a/py_neon/dense/dPartition.py b/py_neon/dense/dPartition.py index 0989d44f..eb5e1452 100644 --- a/py_neon/dense/dPartition.py +++ b/py_neon/dense/dPartition.py @@ -3,6 +3,7 @@ from enum import Enum import py_neon +from py_neon import Py_neon class dPartitionInt(ctypes.Structure): @@ -24,26 +25,45 @@ class dPartitionInt(ctypes.Structure): ("mStencil", ctypes.POINTER(ctypes.c_int)), ] - def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(dPartitionInt, field_name) + def __init__(self): + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) + self._help_load_api() - str = f"" - str += f"\n\tdataView: {self.mDataView} (offset: {get_offset('mDataView')})" - str += f"\n\tmDim: {self.mDim} (offset: {get_offset('mDim')})" - str += f"\n\tmMem: {self.mMem} (offset: {get_offset('mMem')})" - str += f"\n\tmZHaloRadius: {self.mZHaloRadius} (offset: {get_offset('mZHaloRadius')})" - str += f"\n\tmZBoundaryRadius: {self.mZBoundaryRadius} (offset: {get_offset('mZBoundaryRadius')})" - str += f"\n\tmPitch1: {self.mPitch1} (offset: {get_offset('mPitch1')})" - str += f"\n\tmPitch2: {self.mPitch2} (offset: {get_offset('mPitch2')})" - str += f"\n\tmPitch3: {self.mPitch3} (offset: {get_offset('mPitch3')})" - str += f"\n\tmPitch4: {self.mPitch4} (offset: {get_offset('mPitch4')})" - str += f"\n\tmPrtID: {self.mPrtID} (offset: {get_offset('mPrtID')})" - str += f"\n\tmOrigin: {self.mOrigin} (offset: {get_offset('mOrigin')})" - str += f"\n\tmCardinality: {self.mCardinality} (offset: {get_offset('mCardinality')})" - str += f"\n\tmFullGridSize: {self.mFullGridSize} (offset: {get_offset('mFullGridSize')})" - str += f"\n\tmPeriodicZ: {self.mPeriodicZ} (offset: {get_offset('mPeriodicZ')})" - str += f"\n\tmStencil: {self.mStencil} (offset: {get_offset('mStencil')})" - return str + def _help_load_api(self): + self.py_neon.lib.dGrid_dField_dPartition_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.dGrid_dField_dPartition_get_member_field_offsets.restype = None + def get_cpp_field_offsets(self): + length = ctypes.c_size_t() + offsets = (ctypes.c_size_t * 15)() # Since there are 15 offsets + self.py_neon.lib.dGrid_dField_dPartition_get_member_field_offsets(offsets, ctypes.byref(length)) + return [offsets[i] for i in range(length.value)] + def __str__(self): + str = f"" + str += f"\n\tdataView: {self.mDataView} (offset: {dPartitionInt.mDataView.offset})" + str += f"\n\tmDim: {self.mDim} (offset: {dPartitionInt.mDim.offset})" + str += f"\n\tmMem: {self.mMem} (offset: {dPartitionInt.mMem.offset})" + str += f"\n\tmZHaloRadius: {self.mZHaloRadius} (offset: {dPartitionInt.mZHaloRadius.offset})" + str += f"\n\tmZBoundaryRadius: {self.mZBoundaryRadius} (offset: {dPartitionInt.mZBoundaryRadius.offset})" + str += f"\n\tmPitch1: {self.mPitch1} (offset: {dPartitionInt.mPitch1.offset})" + str += f"\n\tmPitch2: {self.mPitch2} (offset: {dPartitionInt.mPitch2.offset})" + str += f"\n\tmPitch3: {self.mPitch3} (offset: {dPartitionInt.mPitch3.offset})" + str += f"\n\tmPitch4: {self.mPitch4} (offset: {dPartitionInt.mPitch4.offset})" + str += f"\n\tmPrtID: {self.mPrtID} (offset: {dPartitionInt.mPrtID.offset})" + str += f"\n\tmOrigin: {self.mOrigin} (offset: {dPartitionInt.mOrigin.offset})" + str += f"\n\tmCardinality: {self.mCardinality} (offset: {dPartitionInt.mCardinality.offset})" + str += f"\n\tmFullGridSize: {self.mFullGridSize} (offset: {dPartitionInt.mFullGridSize.offset})" + str += f"\n\tmPeriodicZ: {self.mPeriodicZ} (offset: {dPartitionInt.mPeriodicZ.offset})" + str += f"\n\tmStencil: {self.mStencil} (offset: {dPartitionInt.mStencil.offset})" + return str + + def get_offsets(self): + return [dPartitionInt.mDataView.offset, dPartitionInt.mDim.offset, dPartitionInt.mMem.offset, dPartitionInt.mZHaloRadius.offset, + dPartitionInt.mZBoundaryRadius.offset, dPartitionInt.mPitch1.offset, dPartitionInt.mPitch2.offset, dPartitionInt.mPitch3.offset, + dPartitionInt.mPitch4.offset, dPartitionInt.mPrtID.offset, dPartitionInt.mOrigin.offset, dPartitionInt.mCardinality.offset, + dPartitionInt.mFullGridSize.offset, dPartitionInt.mPeriodicZ.offset, dPartitionInt.mStencil.offset] diff --git a/py_neon/dense/dSpan.py b/py_neon/dense/dSpan.py index 01714dd2..922daf8a 100644 --- a/py_neon/dense/dSpan.py +++ b/py_neon/dense/dSpan.py @@ -8,52 +8,45 @@ class dSpan(ctypes.Structure): + _fields_ = [ + ("dataView", DataView), + ("z_ghost_radius", ctypes.c_int), + ("z_boundary_radius", ctypes.c_int), + ("max_z_in_domain", ctypes.c_int), + ("span_dim", Index_3d) + ] + def __init__(self): try: self.py_neon: Py_neon = Py_neon() except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() + self._help_load_api() - def help_load_api(self): + def _help_load_api(self): self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.restype = None - def get_member_field_offsets(self): + def get_cpp_field_offsets(self): length = ctypes.c_size_t() - offsets = (ctypes.c_size_t * 5)() # Assuming there are 5 offsets based on your C++ code + offsets = (ctypes.c_size_t * 5)() # Assuming there are 5 offsets self.py_neon.lib.dGrid_dSpan_get_member_field_offsets(offsets, ctypes.byref(length)) return [offsets[i] for i in range(length.value)] - - - _fields_ = [ - ("dataView", DataView), - ("z_ghost_radius", ctypes.c_int), - ("z_boundary_radius", ctypes.c_int), - ("max_z_in_domain", ctypes.c_int), - ("span_dim", Index_3d) - ] - + def __str__(self): - def get_offset(field_name): - return "ctypes.(dSpan, field_name)" - - str = f"" - str += f"\n\tdataView: {self.dataView} (offset: {get_offset('dataView')})" - str += f"\n\tz_ghost_radius: {self.z_ghost_radius} (offset: {get_offset('z_ghost_radius')})" - str += f"\n\tz_boundary_radius: {self.z_boundary_radius} (offset: {get_offset('z_boundary_radius')})" - str += f"\n\tmax_z_in_domain: {self.max_z_in_domain} (offset: {get_offset('max_z_in_domain')})" - str += f"\n\tspan_dim: {self.span_dim} (offset: {get_offset('span_dim')})" + str = f"" + str += f"\n\tdataView: {self.dataView} (offset: {dSpan.dataView.offset})" + str += f"\n\tz_ghost_radius: {self.z_ghost_radius} (offset: {dSpan.z_ghost_radius.offset})" + str += f"\n\tz_boundary_radius: {self.z_boundary_radius} (offset: {dSpan.z_boundary_radius.offset})" + str += f"\n\tmax_z_in_domain: {self.max_z_in_domain} (offset: {dSpan.max_z_in_domain.offset})" + str += f"\n\tspan_dim: {self.span_dim} (offset: {dSpan.span_dim.offset})" return str def get_span_dim(self): return copy.deepcopy(self.span_dim) def get_offsets(self): - # def get_offset(field_name): - # return ctypes.offsetof(dSpan, field_name) - # return [get_offset('dataView'), get_offset('z_ghost_radius'), get_offset('z_boundary_radius'), get_offset('max_z_in_domain'), get_offset('span_dim')] return [dSpan.dataView.offset, dSpan.z_ghost_radius.offset, dSpan.z_boundary_radius.offset, dSpan.max_z_in_domain.offset, dSpan.span_dim.offset] @staticmethod diff --git a/py_neon/index_3d.py b/py_neon/index_3d.py index 8288677d..5fe426c0 100644 --- a/py_neon/index_3d.py +++ b/py_neon/index_3d.py @@ -18,4 +18,9 @@ def __str__(self): str += f"\n\ty: {self.y}" str += f"\n\tz: {self.z}" return str + + def __eq__(self, other): + if not isinstance(other, Index_3d): + return NotImplemented + return (self.x == other.x and self.y == other.y and self.z == other.z) diff --git a/py_neon/multires/__init__.py b/py_neon/multires/__init__.py index e69de29b..7831d4f4 100644 --- a/py_neon/multires/__init__.py +++ b/py_neon/multires/__init__.py @@ -0,0 +1,8 @@ +from py_neon.backend import Backend + +from ..block.bSpan import bSpan +from .mGrid import mGrid +from .mField import mField +from .mPartition import mPartitionInt + +from py_neon.allocationCounter import allocationCounter diff --git a/py_neon/multires/mField.py b/py_neon/multires/mField.py index b9734158..11680f7d 100644 --- a/py_neon/multires/mField.py +++ b/py_neon/multires/mField.py @@ -2,6 +2,7 @@ import ctypes from enum import Enum import py_neon +from py_neon import Py_neon from .mPartition import mPartitionInt as NeMPartitionInt from py_neon.execution import Execution as NeExecution from py_neon.dataview import DataView as NeDataView @@ -13,24 +14,28 @@ class mField(object): def __init__(self, - py_neon: NePy_neon, - grid_handle: ctypes.c_uint64 + grid_handle: ctypes.c_uint64, + cardinality: ctypes.c_int ): if grid_handle == 0: - raise Exception('mField: Invalid handle') - - self.py_neon = py_neon + raise Exception('DField: Invalid handle') + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) self.handle_type = ctypes.POINTER(ctypes.c_uint64) self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.grid_handle = grid_handle - self.help_load_api() - self.help_new() + self.cardinality = cardinality + self._help_load_api() + self._help_field_new() def __del__(self): self.help_delete() - def help_load_api(self): + def _help_load_api(self): # Importing new functions ## new_field self.py_neon.lib.mGrid_mField_new.argtypes = [self.handle_type, @@ -43,7 +48,7 @@ def help_load_api(self): ## get_partition self.py_neon.lib.mGrid_mField_get_partition.argtypes = [self.handle_type, - ctypes.POINTER(NePartitionInt), # the span object + ctypes.POINTER(NeMPartitionInt), # the span object ctypes.c_int, NeExecution, # the execution type ctypes.c_int, # the device id @@ -52,20 +57,20 @@ def help_load_api(self): self.py_neon.lib.mGrid_mField_get_partition.restype = ctypes.c_int # size partition - self.py_neon.lib.mGrid_mField_partition_size.argtypes = [ctypes.POINTER(NePartitionInt)] + self.py_neon.lib.mGrid_mField_partition_size.argtypes = [ctypes.POINTER(NeMPartitionInt)] self.py_neon.lib.mGrid_mField_partition_size.restype = ctypes.c_int # field read self.py_neon.lib.mGrid_mField_read.argtypes = [self.handle_type, ctypes.c_int, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int] self.py_neon.lib.mGrid_mField_read.restype = ctypes.c_int # field write self.py_neon.lib.mGrid_mField_write.argtypes = [self.handle_type, ctypes.c_int, - py_neon.Index_3d, + ctypes.POINTER(py_neon.Index_3d), ctypes.c_int, ctypes.c_int] self.py_neon.lib.mGrid_mField_write.restype = ctypes.c_int @@ -81,63 +86,59 @@ def help_load_api(self): self.py_neon.lib.mGrid_mField_update_device_data.restype = ctypes.c_int - - def help_new(self): + def _help_field_new(self): if self.handle == 0: raise Exception('mGrid: Invalid handle') - res = self.py_neon.lib.mGrid_mField_new(self.handle, self.grid_handle) + res = self.py_neon.lib.mGrid_mField_new(ctypes.byref(self.handle), ctypes.byref(self.grid_handle), self.cardinality) if res != 0: raise Exception('mGrid: Failed to initialize field') def help_delete(self): if self.handle == 0: return - res = self.py_neon.lib.mGrid_mField_delete(self.handle) + res = self.py_neon.lib.mGrid_mField_delete(ctypes.byref(self.handle)) if res != 0: raise Exception('Failed to delete field') - # TODOMATT ask Max how to reconcile our new partitions with the wpne partitions - # def get_partition(self, - # field_index: ctypes.c_int, - # execution: NeExecution, - # c: ctypes.c_int, - # data_view: NeDataView - # ) -> Wpne_NeonDensePartitionInt: - - # if self.handle == 0: - # raise Exception('mField: Invalid handle') - - # partition = NePartitionInt() - - # res = self.py_neon.lib.mGrid_mField_get_partition(self.handle, - # partition, - # field_index, - # execution, - # c, - # data_view) - # if res != 0: - # raise Exception('Failed to get span') - - # ccp_size = self.py_neon.lib.mGrid_mField_partition_size(partition) - # ctypes_size = ctypes.sizeof(partition) - - # if ccp_size != ctypes_size: - # raise Exception(f'Failed to get span: cpp_size {ccp_size} != ctypes_size {ctypes_size}') - - # print(f"Partition {partition}") - # wpne_partition = Wpne_NeonDensePartitionInt(partition) - # return wpne_partition + def get_partition(self, + field_index: ctypes.c_int, + execution: NeExecution, + c: ctypes.c_int, + data_view: NeDataView + ) -> NeMPartitionInt: + + if self.handle == 0: + raise Exception('mField: Invalid handle') + + partition = NeMPartitionInt() + + res = self.py_neon.lib.mGrid_mField_get_partition(self.handle, + partition, + field_index, + execution, + c, + data_view) + if res != 0: + raise Exception('Failed to get partition') + + ccp_size = self.py_neon.lib.mGrid_mField_partition_size(partition) + ctypes_size = ctypes.sizeof(partition) + + if ccp_size != ctypes_size: + raise Exception(f'Failed to get span: cpp_size {ccp_size} != ctypes_size {ctypes_size}') + + print(f"Partition {partition}") + return partition def read(self, field_level: ctypes.c_int, idx: Index_3d, cardinality: ctypes.c_int): - return self.py_neon.lib.mGrid_mField_read(self.handle, field_level, idx, cardinality) + return self.py_neon.lib.mGrid_mField_read(ctypes.byref(self.handle), field_level, idx, cardinality) def write(self, field_level: ctypes.c_int, idx: Index_3d, cardinality: ctypes.c_int, newValue: ctypes.c_int): - return self.py_neon.lib.mGrid_mField_write(self.handle, field_level, idx, cardinality, newValue) + return self.py_neon.lib.mGrid_mField_write(ctypes.byref(self.handle), field_level, idx, cardinality, newValue) def updateHostData(self, streamSetId: ctypes.c_int): - return self.py_neon.lib.mGrid_mField_update_host_data(self.handle, streamSetId) + return self.py_neon.lib.mGrid_mField_update_host_data(ctypes.byref(self.handle), streamSetId) def updateDeviceData(self, streamSetId: ctypes.c_int): - return self.py_neon.lib.mGrid_mField_update_device_data(self.handle, streamSetId) - \ No newline at end of file + return self.py_neon.lib.mGrid_mField_update_device_data(ctypes.byref(self.handle), streamSetId) \ No newline at end of file diff --git a/py_neon/multires/mGrid.py b/py_neon/multires/mGrid.py index 1809daae..19382cd4 100644 --- a/py_neon/multires/mGrid.py +++ b/py_neon/multires/mGrid.py @@ -7,37 +7,48 @@ from py_neon.execution import Execution from py_neon import Py_neon from py_neon.dataview import DataView -from .dSpan import dSpan -from .backend import Backend +from ..block.bSpan import bSpan +from ..backend import Backend from py_neon.index_3d import Index_3d +import numpy as np class mGrid(object): + def __init__(self, backend = None, dim = None, depth = 1, sparsity_pattern: np.ndarray = None): + if sparsity_pattern is None: + sparsity_pattern = np.ones((dim.x,dim.y,dim.z)) + if backend is None: + # raise exception + raise Exception('dGrid: backend pamrameter is missing') + if sparsity_pattern.shape[0] != dim.x or sparsity_pattern.shape[1] != dim.y or sparsity_pattern.shape[2] != dim.z: + raise Exception('dGrid: sparsity_pattern\'s shape does not match the dim') - - def __init__(self, backend = None, dim = None, depth = 0): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend self.dim = dim + self.sparsity_pattern = sparsity_pattern self.depth = depth + try: self.py_neon: Py_neon = Py_neon() except Exception as e: self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) raise Exception('Failed to initialize PyNeon: ' + str(e)) - self.help_load_api() - self.help_grid_new() + + self._help_load_api() + self._help_grid_new() def __del__(self): if self.handle == 0: return - self.help_grid_delete() + self._help_grid_delete() - def help_load_api(self): + def _help_load_api(self): # grid_new self.py_neon.lib.mGrid_new.argtypes = [self.py_neon.handle_type, - ctypes.POINTER(Backend), - py_neon.Index_3d, + self.py_neon.handle_type, + ctypes.POINTER(py_neon.Index_3d), + ctypes.POINTER(ctypes.c_int), ctypes.c_int] self.py_neon.lib.mGrid_new.restype = ctypes.c_int @@ -45,64 +56,77 @@ def help_load_api(self): self.py_neon.lib.mGrid_delete.argtypes = [self.py_neon.handle_type] self.py_neon.lib.mGrid_delete.restype = ctypes.c_int + + self.py_neon.lib.mGrid_get_dimensions.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(py_neon.Index_3d)] + self.py_neon.lib.mGrid_get_dimensions.restype = ctypes.c_int + self.py_neon.lib.mGrid_get_span.argtypes = [self.py_neon.handle_type, ctypes.c_int, # the grid index - ctypes.POINTER(dSpan), # the span object + ctypes.POINTER(bSpan), # the span object py_neon.Execution, # the execution type ctypes.c_int, # the device id py_neon.DataView, # the data view ] self.py_neon.lib.mGrid_get_span.restype = ctypes.c_int - self.py_neon.lib.mGrid_span_size.argtypes = [ctypes.POINTER(dSpan)] + self.py_neon.lib.mGrid_span_size.argtypes = [ctypes.POINTER(bSpan)] self.py_neon.lib.mGrid_span_size.restype = ctypes.c_int self.py_neon.lib.mGrid_get_properties.argtypes = [self.py_neon.handle_type, ctypes.c_int, # the grid index - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.mGrid_get_properties.restype = ctypes.c_int self.py_neon.lib.mGrid_is_inside_domain.argtypes = [self.py_neon.handle_type, ctypes.c_int, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.mGrid_is_inside_domain.restype = ctypes.c_bool - def help_grid_new(self): - if self.handle == 0: - raise Exception('mGrid: Invalid handle') - - if self.backend is None: - self.backend = Backend() - if self.dim is None: - self.dim = py_neon.Index_3d(10,10,10) + def _help_grid_new(self): + if self.backend.handle.value == 0: # Check backend handle validity + raise Exception('mGrid: Invalid backend handle') - res = self.py_neon.lib.mGrid_new(self.handle, self.backend.handle, self.dim, self.depth) + if self.handle.value != 0: # Ensure the grid handle is uninitialized + raise Exception('mGrid: Grid handle already initialized') + + sparsity_pattern_array = self.sparsity_pattern.ctypes.data_as(ctypes.POINTER(ctypes.c_int)) + res = self.py_neon.lib.mGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim, sparsity_pattern_array, self.depth) if res != 0: raise Exception('mGrid: Failed to initialize grid') + print(f"mGrid initialized with handle {self.handle.value}") - def help_grid_delete(self): - if self.handle == 0: - return - res = self.py_neon.lib.mGrid_delete(self.handle) - if res != 0: + def _help_grid_delete(self): + if self.py_neon.lib.mGrid_delete(ctypes.byref(self.handle)) != 0: raise Exception('Failed to delete grid') - def new_field(self) -> mField: - field = mField(self.py_neon, self.handle) + def get_python_dimensions(self): + return self.dim + + def get_cpp_dimensions(self): + cpp_dim = Index_3d(0,0,0) + res = self.py_neon.lib.mGrid_get_dimensions(ctypes.byref(self.handle), cpp_dim) + if res != 0: + raise Exception('mGrid: Failed to obtain grid dimension') + + return cpp_dim + + def new_field(self, cardinality: ctypes.c_int) -> mField: + field = mField(self.handle, cardinality) return field def get_span(self, grid_level: ctypes.c_int, execution: Execution, c: ctypes.c_int, - data_view: DataView) -> dSpan: + data_view: DataView) -> bSpan: if self.handle == 0: raise Exception('mGrid: Invalid handle') - span = dSpan() - res = self.py_neon.lib.mGrid_get_span(self.handle, grid_level, span, execution, c, data_view) + span = bSpan() + res = self.py_neon.lib.mGrid_get_span(ctypes.byref(self.handle), grid_level, span, execution, c, data_view) if res != 0: raise Exception('Failed to get span') @@ -114,8 +138,10 @@ def get_span(self, return span - def getProperties(self, grid_inex: ctypes.c_int, idx: Index_3d): - return DataView.from_int(self.py_neon.lib.mGrid_get_properties(self.handle, grid_inex, idx)) + def getProperties(self, grid_level: ctypes.c_int, idx: Index_3d): + return DataView(self.py_neon.lib.mGrid_get_properties(ctypes.byref(self.handle), grid_level, idx)) def isInsideDomain(self, grid_level: ctypes.c_int, idx: Index_3d): - return self.py_neon.lib.mGrid_is_inside_domain(self.handle, grid_level, idx) + if idx.x < 0 or idx.y < 0 or idx.z < 0: + raise Exception(f'can\'t access negative indices in mGrid') # @TODOMATT make sure that this is a valid requirement + return self.py_neon.lib.mGrid_is_inside_domain(ctypes.byref(self.handle), grid_level, idx) diff --git a/py_neon/multires/mPartition.py b/py_neon/multires/mPartition.py index 009752de..1d7ef73f 100644 --- a/py_neon/multires/mPartition.py +++ b/py_neon/multires/mPartition.py @@ -3,10 +3,20 @@ from enum import Enum import py_neon +from py_neon import Py_neon class mPartitionInt(ctypes.Structure): _fields_ = [ + ("mCardinality", ctypes.c_int), + ("mMem", ctypes.POINTER(ctypes.c_int)), + ("mStencilNghIndex", ctypes.POINTER(ctypes.c_int)), + ("mBlockConnectivity", ctypes.POINTER(ctypes.c_uint32)), + ("mMask", ctypes.POINTER(ctypes.c_uint32)), + ("mOrigin", ctypes.POINTER(py_neon.Index_3d)), + ("mSetIdx", ctypes.c_int), + ("mMultiResDiscreteIdxSpacing", ctypes.c_int), + ("mDomainSize", py_neon.Index_3d), ("mLevel", ctypes.c_int), ("mMemParent", ctypes.POINTER(ctypes.c_int)), ("mMemChild", ctypes.POINTER(ctypes.c_int)), @@ -19,19 +29,51 @@ class mPartitionInt(ctypes.Structure): ("mSpacing", ctypes.POINTER(ctypes.c_int)) ] - def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(mPartitionInt, field_name) + def __init__(self): + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) + self._help_load_api() + + def _help_load_api(self): + self.py_neon.lib.mGrid_mField_mPartition_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.mGrid_mField_mPartition_get_member_field_offsets.restype = None + def get_cpp_field_offsets(self): + length = ctypes.c_size_t() + offsets = (ctypes.c_size_t * 19)() # Since there are 19 offsets + self.py_neon.lib.mGrid_mField_mPartition_get_member_field_offsets(offsets, ctypes.byref(length)) + return [offsets[i] for i in range(length.value)] + + def __str__(self): str_repr = f"" - str_repr += f"\n\tmLevel: {self.mLevel} (offset: {get_offset('mLevel')})" - str_repr += f"\n\tmMemParent: {self.mMemParent} (offset: {get_offset('mMemParent')})" - str_repr += f"\n\tmMemChild: {self.mMemChild} (offset: {get_offset('mMemChild')})" - str_repr += f"\n\tmParentBlockID: {self.mParentBlockID} (offset: {get_offset('mParentBlockID')})" - str_repr += f"\n\tmMaskLowerLevel: {self.mMaskLowerLevel} (offset: {get_offset('mMaskLowerLevel')})" - str_repr += f"\n\tmMaskUpperLevel: {self.mMaskUpperLevel} (offset: {get_offset('mMaskUpperLevel')})" - str_repr += f"\n\tmChildBlockID: {self.mChildBlockID} (offset: {get_offset('mChildBlockID')})" - str_repr += f"\n\tmParentNeighbourBlocks: {self.mParentNeighbourBlocks} (offset: {get_offset('mParentNeighbourBlocks')})" - str_repr += f"\n\tmRefFactors: {self.mRefFactors} (offset: {get_offset('mRefFactors')})" - str_repr += f"\n\tmSpacing: {self.mSpacing} (offset: {get_offset('mSpacing')})" - return str_repr \ No newline at end of file + str_repr += f"\n\tmCardinality: {self.mCardinality} (offset: {mPartitionInt.mCardinality.offset})" + str_repr += f"\n\tmMem: {self.mMem} (offset: {mPartitionInt.mMem.offset})" + str_repr += f"\n\tmStencilNghIndex: {self.mStencilNghIndex} (offset: {mPartitionInt.mStencilNghIndex.offset})" + str_repr += f"\n\tmBlockConnectivity: {self.mBlockConnectivity} (offset: {mPartitionInt.mBlockConnectivity.offset})" + str_repr += f"\n\tmMask: {self.mMask} (offset: {mPartitionInt.mMask.offset})" + str_repr += f"\n\tmOrigin: {self.mOrigin} (offset: {mPartitionInt.mOrigin.offset})" + str_repr += f"\n\tmSetIdx: {self.mSetIdx} (offset: {mPartitionInt.mSetIdx.offset})" + str_repr += f"\n\tmMultiResDiscreteIdxSpacing: {self.mMultiResDiscreteIdxSpacing} (offset: {mPartitionInt.mMultiResDiscreteIdxSpacing.offset})" + str_repr += f"\n\tmDomainSize: {self.mDomainSize} (offset: {mPartitionInt.mDomainSize.offset})" + str_repr += f"\n\tmLevel: {self.mLevel} (offset: {mPartitionInt.mLevel.offset})" + str_repr += f"\n\tmMemParent: {self.mMemParent} (offset: {mPartitionInt.mMemParent.offset})" + str_repr += f"\n\tmMemChild: {self.mMemChild} (offset: {mPartitionInt.mMemChild.offset})" + str_repr += f"\n\tmParentBlockID: {self.mParentBlockID} (offset: {mPartitionInt.mParentBlockID.offset})" + str_repr += f"\n\tmMaskLowerLevel: {self.mMaskLowerLevel} (offset: {mPartitionInt.mMaskLowerLevel.offset})" + str_repr += f"\n\tmMaskUpperLevel: {self.mMaskUpperLevel} (offset: {mPartitionInt.mMaskUpperLevel.offset})" + str_repr += f"\n\tmChildBlockID: {self.mChildBlockID} (offset: {mPartitionInt.mChildBlockID.offset})" + str_repr += f"\n\tmParentNeighbourBlocks: {self.mParentNeighbourBlocks} (offset: {mPartitionInt.mParentNeighbourBlocks.offset})" + str_repr += f"\n\tmRefFactors: {self.mRefFactors} (offset: {mPartitionInt.mRefFactors.offset})" + str_repr += f"\n\tmSpacing: {self.mSpacing} (offset: {mPartitionInt.mSpacing.offset})" + return str_repr + + def get_offsets(self): + return [mPartitionInt.mCardinality.offset, mPartitionInt.mMem.offset, mPartitionInt.mStencilNghIndex.offset, + mPartitionInt.mBlockConnectivity.offset, mPartitionInt.mMask.offset, mPartitionInt.mOrigin.offset, + mPartitionInt.mSetIdx.offset, mPartitionInt.mMultiResDiscreteIdxSpacing.offset, mPartitionInt.mDomainSize.offset, + mPartitionInt.mLevel.offset, mPartitionInt.mMemParent.offset, mPartitionInt.mMemChild.offset, mPartitionInt.mParentBlockID.offset, + mPartitionInt.mMaskLowerLevel.offset, mPartitionInt.mMaskUpperLevel.offset, mPartitionInt.mChildBlockID.offset, + mPartitionInt.mParentNeighbourBlocks.offset, mPartitionInt.mRefFactors.offset, mPartitionInt.mSpacing.offset] diff --git a/py_neon/py_ne.py b/py_neon/py_ne.py index 61ab9da4..6a8fd5b4 100644 --- a/py_neon/py_ne.py +++ b/py_neon/py_ne.py @@ -99,13 +99,13 @@ def __init__(self, ): self.py_neon = py_neon self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) - self.help_load_api() + self._help_load_api() self.help_new() def __del__(self): self.help_delete() - def help_load_api(self): + def _help_load_api(self): # Importing new functions ## new_field self.py_neon.lib.dGrid_dField_new.argtypes = [self.handle_type, @@ -133,15 +133,15 @@ class DGrid(object): def __init__(self): self.py_neon: PyNeon = PyNeon() self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) - self.help_load_api() + self._help_load_api() self.help_grid_new() def __del__(self): if self.handle == 0: return - self.help_grid_delete() + self._help_grid_delete() - def help_load_api(self): + def _help_load_api(self): # grid_new self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type] @@ -166,7 +166,7 @@ def help_grid_new(self): if res != 0: raise Exception('DGrid: Failed to initialize grid') - def help_grid_delete(self): + def _help_grid_delete(self): if self.handle == 0: return res = self.py_neon.lib.dGrid_delete(self.handle) diff --git a/py_neon/test/__init__.py b/py_neon/test/__init__.py new file mode 100644 index 00000000..a2edfdf6 --- /dev/null +++ b/py_neon/test/__init__.py @@ -0,0 +1,51 @@ +import copy +import ctypes +from enum import Enum + +from ..py_ne import Py_neon +from ..dataview import DataView +from ..execution import Execution +from ..index_3d import Index_3d + +from ..dense.dGrid import bSpan +from ..dense.dField import bSpan +from ..dense.dSpan import bSpan +from ..dense.dPartition import bSpan +from ..block.bGrid import bSpan +from ..block.bField import bSpan +from ..block.bSpan import bSpan +from ..block.bPartition import bSpan +from ..multires.mGrid import mGrid +from ..multires.mField import mField +from ..multires.mPartition import mPartitionInt + +from py_neon.allocationCounter import allocationCounter + +# +# +# class PyNeon(object): +# def __init__(self): +# self.handle_type = ctypes.POINTER(ctypes.c_uint64) +# self.lib = ctypes.CDLL( +# '/home/max/repos/neon/warp/neon_warp_testing/neon_py_bindings/cmake-build-debug/libNeonPy/liblibNeonPy.so') +# # # grid_new +# # self.lib.grid_new.argtypes = [self.handle_type] +# # # self.lib.grid_new.re = [ctypes.c_int] +# # # grid_delete +# # self.lib.grid_delete.argtypes = [self.handle_type] +# # # self.lib.grid_delete.restype = [ctypes.c_int] +# # # new_field +# # self.lib.field_new.argtypes = [self.handle_type, self.handle_type] +# # # delete_field +# # self.lib.field_delete.argtypes = [self.handle_type] +# +# def field_new(self, handle_field: ctypes.c_uint64, handle_grid: ctypes.c_uint64): +# res = self.lib.field_new(handle_field, handle_grid) +# if res != 0: +# raise Exception('Failed to initialize field') +# +# def field_delete(self, handle_field: ctypes.c_uint64): +# res = self.lib.grid_delete(handle_field) +# if res != 0: +# raise Exception('Failed to initialize grid') +#