From 7c13154dda88b3113c97882aacb4c8e5b00350f7 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Thu, 23 May 2024 20:40:13 -0700 Subject: [PATCH 01/10] added backend support to python bindings. It is untested. --- libNeonPy/include/Neon/py/backend.h | 63 +++++++++++++++ libNeonPy/src/Neon/py/backend.cpp | 119 ++++++++++++++++++++++++++++ libNeonPy/src/Neon/py/grid.cpp | 4 +- py_neon/dense/backend.py | 52 ++++++++++++ py_neon/dense/grid.py | 16 +++- 5 files changed, 250 insertions(+), 4 deletions(-) create mode 100644 libNeonPy/include/Neon/py/backend.h create mode 100644 libNeonPy/src/Neon/py/backend.cpp create mode 100644 py_neon/dense/backend.py diff --git a/libNeonPy/include/Neon/py/backend.h b/libNeonPy/include/Neon/py/backend.h new file mode 100644 index 00000000..3cfa7e3c --- /dev/null +++ b/libNeonPy/include/Neon/py/backend.h @@ -0,0 +1,63 @@ +#pragma once +#include +#include "Neon/set/Backend.h" + + +/** + * Empty constructor + */ +extern "C" auto dBackend_new( + uint64_t& handle) + -> int; + +/** + * Creating a Backend object with the first nGpus devices. + */ +extern "C" auto dBackend_new( + uint64_t& handle, + int nGpus /*! Number of devices. The devices are selected in the order specifies by CUDA */, + Neon::Runtime runtime /*! Type of runtime to use */) + -> int; + +/** + * + */ +extern "C" auto dBackend_new( + uint64_t& handle, + const std::vector& devIds /*! Vectors of device ids. There are CUDA device ids */, + Neon::Runtime runtime /*! Type of runtime to use */) + -> int; + +/** + * + */ +extern "C" auto dBackend_new( + uint64_t& handle, + const Neon::set::DevSet& devSet, + Neon::Runtime runtime /*! Type of runtime to use */) + -> int; + +/** + * + */ +extern "C" auto dBackend_new( + uint64_t& handle, + const std::vector& devIds, + const Neon::set::StreamSet& streamSet) + -> int; + +/** + * + */ +extern "C" auto dBackend_new( + uint64_t& handle, + const Neon::set::DevSet& devSet, + const Neon::set::StreamSet& streamSet) + -> int; + +/** + * Delete a backend object on the heap. + */ +extern "C" auto dBackend_delete( + uint64_t& handle) + -> int; diff --git a/libNeonPy/src/Neon/py/backend.cpp b/libNeonPy/src/Neon/py/backend.cpp new file mode 100644 index 00000000..8e9f8e91 --- /dev/null +++ b/libNeonPy/src/Neon/py/backend.cpp @@ -0,0 +1,119 @@ +#include "Neon/py/backend.h" +#include "Neon/set/Backend.h" + +void backend_constructor_prologue(uint64_t& handle) { + std::cout << "dBackend_new - BEGIN" << std::endl; + std::cout << "dBackend handle" << handle << std::endl; +} + +int backend_constructor_epilogue(uint64_t& handle, Neon::Backend* backendPtr) { + if (backendPtr == nullptr) { + std::cout << "NeonPy: Initialization error. Unable to allocage backend " << std::endl; + return -1; + } + handle = (uint64_t)backendPtr; + std::cout << "allocated backend heap location: " << backendPtr << std::endl; + std::cout << "grid_new - END" << std::endl; + return 0; +} + +auto dBackend_new_default( + uint64_t& handle) + -> int +{ + return dBackend_new(handle, 1, Neon::Runtime::openmp); +} + +auto dBackend_new( + uint64_t& handle) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_new( + uint64_t& handle, + int nGpus, + Neon::Runtime runtime) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(nGpus, runtime); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_new( + uint64_t& handle, + const std::vector& devIds, + Neon::Runtime runtime) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(devIds, runtime); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_new( + uint64_t& handle, + const Neon::set::DevSet& devSet, + Neon::Runtime runtime) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(devSet, runtime); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_new( + uint64_t& handle, + const std::vector& devIds, + const Neon::set::StreamSet& streamSet) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(devIds, streamSet); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_new( + uint64_t& handle, + const std::vector& devSet, + const Neon::set::StreamSet& streamSet) + -> int +{ + backend_constructor_prologue(handle); + + auto backendPtr = new (std::nothrow) Neon::Backend(devSet, streamSet); + + return backend_constructor_epilogue(handle, backendPtr); +} + +auto dBackend_delete( + uint64_t& handle) + -> int +{ + std::cout << "dBackend_delete - BEGIN" << std::endl; + std::cout << "backendHandle " << handle << std::endl; + + using Backend = Neon::Backend; + Backend* backendPtr = (Backend*)handle; + + if (backendPtr != nullptr) { + delete backendPtr; + } + handle = 0; + std::cout << "dBackend_delete - END" << std::endl; + return 0; +} \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/grid.cpp b/libNeonPy/src/Neon/py/grid.cpp index 7bb867e2..47c2c0b0 100644 --- a/libNeonPy/src/Neon/py/grid.cpp +++ b/libNeonPy/src/Neon/py/grid.cpp @@ -2,7 +2,9 @@ #include "Neon/domain/Grids.h" auto dGrid_new( - uint64_t& handle) + uint64_t& handle, + Neon::Backend* backendPtr, + Neon::index_3d dimInput) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; diff --git a/py_neon/dense/backend.py b/py_neon/dense/backend.py new file mode 100644 index 00000000..7dbba64c --- /dev/null +++ b/py_neon/dense/backend.py @@ -0,0 +1,52 @@ +import copy +import ctypes +from enum import Enum + +import py_neon +from py_neon.execution import Execution +from py_neon import Py_neon +from py_neon.dataview import DataView + + +class Backend(object): + def __init__(self): + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + 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_backend_new() + + def __del__(self): + if self.handle == 0: + return + self.help_backend_delete() + + def help_load_api(self): + + # backend_new + self.py_neon.lib.dBackend_new_default.argtypes = [self.py_neon.handle_type] + self.py_neon.lib.dBackend_new_default.restype = ctypes.c_int + + # backend_delete + self.py_neon.lib.dBackend_delete.argtypes = [self.py_neon.handle_type] + self.py_neon.lib.dBackend_delete.restype = ctypes.c_int + + + + def help_backend_new(self): + if self.handle == 0: + raise Exception('DBackend: Invalid handle') + + res = self.py_neon.lib.dBackend_new_default(self.handle) + if res != 0: + raise Exception('DBackend: Failed to initialize backend') + + def help_backend_delete(self): + if self.handle == 0: + return + res = self.py_neon.lib.dBackend_delete(self.handle) + if res != 0: + raise Exception('Failed to delete backend') diff --git a/py_neon/dense/grid.py b/py_neon/dense/grid.py index deefa844..da0ba875 100644 --- a/py_neon/dense/grid.py +++ b/py_neon/dense/grid.py @@ -8,11 +8,14 @@ from py_neon import Py_neon from py_neon.dataview import DataView from .span import Span +from .backend import Backend class Grid(object): - def __init__(self): + def __init__(self, backend = None, dim = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + self.backend = backend + self.dim = dim try: self.py_neon: Py_neon = Py_neon() except Exception as e: @@ -29,7 +32,9 @@ 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.lib.dGrid_new.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(Backend), + py_neon.Index_3d] self.py_neon.lib.dGrid_new.restype = ctypes.c_int # grid_delete @@ -52,7 +57,12 @@ def help_grid_new(self): if self.handle == 0: raise Exception('DGrid: Invalid handle') - res = self.py_neon.lib.dGrid_new(self.handle) + if self.backend is None: + self.backend = Backend() + if self.dim is None: + self.dim = py_neon.Index_3d(10,10,10) + + res = self.py_neon.lib.dGrid_new(self.handle, self.backend, self.dim) if res != 0: raise Exception('DGrid: Failed to initialize grid') From ab323ede8057660b25ed8646f40070fd410e30e5 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Tue, 28 May 2024 06:52:17 -0700 Subject: [PATCH 02/10] made requested changes to first part of project --- libNeonPy/include/Neon/py/backend.h | 41 +++++---------- libNeonPy/src/Neon/py/backend.cpp | 77 +++++++++-------------------- libNeonPy/src/Neon/py/grid.cpp | 6 +-- py_neon/dense/backend.py | 55 ++++++++++++++++++--- py_neon/dense/grid.py | 2 +- 5 files changed, 85 insertions(+), 96 deletions(-) diff --git a/libNeonPy/include/Neon/py/backend.h b/libNeonPy/include/Neon/py/backend.h index 3cfa7e3c..1ee3afbd 100644 --- a/libNeonPy/include/Neon/py/backend.h +++ b/libNeonPy/include/Neon/py/backend.h @@ -6,54 +6,31 @@ /** * Empty constructor */ -extern "C" auto dBackend_new( +extern "C" auto dBackend_new1( uint64_t& handle) -> int; /** * Creating a Backend object with the first nGpus devices. */ -extern "C" auto dBackend_new( +extern "C" auto dBackend_new2( uint64_t& handle, int nGpus /*! Number of devices. The devices are selected in the order specifies by CUDA */, - Neon::Runtime runtime /*! Type of runtime to use */) + int runtime /*! Type of runtime to use */) -> int; /** * */ -extern "C" auto dBackend_new( +extern "C" auto dBackend_new3( uint64_t& handle, - const std::vector& devIds /*! Vectors of device ids. There are CUDA device ids */, - Neon::Runtime runtime /*! Type of runtime to use */) + const int* devIds /*! Vectors of device ids. There are CUDA device ids */, + int runtime /*! Type of runtime to use */) -> int; -/** - * - */ -extern "C" auto dBackend_new( - uint64_t& handle, - const Neon::set::DevSet& devSet, - Neon::Runtime runtime /*! Type of runtime to use */) - -> int; -/** - * - */ -extern "C" auto dBackend_new( - uint64_t& handle, - const std::vector& devIds, - const Neon::set::StreamSet& streamSet) - -> int; -/** - * - */ -extern "C" auto dBackend_new( - uint64_t& handle, - const Neon::set::DevSet& devSet, - const Neon::set::StreamSet& streamSet) - -> int; + /** * Delete a backend object on the heap. @@ -61,3 +38,7 @@ extern "C" auto dBackend_new( extern "C" auto dBackend_delete( uint64_t& handle) -> int; + + +extern "C" auto dBackend_get_string(uint64_t& handle) -> const char*; + diff --git a/libNeonPy/src/Neon/py/backend.cpp b/libNeonPy/src/Neon/py/backend.cpp index 8e9f8e91..ef4a538d 100644 --- a/libNeonPy/src/Neon/py/backend.cpp +++ b/libNeonPy/src/Neon/py/backend.cpp @@ -17,17 +17,11 @@ int backend_constructor_epilogue(uint64_t& handle, Neon::Backend* backendPtr) { return 0; } -auto dBackend_new_default( - uint64_t& handle) - -> int -{ - return dBackend_new(handle, 1, Neon::Runtime::openmp); -} - -auto dBackend_new( +auto dBackend_new1( uint64_t& handle) -> int { + std::cout << "first constructor" << std::endl; backend_constructor_prologue(handle); auto backendPtr = new (std::nothrow) Neon::Backend(); @@ -35,67 +29,30 @@ auto dBackend_new( return backend_constructor_epilogue(handle, backendPtr); } -auto dBackend_new( +auto dBackend_new2( + std::cout << "second constructor" << std::endl; uint64_t& handle, int nGpus, - Neon::Runtime runtime) - -> int -{ - backend_constructor_prologue(handle); - - auto backendPtr = new (std::nothrow) Neon::Backend(nGpus, runtime); - - return backend_constructor_epilogue(handle, backendPtr); -} - -auto dBackend_new( - uint64_t& handle, - const std::vector& devIds, - Neon::Runtime runtime) - -> int -{ - backend_constructor_prologue(handle); - - auto backendPtr = new (std::nothrow) Neon::Backend(devIds, runtime); - - return backend_constructor_epilogue(handle, backendPtr); -} - -auto dBackend_new( - uint64_t& handle, - const Neon::set::DevSet& devSet, - Neon::Runtime runtime) - -> int -{ - backend_constructor_prologue(handle); - - auto backendPtr = new (std::nothrow) Neon::Backend(devSet, runtime); - - return backend_constructor_epilogue(handle, backendPtr); -} - -auto dBackend_new( - uint64_t& handle, - const std::vector& devIds, - const Neon::set::StreamSet& streamSet) + int runtime) -> int { backend_constructor_prologue(handle); - auto backendPtr = new (std::nothrow) Neon::Backend(devIds, streamSet); + auto backendPtr = new (std::nothrow) Neon::Backend(nGpus, Neon::Runtime(runtime)); return backend_constructor_epilogue(handle, backendPtr); } -auto dBackend_new( +auto dBackend_new3( + std::cout << "third constructor" << std::endl; uint64_t& handle, - const std::vector& devSet, - const Neon::set::StreamSet& streamSet) + const int* devIds, + int runtime) -> int { backend_constructor_prologue(handle); - auto backendPtr = new (std::nothrow) Neon::Backend(devSet, streamSet); + auto backendPtr = new (std::nothrow) Neon::Backend(std::vector(*devIds), Neon::runtime(runtime)); return backend_constructor_epilogue(handle, backendPtr); } @@ -116,4 +73,14 @@ auto dBackend_delete( handle = 0; std::cout << "dBackend_delete - END" << std::endl; return 0; -} \ No newline at end of file +} + +auto dBackend_get_string(uint64_t& handle) -> const char* { + std::cout << "get_string - BEGIN" << std::endl; + std::cout << "backendHandle " << handle << std::endl; + + using Backend = Neon::Backend; + Backend* backendPtr = (Backend*)handle; + + return backendPtr->toString().c_str(); +} diff --git a/libNeonPy/src/Neon/py/grid.cpp b/libNeonPy/src/Neon/py/grid.cpp index 47c2c0b0..f3d6b81f 100644 --- a/libNeonPy/src/Neon/py/grid.cpp +++ b/libNeonPy/src/Neon/py/grid.cpp @@ -4,7 +4,7 @@ auto dGrid_new( uint64_t& handle, Neon::Backend* backendPtr, - Neon::index_3d dimInput) + Neon::index_3d dim) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -13,10 +13,8 @@ auto dGrid_new( Neon::init(); using Grid = Neon::dGrid; - Neon::Backend bk(1, Neon::Runtime::openmp); - Neon::index_3d dim(10, 10, 10); Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); - Grid g(bk, dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); + Grid g(*backendPtr, dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); auto gridPtr = new (std::nothrow) Grid(g); if (gridPtr == nullptr) { diff --git a/py_neon/dense/backend.py b/py_neon/dense/backend.py index 7dbba64c..771ab75d 100644 --- a/py_neon/dense/backend.py +++ b/py_neon/dense/backend.py @@ -9,7 +9,14 @@ class Backend(object): - def __init__(self): + + class Runtime(Enum): + none = 0 + system = 0 + stream = 1 + openmp = 2 + + def __init__(self, arg1 = None, arg2 = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) try: self.py_neon: Py_neon = Py_neon() @@ -17,7 +24,7 @@ def __init__(self): 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() + self.help_backend_new(arg1, arg2) def __del__(self): if self.handle == 0: @@ -27,26 +34,62 @@ def __del__(self): def help_load_api(self): # backend_new - self.py_neon.lib.dBackend_new_default.argtypes = [self.py_neon.handle_type] - self.py_neon.lib.dBackend_new_default.restype = ctypes.c_int + self.py_neon.lib.dBackend_new1.argtypes = [self.py_neon.handle_type] + self.py_neon.lib.dBackend_new1.restype = ctypes.c_int + + # backend_new + self.py_neon.lib.dBackend_new2.argtypes = [self.py_neon.handle_type, + ctypes.c_int, + ctypes.c_int] + self.py_neon.lib.dBackend_new2.restype = ctypes.c_int + + # backend_new + self.py_neon.lib.dBackend_new3.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(ctypes.c_int), + ctypes.c_int] + self.py_neon.lib.dBackend_new3.restype = ctypes.c_int # backend_delete self.py_neon.lib.dBackend_delete.argtypes = [self.py_neon.handle_type] self.py_neon.lib.dBackend_delete.restype = ctypes.c_int + # backend_get_string + 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 - def help_backend_new(self): + + def help_backend_new(self, arg1=None, arg2=None): if self.handle == 0: raise Exception('DBackend: Invalid handle') - res = self.py_neon.lib.dBackend_new_default(self.handle) + if arg1 is None and arg2 is None: + # Call the empty constructor + res = self.py_neon.lib.dBackend_new1(self.handle) + elif isinstance(arg1, int) and isinstance(arg2, int): + # Call the constructor with nGpus and runtime + res = self.py_neon.lib.dBackend_new2(self.handle, arg1, arg2) + elif isinstance(arg1, list) and isinstance(arg2, int): + # Call the constructor with devIds and runtime + from ctypes import c_int, POINTER, byref + + # Convert the list to a ctypes array + dev_ids = (c_int * len(arg1))(*arg1) + res = self.py_neon.lib.dBackend_new3(self.handle, dev_ids, arg2) + else: + raise Exception('DBackend: Invalid arguments provided') + if res != 0: raise Exception('DBackend: Failed to initialize backend') + def help_backend_delete(self): if self.handle == 0: return res = self.py_neon.lib.dBackend_delete(self.handle) if res != 0: raise Exception('Failed to delete backend') + + def __str__(self): + return ctypes.cast(self.py_neon.lib.get_string(self.handle), ctypes.c_char_p).value.decode('utf-8') + \ No newline at end of file diff --git a/py_neon/dense/grid.py b/py_neon/dense/grid.py index da0ba875..f0572535 100644 --- a/py_neon/dense/grid.py +++ b/py_neon/dense/grid.py @@ -62,7 +62,7 @@ def help_grid_new(self): if self.dim is None: self.dim = py_neon.Index_3d(10,10,10) - res = self.py_neon.lib.dGrid_new(self.handle, self.backend, self.dim) + res = self.py_neon.lib.dGrid_new(self.handle, self.backend.handle, self.dim) if res != 0: raise Exception('DGrid: Failed to initialize grid') From ea583b432bd31d7d2bf22da5b9615670250f2755 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Tue, 25 Jun 2024 07:52:05 -0700 Subject: [PATCH 03/10] implemented all critical bindings. Started writing tests but they are not all passing yet. --- libNeonDomain/include/Neon/domain/Grids.h | 1 + .../include/Neon/domain/details/bGrid/bSpan.h | 3 + .../Neon/domain/details/bGrid/bSpan_imp.h | 37 ++ .../include/Neon/domain/details/dGrid/dSpan.h | 6 + .../Neon/domain/details/dGrid/dSpan_imp.h | 12 + .../Neon/domain/details/mGrid/mField.h | 6 + .../Neon/domain/details/mGrid/mField_imp.h | 2 +- .../include/Neon/domain/details/mGrid/mGrid.h | 1 + .../src/domain/details/mGrid/mGrid.cpp | 5 + libNeonPy/include/Neon/py/AllocationCounter.h | 26 ++ .../include/Neon/py/allocationBindings.h | 9 + libNeonPy/include/Neon/py/bGrid.h | 95 +++++ libNeonPy/include/Neon/py/{grid.h => dGrid.h} | 47 ++- libNeonPy/include/Neon/py/mGrid.h | 99 +++++ libNeonPy/src/Neon/py/AllocationCounter.cpp | 31 ++ libNeonPy/src/Neon/py/allocationBindings.cpp | 8 + libNeonPy/src/Neon/py/bGrid.cpp | 320 +++++++++++++++ libNeonPy/src/Neon/py/backend.cpp | 17 +- libNeonPy/src/Neon/py/dGrid.cpp | 367 ++++++++++++++++++ libNeonPy/src/Neon/py/grid.cpp | 181 --------- libNeonPy/src/Neon/py/mGrid.cpp | 335 ++++++++++++++++ py_neon/dense/__init__.py | 16 +- py_neon/dense/allocationCounter.py | 27 ++ py_neon/dense/bField.py | 138 +++++++ py_neon/dense/{grid.py => bGrid.py} | 61 +-- py_neon/dense/bPartition.py | 34 ++ py_neon/dense/bSpan.py | 51 +++ py_neon/dense/backend.py | 15 +- py_neon/dense/{field.py => dField.py} | 56 ++- py_neon/dense/dGrid.py | 120 ++++++ py_neon/dense/dPartition.py | 49 +++ py_neon/dense/dSpan.py | 62 +++ py_neon/dense/mField.py | 143 +++++++ py_neon/dense/mGrid.py | 121 ++++++ py_neon/dense/mPartition.py | 37 ++ py_neon/dense/partition.py | 46 --- py_neon/dense/span.py | 33 -- py_neon/index_1d.py | 17 + py_neon/index_3d.py | 2 +- 39 files changed, 2327 insertions(+), 309 deletions(-) create mode 100644 libNeonPy/include/Neon/py/AllocationCounter.h create mode 100644 libNeonPy/include/Neon/py/allocationBindings.h create mode 100644 libNeonPy/include/Neon/py/bGrid.h rename libNeonPy/include/Neon/py/{grid.h => dGrid.h} (53%) create mode 100644 libNeonPy/include/Neon/py/mGrid.h create mode 100644 libNeonPy/src/Neon/py/AllocationCounter.cpp create mode 100644 libNeonPy/src/Neon/py/allocationBindings.cpp create mode 100644 libNeonPy/src/Neon/py/bGrid.cpp create mode 100644 libNeonPy/src/Neon/py/dGrid.cpp delete mode 100644 libNeonPy/src/Neon/py/grid.cpp create mode 100644 libNeonPy/src/Neon/py/mGrid.cpp create mode 100644 py_neon/dense/allocationCounter.py create mode 100644 py_neon/dense/bField.py rename py_neon/dense/{grid.py => bGrid.py} (54%) create mode 100644 py_neon/dense/bPartition.py create mode 100644 py_neon/dense/bSpan.py rename py_neon/dense/{field.py => dField.py} (61%) create mode 100644 py_neon/dense/dGrid.py create mode 100644 py_neon/dense/dPartition.py create mode 100644 py_neon/dense/dSpan.py create mode 100644 py_neon/dense/mField.py create mode 100644 py_neon/dense/mGrid.py create mode 100644 py_neon/dense/mPartition.py delete mode 100644 py_neon/dense/partition.py delete mode 100644 py_neon/dense/span.py create mode 100644 py_neon/index_1d.py diff --git a/libNeonDomain/include/Neon/domain/Grids.h b/libNeonDomain/include/Neon/domain/Grids.h index 5c9701a4..85f1bbe8 100644 --- a/libNeonDomain/include/Neon/domain/Grids.h +++ b/libNeonDomain/include/Neon/domain/Grids.h @@ -4,6 +4,7 @@ #include "Neon/domain/aGrid.h" #include "Neon/domain/eGrid.h" #include "Neon/domain/bGrid.h" +#include "Neon/domain/mGrid.h" #include "Neon/domain/dGridSoA.h" #include "Neon/domain/bGridDisg.h" #include "Neon/domain/bGridMgpuDisg.h" diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h index 9c6ed821..34ec5def 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h @@ -49,6 +49,9 @@ class bSpan typename Idx::DataBlockCount mFirstDataBlockOffset; typename SBlock::BitMask const* NEON_RESTRICT mActiveMask; Neon::DataView mDataView; + + // Function to get offsets of member variables + static std::vector getOffsets(); }; } // namespace Neon::domain::details::bGrid diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h index a1206cd4..61b9f8c9 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h @@ -48,4 +48,41 @@ 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)); + + return offsets; +} +#endif + } // namespace Neon::domain::details::bGrid \ No newline at end of file diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h index eb2fbe4c..d20b897b 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h @@ -2,6 +2,7 @@ #include "Neon/set/DevSet.h" #include "dIndex.h" #include "Neon/set/ExecutionThreadSpan.h" +#include namespace Neon::domain::details::dGrid { @@ -43,6 +44,11 @@ class dSpan helpGetDim() const -> Neon::index_3d const&; + #if !defined(NEON_WARP_COMPILATION) + // Function to get offsets of member variables + static std::vector getOffsets(); + #endif + private: Neon::DataView mDataView; int mZghostRadius; diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h index 846af657..2ba21146 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h @@ -72,4 +72,16 @@ NEON_CUDA_HOST_DEVICE inline auto dSpan::helpGetDim() return mSpanDim; } +#if !defined(NEON_WARP_COMPILATION) +inline std::vector dSpan::getOffsets() { + return { + offsetof(dSpan, mDataView), + offsetof(dSpan, mZghostRadius), + offsetof(dSpan, mZboundaryRadius), + offsetof(dSpan, mMaxZInDomain), + offsetof(dSpan, mSpanDim) + }; +} +#endif + } // namespace Neon::domain::details::dGrid \ No newline at end of file diff --git a/libNeonDomain/include/Neon/domain/details/mGrid/mField.h b/libNeonDomain/include/Neon/domain/details/mGrid/mField.h index 59b1a299..35a255c3 100644 --- a/libNeonDomain/include/Neon/domain/details/mGrid/mField.h +++ b/libNeonDomain/include/Neon/domain/details/mGrid/mField.h @@ -33,6 +33,7 @@ class mField using Grid = Neon::domain::details::mGrid::mGrid; using Partition = Neon::domain::details::mGrid::mPartition; using Idx = typename Partition::Idx; + using Descriptor = mGridDescriptor<1>; mField() = default; @@ -98,6 +99,11 @@ class mField return mData->grid->getBackend(); } + auto getDescriptor() const -> const Descriptor& + { + return mData->grid->getDescriptor(); + } + private: mField(const std::string& name, const mGrid& grid, diff --git a/libNeonDomain/include/Neon/domain/details/mGrid/mField_imp.h b/libNeonDomain/include/Neon/domain/details/mGrid/mField_imp.h index 1c8bb264..e3c3814f 100644 --- a/libNeonDomain/include/Neon/domain/details/mGrid/mField_imp.h +++ b/libNeonDomain/include/Neon/domain/details/mGrid/mField_imp.h @@ -202,7 +202,7 @@ auto mField::getReference(const Neon::index_3d& idx, const int& cardinality, const int level) -> T& { - return mData->fields[level].getReference()(idx, cardinality); + return mData->fields[level].getReference(idx, cardinality); } template diff --git a/libNeonDomain/include/Neon/domain/details/mGrid/mGrid.h b/libNeonDomain/include/Neon/domain/details/mGrid/mGrid.h index 2d2634aa..75f692d6 100644 --- a/libNeonDomain/include/Neon/domain/details/mGrid/mGrid.h +++ b/libNeonDomain/include/Neon/domain/details/mGrid/mGrid.h @@ -169,6 +169,7 @@ class mGrid auto getOriginBlock3DIndex(const Neon::int32_3d idx, int level) const -> Neon::int32_3d; auto getDescriptor() const -> const Descriptor&; auto getRefFactors() const -> const Neon::set::MemSet&; + auto getGridCount() const -> uint32_t; auto getLevelSpacing() const -> const Neon::set::MemSet&; auto getBackend() const -> const Backend&; auto getBackend() -> Backend&; diff --git a/libNeonDomain/src/domain/details/mGrid/mGrid.cpp b/libNeonDomain/src/domain/details/mGrid/mGrid.cpp index a84c5bfd..8028dca0 100644 --- a/libNeonDomain/src/domain/details/mGrid/mGrid.cpp +++ b/libNeonDomain/src/domain/details/mGrid/mGrid.cpp @@ -522,6 +522,11 @@ auto mGrid::getRefFactors() const -> const Neon::set::MemSet& return mData->mRefFactors; } +auto mGrid::getGridCount() const -> uint32_t +{ + return mData->grids.size(); +} + auto mGrid::getLevelSpacing() const -> const Neon::set::MemSet& { return mData->mSpacing; diff --git a/libNeonPy/include/Neon/py/AllocationCounter.h b/libNeonPy/include/Neon/py/AllocationCounter.h new file mode 100644 index 00000000..9c278b09 --- /dev/null +++ b/libNeonPy/include/Neon/py/AllocationCounter.h @@ -0,0 +1,26 @@ +#pragma once +#include + +class AllocationCounter { +public: + // Static methods to manage allocations and deallocations + static void Allocation(); + static void Deallocation(); + + // Static method to get the current allocation count + static int GetAllocationCount(); + +private: + // Private constructor to prevent instantiation + AllocationCounter() = default; + + // Private static method to get the singleton instance + static AllocationCounter& GetInstance(); + + // Private static variable to hold the allocation count + static int allocationCount; + + // Mutex to protect access to allocationCount + static std::mutex allocationMutex; +}; + diff --git a/libNeonPy/include/Neon/py/allocationBindings.h b/libNeonPy/include/Neon/py/allocationBindings.h new file mode 100644 index 00000000..58bc67ee --- /dev/null +++ b/libNeonPy/include/Neon/py/allocationBindings.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include "AllocationCounter.h" + +/** + * Get Counter + */ +extern "C" auto get_allocation_counter() + -> int; \ No newline at end of file diff --git a/libNeonPy/include/Neon/py/bGrid.h b/libNeonPy/include/Neon/py/bGrid.h new file mode 100644 index 00000000..9e3944de --- /dev/null +++ b/libNeonPy/include/Neon/py/bGrid.h @@ -0,0 +1,95 @@ +#pragma once +#include +#include "Neon/domain/Grids.h" + +/** + * 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) + -> int; + +/** + * Delete a grid object on the heap. + */ +extern "C" auto bGrid_delete( + uint64_t& handle) + -> int; + +/** + * Generates a new field object on the heap. + */ +extern "C" auto bGrid_bField_new( + uint64_t& handle, + uint64_t& grid) + -> int; + +/** + * Delete a field object on the heap. + */ +extern "C" auto bGrid_bField_delete( + uint64_t& handle) + -> int; + +extern "C" auto bGrid_bField_get_partition( + uint64_t& field_handle, + Neon::bGrid::Partition* partition_handle, + Neon::Execution execution, + int device, + Neon::DataView data_view) + -> int; + +extern "C" auto bGrid_get_span( + uint64_t& gridHandle, + Neon::bGrid::Span* spanRes, + int execution, + int device, + int data_view) + -> int; + +extern "C" auto bGrid_span_size( + Neon::bGrid::Span* spanRes) + -> int; + +extern "C" auto bGrid_bField_partition_size( + Neon::bGrid::Partition* partitionPtr) + -> int; + +extern "C" auto bGrid_get_properties( /* TODOMATT verify what the return of this method should be */ + uint64_t& gridHandle, + const Neon::index_3d& idx) + -> int; + +extern "C" auto bGrid_is_inside_domain( + uint64_t& gridHandle, + const Neon::index_3d& idx) + -> bool; + +extern "C" auto bGrid_bField_read( + uint64_t& fieldHandle, + 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, + int newValue) + -> int; + +extern "C" auto bGrid_bField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int; + +extern "C" auto bGrid_bField_update_device_data( + uint64_t& fieldHandle, + 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 diff --git a/libNeonPy/include/Neon/py/grid.h b/libNeonPy/include/Neon/py/dGrid.h similarity index 53% rename from libNeonPy/include/Neon/py/grid.h rename to libNeonPy/include/Neon/py/dGrid.h index bc225242..8f3a178f 100644 --- a/libNeonPy/include/Neon/py/grid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -7,8 +7,15 @@ * NOTE: some parameters are still not exposed */ extern "C" auto dGrid_new( - uint64_t& handle) + uint64_t& handle, + uint64_t& backendPtr, + const Neon::int32_3d& dim) -> int; +// extern "C" auto dGrid_new( +// uint64_t& handle, +// uint64_t& backendPtr, +// Neon::index_3d dim) +// -> int; /** * Delete a grid object on the heap. @@ -54,4 +61,40 @@ extern "C" auto dGrid_span_size( extern "C" auto dGrid_dField_partition_size( Neon::dGrid::Partition* partitionPtr) - -> int; \ No newline at end of file + -> int; + +extern "C" auto dGrid_get_properties( /* TODOMATT verify what the return of this method should be */ + uint64_t& gridHandle, + const Neon::index_3d& idx) + -> int; + +extern "C" auto dGrid_is_inside_domain( + uint64_t& gridHandle, + const Neon::index_3d& idx) + -> bool; + +extern "C" auto dGrid_dField_read( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality) + -> int; + +extern "C" auto dGrid_dField_write( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality, + int newValue) + -> int; + +extern "C" auto dGrid_dField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int; + +extern "C" auto dGrid_dField_update_device_data( + uint64_t& fieldHandle, + int streamSetId) + -> int; + +extern "C" auto bGrid_bSpan_get_member_field_offsets(std::size_t* length) + -> std::size_t*; \ No newline at end of file diff --git a/libNeonPy/include/Neon/py/mGrid.h b/libNeonPy/include/Neon/py/mGrid.h new file mode 100644 index 00000000..4af9a507 --- /dev/null +++ b/libNeonPy/include/Neon/py/mGrid.h @@ -0,0 +1,99 @@ +#pragma once +#include +#include "Neon/domain/Grids.h" + +/** + * 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 mGrid_new( + uint64_t& handle, + Neon::Backend* backendPtr, + Neon::index_3d dim, + uint32_t& depth) + -> int; + +/** + * Delete a grid object on the heap. + */ +extern "C" auto mGrid_delete( + uint64_t& handle) + -> int; + +/** + * Generates a new field object on the heap. + */ +extern "C" auto mGrid_mField_new( + uint64_t& handle, + uint64_t& grid) + -> int; + +/** + * Delete a field object on the heap. + */ +extern "C" auto mGrid_mField_delete( + uint64_t& handle) + -> int; + +extern "C" auto mGrid_mField_get_partition( + uint64_t& field_handle, + Neon::domain::mGrid::Partition* partition_handle, + uint64_t& field_level, + Neon::Execution execution, + int device, + Neon::DataView data_view) + -> int; + +extern "C" auto mGrid_get_span( + uint64_t& gridHandle, + uint64_t& grid_level, + Neon::domain::mGrid::Span* spanRes, + int execution, + int device, + int data_view) + -> int; + +extern "C" auto mGrid_span_size( + Neon::domain::mGrid::Span* spanRes) + -> int; + +extern "C" auto mGrid_mField_partition_size( + Neon::domain::mGrid::Partition* partitionPtr) + -> int; + +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) + -> int; + +extern "C" auto mGrid_is_inside_domain( + uint64_t& gridHandle, + 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) + -> int; + +extern "C" auto mGrid_mField_write( + uint64_t& fieldHandle, + uint64_t& field_level, + const Neon::index_3d& idx, + const int& cardinality, + int newValue) + -> int; + +extern "C" auto mGrid_mField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int; + +extern "C" auto mGrid_mField_update_device_data( + uint64_t& fieldHandle, + int streamSetId) + -> int; \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/AllocationCounter.cpp b/libNeonPy/src/Neon/py/AllocationCounter.cpp new file mode 100644 index 00000000..3c910118 --- /dev/null +++ b/libNeonPy/src/Neon/py/AllocationCounter.cpp @@ -0,0 +1,31 @@ +#include "Neon/py/AllocationCounter.h" + +// Initialize the static member variable +int AllocationCounter::allocationCount = 0; + +// Initialize the static mutex +std::mutex AllocationCounter::allocationMutex; + +// Static method to manage allocations +void AllocationCounter::Allocation() { + std::lock_guard lock(allocationMutex); + allocationCount++; +} + +// Static method to manage deallocations +void AllocationCounter::Deallocation() { + std::lock_guard lock(allocationMutex); + allocationCount--; +} + +// Static method to get the current allocation count +int AllocationCounter::GetAllocationCount() { + std::lock_guard lock(allocationMutex); + return allocationCount; +} + +// Private static method to get the singleton instance +AllocationCounter& AllocationCounter::GetInstance() { + static AllocationCounter instance; + return instance; +} \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/allocationBindings.cpp b/libNeonPy/src/Neon/py/allocationBindings.cpp new file mode 100644 index 00000000..457037a8 --- /dev/null +++ b/libNeonPy/src/Neon/py/allocationBindings.cpp @@ -0,0 +1,8 @@ +#include "Neon/py/allocationBindings.h" +#include "Neon/py/AllocationCounter.h" + +auto get_allocation_counter() + -> int +{ + return AllocationCounter::GetAllocationCount(); +} \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp new file mode 100644 index 00000000..b0d91658 --- /dev/null +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -0,0 +1,320 @@ +#include "Neon/domain/Grids.h" +#include "Neon/py/bGrid.h" +#include "Neon/py/AllocationCounter.h" + + +auto bGrid_new( + uint64_t& handle, + uint64_t& backendPtr, + Neon::index_3d dim) + -> int +{ + std::cout << "bGrid_new - BEGIN" << std::endl; + std::cout << "bGrid_new - gridHandle " << handle << std::endl; + + Neon::init(); + + using Grid = Neon::bGrid; + Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); + Grid g(*reinterpret_cast(backendPtr), 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 = (uint64_t)gridPtr; + std::cout << "grid_new - END" << std::endl; + + // g.ioDomainToVtk("") + return 0; +} + +auto bGrid_delete( + uint64_t& handle) + -> int +{ + std::cout << "bGrid_delete - BEGIN" << std::endl; + std::cout << "bGrid_delete - gridHandle " << handle << std::endl; + + using Grid = Neon::bGrid; + Grid* gridPtr = reinterpret_cast(handle); + + if (gridPtr != nullptr) { + delete gridPtr; + AllocationCounter::Deallocation(); + } + handle = 0; + std::cout << "bGrid_delete - END" << std::endl; + return 0; +} + +auto bGrid_get_span( + uint64_t& gridHandle, + Neon::bGrid::Span* spanRes, + int execution, + int device, + int data_view) + -> int +{ + std::cout << "bGrid_get_span - BEGIN " << std::endl; + std::cout << "bGrid_get_span - gridHandle " << gridHandle << std::endl; + std::cout << "bGrid_get_span - execution " << execution << std::endl; + std::cout << "bGrid_get_span - device " << device << std::endl; + std::cout << "bGrid_get_span - data_view " << data_view << std::endl; + std::cout << "bGrid_get_span - Span size " << sizeof(*spanRes) << std::endl; + + using Grid = Neon::bGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + auto& gridSpan = grid.getSpan(Neon::ExecutionUtils::fromInt(execution), + device, + Neon::DataViewUtil::fromInt(data_view)); + (*spanRes) = gridSpan; + std::cout << "field_new - END" << &gridSpan << std::endl; + + return 0; + } + return -1; +} + +auto bGrid_bField_new( + uint64_t& handle, + uint64_t& gridHandle) + -> 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; + + using Grid = Neon::bGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + using Field = Grid::Field; + Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); + std::cout << field.toString() << std::endl; + Field* fieldPtr = new (std::nothrow) Field(field); + AllocationCounter::Allocation(); + + if (fieldPtr == nullptr) { + 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; + + return 0; + } + std::cout << "bGrid_bField_new - ERROR (grid ptr " << gridPtr << ") " << std::endl; + + return -1; +} + +auto bGrid_bField_get_partition( + uint64_t& field_handle, + [[maybe_unused]] Neon::bGrid::Partition* partitionPtr, + Neon::Execution execution, + int device, + Neon::DataView data_view) + -> int +{ + + std::cout << "bGrid_bField_get_partition - BEGIN " << std::endl; + std::cout << "bGrid_bField_get_partition - field_handle " << field_handle << std::endl; + std::cout << "bGrid_bField_get_partition - execution " << Neon::ExecutionUtils::toString(execution) << std::endl; + std::cout << "bGrid_bField_get_partition - device " << device << std::endl; + std::cout << "bGrid_bField_get_partition - data_view " << Neon::DataViewUtil::toString(data_view) << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)field_handle; + + if (fieldPtr != nullptr) { + auto p = fieldPtr->getPartition(execution, + device, + data_view); + std::cout << p.cardinality() << std::endl; + *partitionPtr = p; + + std::cout << "bGrid_bField_get_partition - END" << std::endl; + + return 0; + } + return -1; +} + +auto bGrid_bField_delete( + uint64_t& handle) + -> int +{ + std::cout << "bGrid_bField_delete - BEGIN" << std::endl; + std::cout << "bGrid_bField_delete - handle " << handle << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)handle; + + if (fieldPtr != nullptr) { + delete fieldPtr; + AllocationCounter::Deallocation(); + } + std::cout << "bGrid_bField_delete - END" << std::endl; + + return 0; +} + +auto bGrid_span_size( + Neon::bGrid::Span* spanRes) + -> int +{ + return sizeof(*spanRes); +} + +auto bGrid_bField_partition_size( + Neon::bGrid::Partition* partitionPtr) + -> int +{ + return sizeof(*partitionPtr); +} + +auto bGrid_get_properties( /* TODOMATT verify what the return of this method should be */ + uint64_t& gridHandle, + 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()); + std::cout << "bGrid_get_properties end" << std::endl; + + return returnValue; +} + +auto bGrid_is_inside_domain( + uint64_t& gridHandle, + const Neon::index_3d& 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); + + std::cout << "bGrid_is_inside_domain end" << std::endl; + + + return returnValue; +} + +auto bGrid_bField_read( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality) + -> int +{ + std::cout << "bGrid_bField_read begin" << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + } + + auto returnValue = (*fieldPtr)(idx, cardinality); + + std::cout << "bGrid_bField_read end" << std::endl; + + return returnValue; +} + +auto bGrid_bField_write( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality, + int newValue) + -> int +{ + std::cout << "bGrid_bField_write begin" << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->getReference(idx, cardinality) = newValue; + + std::cout << "bGrid_bField_write end" << std::endl; + return 0; +} + +auto bGrid_bField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "bGrid_bField_update_host_data begin" << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateHostData(streamSetId); + + std::cout << "bGrid_bField_update_host_data end" << std::endl; + return 0; +} + +auto bGrid_bField_update_device_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "bGrid_bField_update_device_data begin" << std::endl; + + using Grid = Neon::bGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateDeviceData(streamSetId); + + std::cout << "bGrid_bField_update_device_data end" << std::endl; + return 0; +} + +extern "C" auto bGrid_bSpan_get_member_field_offsets(std::size_t* length) + -> std::size_t* +{ + 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 diff --git a/libNeonPy/src/Neon/py/backend.cpp b/libNeonPy/src/Neon/py/backend.cpp index ef4a538d..c3593400 100644 --- a/libNeonPy/src/Neon/py/backend.cpp +++ b/libNeonPy/src/Neon/py/backend.cpp @@ -1,5 +1,6 @@ #include "Neon/py/backend.h" #include "Neon/set/Backend.h" +#include "Neon/py/AllocationCounter.h" void backend_constructor_prologue(uint64_t& handle) { std::cout << "dBackend_new - BEGIN" << std::endl; @@ -11,9 +12,9 @@ int backend_constructor_epilogue(uint64_t& handle, Neon::Backend* backendPtr) { std::cout << "NeonPy: Initialization error. Unable to allocage backend " << std::endl; return -1; } - handle = (uint64_t)backendPtr; + handle = reinterpret_cast(backendPtr); std::cout << "allocated backend heap location: " << backendPtr << std::endl; - std::cout << "grid_new - END" << std::endl; + std::cout << "backend_new - END" << std::endl; return 0; } @@ -22,6 +23,8 @@ auto dBackend_new1( -> int { std::cout << "first constructor" << std::endl; + AllocationCounter::Allocation(); + backend_constructor_prologue(handle); auto backendPtr = new (std::nothrow) Neon::Backend(); @@ -30,12 +33,13 @@ auto dBackend_new1( } auto dBackend_new2( - std::cout << "second constructor" << std::endl; 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)); @@ -44,15 +48,17 @@ auto dBackend_new2( } auto dBackend_new3( - std::cout << "third constructor" << std::endl; uint64_t& handle, const int* devIds, int runtime) -> int { + std::cout << "third constructor" << std::endl; + backend_constructor_prologue(handle); - auto backendPtr = new (std::nothrow) Neon::Backend(std::vector(*devIds), Neon::runtime(runtime)); + auto backendPtr = new (std::nothrow) Neon::Backend(std::vector(*devIds), Neon::Runtime(runtime)); + AllocationCounter::Allocation(); return backend_constructor_epilogue(handle, backendPtr); } @@ -69,6 +75,7 @@ auto dBackend_delete( if (backendPtr != nullptr) { delete backendPtr; + AllocationCounter::Deallocation(); } handle = 0; std::cout << "dBackend_delete - END" << std::endl; diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp new file mode 100644 index 00000000..c20e29d9 --- /dev/null +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -0,0 +1,367 @@ +#include "Neon/py/dGrid.h" +#include "Neon/domain/Grids.h" +#include "Neon/set/Backend.h" +#include "Neon/py/AllocationCounter.h" + +auto dGrid_new( + uint64_t& handle, + uint64_t& backendPtr, + const Neon::int32_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::int32_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); + 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_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) + -> int +{ + std::cout << "dGrid_delete - gridHandle " << handle << std::endl << std::flush; + std::cout << "dGrid_delete - BEGIN" << std::endl; + std::cout << "test" << std::endl; + + using Grid = Neon::dGrid; + Grid* gridPtr = reinterpret_cast(handle); + + if (gridPtr != nullptr) { + delete gridPtr; + AllocationCounter::Deallocation(); + } + handle = 0; + std::cout << "dGrid_delete - END" << std::endl; + return 0; +} + +auto dGrid_get_span( + uint64_t& gridHandle, + Neon::dGrid::Span* spanRes, + int execution, + int device, + int data_view) + -> int +{ + std::cout << "dGrid_get_span - BEGIN " << std::endl; + std::cout << "dGrid_get_span - gridHandle " << gridHandle << std::endl; + std::cout << "dGrid_get_span - execution " << execution << std::endl; + std::cout << "dGrid_get_span - device " << device << std::endl; + std::cout << "dGrid_get_span - data_view " << data_view << std::endl; + std::cout << "dGrid_get_span - Span size " << sizeof(*spanRes) << std::endl; + + using Grid = Neon::dGrid; + Grid* gridPtr = (Grid*)gridHandle; + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + auto& gridSpan = grid.getSpan(Neon::ExecutionUtils::fromInt(execution), + device, + Neon::DataViewUtil::fromInt(data_view)); + (*spanRes) = gridSpan; + std::cout << "dGrid_get_span - END" << &gridSpan << std::endl; + + return 0; + } + return -1; +} + +auto dGrid_dField_new( + uint64_t& handle, + uint64_t& gridHandle) + -> int +{ + std::cout << "dGrid_dField_new - BEGIN" << std::endl; + std::cout << "dGrid_dField_new - gridHandle " << gridHandle << std::endl; + std::cout << "dGrid_dField_new - handle " << handle << std::endl; + + using Grid = Neon::dGrid; + Grid* gridPtr = (Grid*)gridHandle; + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + using Field = Grid::Field; + Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); + std::cout << field.toString() << std::endl; + Field* fieldPtr = new (std::nothrow) Field(field); + AllocationCounter::Allocation(); + + if (fieldPtr == nullptr) { + std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; + return -1; + } + handle = (uint64_t)fieldPtr; + std::cout << "dGrid_dField_new - END " << handle << std::endl; + + return 0; + } + std::cout << "dGrid_dField_new - ERROR (grid ptr " << gridPtr << ") " << std::endl; + + return -1; +} + +auto dGrid_dField_get_partition( + uint64_t& field_handle, + [[maybe_unused]] Neon::dGrid::Partition* partitionPtr, + Neon::Execution execution, + int device, + Neon::DataView data_view) + -> int +{ + + std::cout << "dGrid_dField_get_partition - BEGIN " << std::endl; + std::cout << "dGrid_dField_get_partition - field_handle " << field_handle << std::endl; + std::cout << "dGrid_dField_get_partition - execution " << Neon::ExecutionUtils::toString(execution) << std::endl; + std::cout << "dGrid_dField_get_partition - device " << device << std::endl; + std::cout << "dGrid_dField_get_partition - data_view " << Neon::DataViewUtil::toString(data_view) << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)field_handle; + std::cout << fieldPtr->toString() << std::endl; + + if (fieldPtr != nullptr) { + auto p = fieldPtr->getPartition(execution, + device, + data_view); + std::cout << p.cardinality() << std::endl; + *partitionPtr = p; + std::cout << "dGrid_dField_get_partition\n" + << partitionPtr->to_string(); + + std::cout << "dGrid_dField_get_partition - END" << std::endl; + + return 0; + } + return -1; +} + +auto dGrid_dField_delete( + uint64_t& handle) + -> int +{ + std::cout << "dGrid_dField_delete - BEGIN" << std::endl; + std::cout << "dGrid_dField_delete - handle " << handle << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)handle; + + if (fieldPtr != nullptr) { + delete fieldPtr; + AllocationCounter::Deallocation(); + } + std::cout << "dGrid_dField_delete - END" << std::endl; + + return 0; +} + +auto dGrid_span_size( + Neon::dGrid::Span* spanRes) + -> int +{ + return sizeof(*spanRes); +} + +auto dGrid_dField_partition_size( + Neon::dGrid::Partition* partitionPtr) + -> int +{ + return sizeof(*partitionPtr); +} + +auto dGrid_get_properties( /* TODOMATT verify what the return of this method should be */ + uint64_t& gridHandle, + const Neon::index_3d& 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()); + std::cout << "dGrid_get_properties end" << std::endl; + + return returnValue; +} + +auto dGrid_is_inside_domain( + uint64_t& gridHandle, + const Neon::index_3d& 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); + + std::cout << "dGrid_is_inside_domain end" << std::endl; + + + return returnValue; +} + +auto dGrid_dField_read( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality) + -> int +{ + std::cout << "dGrid_dField_read begin" << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + } + + auto returnValue = (*fieldPtr)(idx, cardinality); + + std::cout << "dGrid_dField_read end" << std::endl; + + return returnValue; +} + +auto dGrid_dField_write( + uint64_t& fieldHandle, + const Neon::index_3d& idx, + const int& cardinality, + int newValue) + -> int +{ + std::cout << "dGrid_dField_write begin" << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->getReference(idx, cardinality) = newValue; + + std::cout << "dGrid_dField_write end" << std::endl; + return 0; +} + +auto dGrid_dField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "dGrid_dField_update_host_data begin" << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateHostData(streamSetId); + + std::cout << "dGrid_dField_update_host_data end" << std::endl; + return 0; +} + +auto dGrid_dField_update_device_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "dGrid_dField_update_device_data begin" << std::endl; + + using Grid = Neon::dGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)fieldHandle; + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateDeviceData(streamSetId); + + std::cout << "dGrid_dField_update_device_data end" << std::endl; + return 0; +} + +extern "C" auto dGrid_dSpan_get_member_field_offsets(std::size_t* length) + -> std::size_t* +{ + std::vector offsets = Neon::domain::details::dGrid::dSpan::getOffsets(); + *length = offsets.size(); + return offsets.data(); +} \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/grid.cpp b/libNeonPy/src/Neon/py/grid.cpp deleted file mode 100644 index f3d6b81f..00000000 --- a/libNeonPy/src/Neon/py/grid.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "Neon/py/grid.h" -#include "Neon/domain/Grids.h" - -auto dGrid_new( - uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim) - -> int -{ - std::cout << "dGrid_new - BEGIN" << std::endl; - std::cout << "dGrid_get_span - gridHandle " << handle << std::endl; - - Neon::init(); - - using Grid = Neon::dGrid; - Neon::domain::Stencil d3q19 = Neon::domain::Stencil::s19_t(false); - Grid g(*backendPtr, dim, [](Neon::index_3d const& /*idx*/) { return true; }, d3q19); - auto gridPtr = new (std::nothrow) Grid(g); - - if (gridPtr == nullptr) { - std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; - return -1; - } - handle = (uint64_t)gridPtr; - std::cout << "grid_new - END" << std::endl; - - // g.ioDomainToVtk("") - return 0; -} - -auto dGrid_delete( - uint64_t& handle) - -> int -{ - std::cout << "dGrid_delete - BEGIN" << std::endl; - std::cout << "dGrid_get_span - gridHandle " << handle << std::endl; - - using Grid = Neon::dGrid; - Grid* gridPtr = (Grid*)handle; - - if (gridPtr != nullptr) { - delete gridPtr; - } - handle = 0; - std::cout << "dGrid_delete - END" << std::endl; - return 0; -} - -auto dGrid_get_span( - uint64_t& gridHandle, - Neon::dGrid::Span* spanRes, - int execution, - int device, - int data_view) - -> int -{ - std::cout << "dGrid_get_span - BEGIN " << std::endl; - std::cout << "dGrid_get_span - gridHandle " << gridHandle << std::endl; - std::cout << "dGrid_get_span - execution " << execution << std::endl; - std::cout << "dGrid_get_span - device " << device << std::endl; - std::cout << "dGrid_get_span - data_view " << data_view << std::endl; - std::cout << "dGrid_get_span - Span size " << sizeof(*spanRes) << std::endl; - - using Grid = Neon::dGrid; - Grid* gridPtr = (Grid*)gridHandle; - Grid& grid = *gridPtr; - - if (gridPtr != nullptr) { - auto& gridSpan = grid.getSpan(Neon::ExecutionUtils::fromInt(execution), - device, - Neon::DataViewUtil::fromInt(data_view)); - (*spanRes) = gridSpan; - std::cout << "field_new - END" << &gridSpan << std::endl; - - return 0; - } - return -1; -} - -auto dGrid_dField_new( - uint64_t& handle, - uint64_t& gridHandle) - -> int -{ - std::cout << "dGrid_dField_new - BEGIN" << std::endl; - std::cout << "dGrid_dField_new - gridHandle " << gridHandle << std::endl; - std::cout << "dGrid_dField_new - handle " << handle << std::endl; - - using Grid = Neon::dGrid; - Grid* gridPtr = (Grid*)gridHandle; - Grid& grid = *gridPtr; - - if (gridPtr != nullptr) { - using Field = Grid::Field; - Field field = grid.newField("test", 1, 0, Neon::DataUse::HOST_DEVICE); - std::cout << field.toString() << std::endl; - Field* fieldPtr = new (std::nothrow) Field(field); - if (fieldPtr == nullptr) { - std::cout << "NeonPy: Initialization error. Unable to allocage grid " << std::endl; - return -1; - } - handle = (uint64_t)fieldPtr; - std::cout << "dGrid_dField_new - END " << handle << std::endl; - - return 0; - } - std::cout << "dGrid_dField_new - ERROR (grid ptr " << gridPtr << ") " << std::endl; - - return -1; -} - -auto dGrid_dField_get_partition( - uint64_t& field_handle, - [[maybe_unused]] Neon::dGrid::Partition* partitionPtr, - Neon::Execution execution, - int device, - Neon::DataView data_view) - -> int -{ - - std::cout << "dGrid_dField_get_partition - BEGIN " << std::endl; - std::cout << "dGrid_dField_get_partition - field_handle " << field_handle << std::endl; - std::cout << "dGrid_dField_get_partition - execution " << Neon::ExecutionUtils::toString(execution) << std::endl; - std::cout << "dGrid_dField_get_partition - device " << device << std::endl; - std::cout << "dGrid_dField_get_partition - data_view " << Neon::DataViewUtil::toString(data_view) << std::endl; - - using Grid = Neon::dGrid; - using Field = Grid::Field; - - Field* fieldPtr = (Field*)field_handle; - std::cout << fieldPtr->toString() << std::endl; - - if (fieldPtr != nullptr) { - auto p = fieldPtr->getPartition(execution, - device, - data_view); - std::cout << p.cardinality() << std::endl; - *partitionPtr = p; - std::cout << "dGrid_dField_get_partition\n" - << partitionPtr->to_string(); - - std::cout << "dGrid_dField_get_partition - END" << std::endl; - - return 0; - } - return -1; -} - -auto dGrid_dField_delete( - uint64_t& handle) - -> int -{ - std::cout << "dGrid_dField_delete - BEGIN" << std::endl; - std::cout << "dGrid_dField_delete - handle " << handle << std::endl; - - using Grid = Neon::dGrid; - using Field = Grid::Field; - - Field* fieldPtr = (Field*)handle; - - if (fieldPtr != nullptr) { - delete fieldPtr; - } - std::cout << "dGrid_dField_delete - END" << std::endl; - - return 0; -} - -auto dGrid_span_size( - Neon::dGrid::Span* spanRes) - -> int -{ - return sizeof(*spanRes); -} - -auto dGrid_dField_partition_size( - Neon::dGrid::Partition* partitionPtr) - -> int -{ - return sizeof(*partitionPtr); -} \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp new file mode 100644 index 00000000..51002dce --- /dev/null +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -0,0 +1,335 @@ +#include "Neon/py/mGrid.h" +#include "Neon/domain/Grids.h" +#include "Neon/py/AllocationCounter.h" + +auto mGrid_new( + uint64_t& handle, + Neon::Backend* backendPtr, + Neon::index_3d dim, + uint32_t& depth) + -> int +{ + std::cout << "mGrid_new - BEGIN" << std::endl; + std::cout << "mGrid_new - gridHandle " << handle << std::endl; + + Neon::init(); + + using Grid = Neon::domain::mGrid; + 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)); + 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 = (uint64_t)gridPtr; + std::cout << "grid_new - END" << std::endl; + + // g.ioDomainToVtk("") + return 0; +} + + +auto mGrid_delete( + uint64_t& handle) + -> int +{ + std::cout << "mGrid_delete - BEGIN" << std::endl; + std::cout << "mGrid_delete - gridHandle " << handle << std::endl; + + using Grid = Neon::domain::mGrid; + Grid* gridPtr = reinterpret_cast(handle); + + if (gridPtr != nullptr) { + delete gridPtr; + AllocationCounter::Deallocation(); + } + handle = 0; + + std::cout << "mGrid_delete - END" << std::endl; + return 0; +} + +auto mGrid_get_span( + uint64_t& gridHandle, + uint64_t& grid_level, + Neon::domain::mGrid::Span* spanRes, + int execution, + int device, + int data_view) + -> int +{ + std::cout << "mGrid_get_span - BEGIN " << std::endl; + std::cout << "mGrid_get_span - gridHandle " << gridHandle << std::endl; + std::cout << "mGrid_get_span - grid_level " << grid_level << std::endl; + std::cout << "mGrid_get_span - execution " << execution << std::endl; + std::cout << "mGrid_get_span - device " << device << std::endl; + std::cout << "mGrid_get_span - data_view " << data_view << std::endl; + std::cout << "mGrid_get_span - Span size " << sizeof(*spanRes) << std::endl; + + using Grid = Neon::domain::mGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + if (grid_level < grid.getGridCount()) { + std::cout << "grid_level out of range in mGrid_get_span" << std::endl; + } + auto& gridSpan = grid(grid_level).getSpan(Neon::ExecutionUtils::fromInt(execution), + device, + Neon::DataViewUtil::fromInt(data_view)); + (*spanRes) = gridSpan; + std::cout << "field_new - END" << &gridSpan << std::endl; + + return 0; + } + return -1; +} + +auto mGrid_mField_new( + uint64_t& handle, + uint64_t& gridHandle) + -> 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; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + Grid* gridPtr = reinterpret_cast(handle); + Grid& grid = *gridPtr; + + if (gridPtr != nullptr) { + Field field = grid.newField("test", 1, 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; + + return 0; + } + std::cout << "mGrid_mField_new - ERROR (grid ptr " << gridPtr << ") " << std::endl; + + return -1; +} + +auto mGrid_mField_get_partition( + uint64_t& field_handle, + [[maybe_unused]] Neon::domain::mGrid::Partition* partitionPtr, + uint64_t& field_level, + Neon::Execution execution, + int device, + Neon::DataView data_view) + -> int +{ + + std::cout << "mGrid_mField_get_partition - BEGIN " << std::endl; + std::cout << "mGrid_mField_get_partition - field_handle " << field_handle << std::endl; + std::cout << "mGrid_mField_get_partition - execution " << Neon::ExecutionUtils::toString(execution) << std::endl; + std::cout << "mGrid_mField_get_partition - field_level " << field_level << std::endl; + std::cout << "mGrid_mField_get_partition - device " << device << std::endl; + std::cout << "mGrid_mField_get_partition - data_view " << Neon::DataViewUtil::toString(data_view) << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)field_handle; + + if (fieldPtr != nullptr) { + const auto& descriptor = fieldPtr->getDescriptor(); + + // check to make sure that the given field level is within bounds. The first clause is to allow a cast in the second clause. + if (descriptor.getDepth() < 0 || field_level >= static_cast(descriptor.getDepth())) { + std::cout << "field index out of bounds" << std::endl; + return -1; + } + auto p = (*fieldPtr)(field_level).getPartition(execution, + device, + data_view); + std::cout << p.cardinality() << std::endl; + *partitionPtr = p; + + std::cout << "mGrid_mField_get_partition - END" << std::endl; + + return 0; + } + return -1; +} + +auto mGrid_mField_delete( + uint64_t& handle) + -> int +{ + std::cout << "mGrid_mField_delete - BEGIN" << std::endl; + std::cout << "mGrid_mField_delete - handle " << handle << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = (Field*)handle; + + if (fieldPtr != nullptr) { + delete fieldPtr; + AllocationCounter::Allocation(); + } + std::cout << "mGrid_mField_delete - END" << std::endl; + + return 0; +} + +auto mGrid_span_size( + Neon::domain::mGrid::Span* spanRes) + -> int +{ + return sizeof(*spanRes); +} + +auto mGrid_mField_partition_size( + Neon::domain::mGrid::Partition* partitionPtr) + -> int +{ + return sizeof(*partitionPtr); +} + +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) + -> int +{ + std::cout << "mGrid_get_properties begin" << std::endl; + + using Grid = Neon::domain::mGrid; + Grid* gridPtr = reinterpret_cast(gridHandle); + 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()); + std::cout << "mGrid_get_properties end" << std::endl; + + return returnValue; +} + +auto mGrid_is_inside_domain( + uint64_t& gridHandle, + uint64_t& grid_level, + const Neon::index_3d& idx + ) + -> bool +{ + std::cout << "mGrid_is_inside_domain begin" << std::endl; + + 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; + + + return returnValue; +} + +auto mGrid_mField_read( + uint64_t& fieldHandle, + uint64_t& field_level, + const Neon::index_3d& idx, + const int& cardinality) + -> int +{ + std::cout << "mGrid_mField_read begin" << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + } + + auto returnValue = (*fieldPtr)(idx, cardinality, field_level); + + std::cout << "mGrid_mField_read end" << std::endl; + + return returnValue; +} + +auto mGrid_mField_write( + uint64_t& fieldHandle, + uint64_t& field_level, + const Neon::index_3d& idx, + const int& cardinality, + int newValue) + -> int +{ + std::cout << "mGrid_mField_write begin" << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->getReference(idx, cardinality, field_level) = newValue; + + std::cout << "mGrid_mField_write end" << std::endl; + return 0; +} + +auto mGrid_mField_update_host_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "mGrid_mField_update_host_data begin" << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateHostData(streamSetId); + + std::cout << "mGrid_mField_update_host_data end" << std::endl; + return 0; +} + +auto mGrid_mField_update_device_data( + uint64_t& fieldHandle, + int streamSetId) + -> int +{ + std::cout << "mGrid_mField_update_device_data begin" << std::endl; + + using Grid = Neon::domain::mGrid; + using Field = Grid::Field; + + Field* fieldPtr = reinterpret_cast(fieldHandle); + + if (fieldPtr == nullptr) { + std::cout << "invalid field" << std::endl; + return -1; + } + + fieldPtr->updateDeviceData(streamSetId); + + std::cout << "mGrid_mField_update_device_data end" << std::endl; + return 0; +} \ No newline at end of file diff --git a/py_neon/dense/__init__.py b/py_neon/dense/__init__.py index aa1f6aef..196f94a5 100644 --- a/py_neon/dense/__init__.py +++ b/py_neon/dense/__init__.py @@ -1,4 +1,14 @@ -from .span import Span -from .field import Field -from .grid import Grid +from .backend import Backend +from .dGrid import dGrid +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 .allocationCounter import allocationCounter # from .partition import PartitionInt \ No newline at end of file diff --git a/py_neon/dense/allocationCounter.py b/py_neon/dense/allocationCounter.py new file mode 100644 index 00000000..28d3a06c --- /dev/null +++ b/py_neon/dense/allocationCounter.py @@ -0,0 +1,27 @@ +import copy +import ctypes +from enum import Enum +from py_neon import Py_neon + +from py_neon.py_ne import Py_neon as NePy_neon + + + + +class allocationCounter(object): + 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): + # 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/dense/bField.py b/py_neon/dense/bField.py new file mode 100644 index 00000000..e7febaf1 --- /dev/null +++ b/py_neon/dense/bField.py @@ -0,0 +1,138 @@ +import copy +import ctypes +from enum import Enum +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 + ): + + if grid_handle == 0: + raise Exception('bField: Invalid handle') + + self.py_neon = py_neon + 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() + + def __del__(self): + self.help_delete() + + def help_load_api(self): + # Importing new functions + ## new_field + self.py_neon.lib.bGrid_bField_new.argtypes = [self.handle_type, + self.handle_type] + self.py_neon.lib.bGrid_bField_new.restype = ctypes.c_int + + ## delete_field + self.py_neon.lib.bGrid_bField_delete.argtypes = [self.handle_type] + self.py_neon.lib.bGrid_bField_delete.restype = ctypes.c_int + + ## get_partition + self.py_neon.lib.bGrid_bField_get_partition.argtypes = [self.handle_type, + ctypes.POINTER(NeBPartitionInt), # the span object + NeExecution, # the execution type + ctypes.c_int, # the device id + NeDataView, # the data view + ] + self.py_neon.lib.bGrid_bField_get_partition.restype = ctypes.c_int + + # size partition + self.py_neon.lib.bGrid_bField_partition_size.argtypes = [ctypes.POINTER(NeBPartitionInt)] + self.py_neon.lib.bGrid_bField_partition_size.restype = ctypes.c_int + + # field read + self.py_neon.lib.bGrid_bField_read.argtypes = [self.handle_type, + 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.c_int, + ctypes.c_int] + self.py_neon.lib.bGrid_bField_write.restype = ctypes.c_int + + # field update host data + self.py_neon.lib.bGrid_bField_update_host_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.bGrid_bField_update_host_data.restype = ctypes.c_int + + # field update device data + self.py_neon.lib.bGrid_bField_update_device_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.bGrid_bField_update_device_data.restype = ctypes.c_int + + + + def help_new(self): + if self.handle == 0: + raise Exception('bGrid: Invalid handle') + + res = self.py_neon.lib.bGrid_bField_new(self.handle, self.grid_handle) + 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) + 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, + # execution: NeExecution, + # c: ctypes.c_int, + # data_view: NeDataView + # ) -> Wpne_NeonDensePartitionInt: + + # if self.handle == 0: + # raise Exception('bField: Invalid handle') + + # partition = NeBPartitionInt() + + # res = self.py_neon.lib.bGrid_bField_get_partition(self.handle, + # partition, + # execution, + # c, + # data_view) + # if res != 0: + # raise Exception('Failed to get span') + + # ccp_size = self.py_neon.lib.bGrid_bField_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 read(self, idx: Index_3d, cardinality: int): + return self.py_neon.lib.bGrid_bField_read(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 updateHostData(self, streamSetId: int): + return self.py_neon.lib.bGrid_bField_update_host_data(self.handle, streamSetId) + + def updateDeviceData(self, streamSetId: int): + return self.py_neon.lib.bGrid_bField_update_device_data(self.handle, streamSetId) + \ No newline at end of file diff --git a/py_neon/dense/grid.py b/py_neon/dense/bGrid.py similarity index 54% rename from py_neon/dense/grid.py rename to py_neon/dense/bGrid.py index f0572535..ca75034b 100644 --- a/py_neon/dense/grid.py +++ b/py_neon/dense/bGrid.py @@ -3,15 +3,17 @@ from enum import Enum import py_neon -from .field import Field +from .bField import bField from py_neon.execution import Execution from py_neon import Py_neon from py_neon.dataview import DataView -from .span import Span +from .bSpan import bSpan from .backend import Backend +from py_neon.index_3d import Index_3d + +class bGrid(object): -class Grid(object): def __init__(self, backend = None, dim = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend @@ -32,67 +34,82 @@ 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.lib.bGrid_new.argtypes = [self.py_neon.handle_type, ctypes.POINTER(Backend), py_neon.Index_3d] - self.py_neon.lib.dGrid_new.restype = ctypes.c_int + self.py_neon.lib.bGrid_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.bGrid_delete.argtypes = [self.py_neon.handle_type] + self.py_neon.lib.bGrid_delete.restype = ctypes.c_int - self.py_neon.lib.dGrid_get_span.argtypes = [self.py_neon.handle_type, + self.py_neon.lib.bGrid_get_span.argtypes = [self.py_neon.handle_type, ctypes.POINTER(Span), # 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.dGrid_get_span.restype = ctypes.c_int + self.py_neon.lib.bGrid_get_span.restype = ctypes.c_int + + self.py_neon.lib.bGrid_span_size.argtypes = [ctypes.POINTER(bSpan)] + self.py_neon.lib.bGrid_span_size.restype = ctypes.c_int + + + self.py_neon.lib.bGrid_get_properties.argtypes = [self.py_neon.handle_type, + py_neon.Index_3d] + self.py_neon.lib.bGrid_get_properties.restype = ctypes.c_int - self.py_neon.lib.dGrid_span_size.argtypes = [ctypes.POINTER(Span)] - self.py_neon.lib.dGrid_span_size.restype = ctypes.c_int + self.py_neon.lib.bGrid_is_inside_domain.argtypes = [self.py_neon.handle_type, + 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('DGrid: Invalid handle') + 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) - res = self.py_neon.lib.dGrid_new(self.handle, self.backend.handle, self.dim) + res = self.py_neon.lib.bGrid_new(self.handle, self.backend.handle, self.dim) if res != 0: - raise Exception('DGrid: Failed to initialize grid') + raise Exception('bGrid: Failed to initialize grid') def help_grid_delete(self): if self.handle == 0: return - res = self.py_neon.lib.dGrid_delete(self.handle) + res = self.py_neon.lib.bGrid_delete(self.handle) if res != 0: raise Exception('Failed to delete grid') - def new_field(self) -> Field: - field = Field(self.py_neon, self.handle) + def new_field(self) -> bField: + field = bField(self.py_neon, self.handle) return field def get_span(self, execution: Execution, c: ctypes.c_int, - data_view: DataView) -> Span: + data_view: DataView) -> bSpan: if self.handle == 0: - raise Exception('DGrid: Invalid handle') + raise Exception('bGrid: Invalid handle') - span = Span() - res = self.py_neon.lib.dGrid_get_span(self.handle, span, execution, c, data_view) + span = bSpan() + res = self.py_neon.lib.bGrid_get_span(self.handle, span, execution, c, data_view) if res != 0: raise Exception('Failed to get span') - cpp_size = self.py_neon.lib.dGrid_span_size(span) + cpp_size = self.py_neon.lib.bGrid_span_size(span) ctypes_size = ctypes.sizeof(span) if cpp_size != ctypes_size: raise Exception(f'Failed to get span: cpp_size {cpp_size} != ctypes_size {ctypes_size}') return span + + def getProperties(self, idx: Index_3d): + return DataView.from_int(self.py_neon.lib.bGrid_get_properties(self.handle, idx)) + + def isInsideDomain(self, idx: Index_3d): + return self.py_neon.lib.bGrid_is_inside_domain(self.handle, idx) diff --git a/py_neon/dense/bPartition.py b/py_neon/dense/bPartition.py new file mode 100644 index 00000000..966db495 --- /dev/null +++ b/py_neon/dense/bPartition.py @@ -0,0 +1,34 @@ +import copy +import ctypes +from enum import Enum + +import py_neon + + +class bPartitionInt(ctypes.Structure): + _fields_ = [ + ("setIdx", ctypes.c_int), + ("mCardinality", ctypes.c_int), + ("mMem", 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)), + ("mDomainSize", py_neon.Index_3d) + ] + + def __str__(self): + def get_offset(field_name): + return ctypes.offsetof(bPartitionInt, field_name) + + 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')})" + return str_repr + diff --git a/py_neon/dense/bSpan.py b/py_neon/dense/bSpan.py new file mode 100644 index 00000000..5b694b35 --- /dev/null +++ b/py_neon/dense/bSpan.py @@ -0,0 +1,51 @@ +import copy +import ctypes +from enum import Enum +from py_neon import Py_neon + +from py_neon import DataView + +class bSpan(ctypes.Structure): + 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): + + # 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 get_member_field_offsets(self): + length = ctypes.c_size_t() + offsets = self.py_neon.lib.bGrid_bSpan_get_member_field_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')})" + 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')] + + @staticmethod + def fields_(): + return bSpan._fields_ \ No newline at end of file diff --git a/py_neon/dense/backend.py b/py_neon/dense/backend.py index 771ab75d..ef60dd94 100644 --- a/py_neon/dense/backend.py +++ b/py_neon/dense/backend.py @@ -57,6 +57,9 @@ 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 + # TODOMATT get num devices + # TODOMATT get device type + def help_backend_new(self, arg1=None, arg2=None): @@ -65,17 +68,17 @@ def help_backend_new(self, arg1=None, arg2=None): if arg1 is None and arg2 is None: # Call the empty constructor - res = self.py_neon.lib.dBackend_new1(self.handle) - elif isinstance(arg1, int) and isinstance(arg2, int): + res = self.py_neon.lib.dBackend_new1(ctypes.byref(self.handle)) + elif isinstance(arg1, int) and isinstance(arg2, Backend.Runtime): # Call the constructor with nGpus and runtime - res = self.py_neon.lib.dBackend_new2(self.handle, arg1, arg2) - elif isinstance(arg1, list) and isinstance(arg2, int): + res = self.py_neon.lib.dBackend_new2(ctypes.byref(self.handle), arg1, arg2.value) + elif isinstance(arg1, list) and isinstance(arg2, Backend.Runtime): # Call the constructor with devIds and runtime - from ctypes import c_int, POINTER, byref + from ctypes import c_int # Convert the list to a ctypes array dev_ids = (c_int * len(arg1))(*arg1) - res = self.py_neon.lib.dBackend_new3(self.handle, dev_ids, arg2) + res = self.py_neon.lib.dBackend_new3(ctypes.byref(self.handle), dev_ids, arg2.value) else: raise Exception('DBackend: Invalid arguments provided') diff --git a/py_neon/dense/field.py b/py_neon/dense/dField.py similarity index 61% rename from py_neon/dense/field.py rename to py_neon/dense/dField.py index 9b3ce651..2911323d 100644 --- a/py_neon/dense/field.py +++ b/py_neon/dense/dField.py @@ -1,14 +1,15 @@ import copy import ctypes from enum import Enum -from .partition import PartitionInt as NePartitionInt +import py_neon +from .dPartition import dPartitionInt as NeDPartition 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 wpne.dense.partition import NeonDensePartitionInt as Wpne_NeonDensePartitionInt +from py_neon.index_3d import Index_3d -class Field(object): +class dField(object): def __init__(self, py_neon: NePy_neon, grid_handle: ctypes.c_uint64 @@ -40,7 +41,7 @@ def help_load_api(self): ## get_partition self.py_neon.lib.dGrid_dField_get_partition.argtypes = [self.handle_type, - ctypes.POINTER(NePartitionInt), # the span object + ctypes.POINTER(NeDPartition), # the span object NeExecution, # the execution type ctypes.c_int, # the device id NeDataView, # the data view @@ -48,9 +49,34 @@ 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(NePartitionInt)] + self.py_neon.lib.dGrid_dField_partition_size.argtypes = [ctypes.POINTER(NeDPartition)] 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.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.c_int, + ctypes.c_int] + self.py_neon.lib.dGrid_dField_write.restype = ctypes.c_int + + # field update host data + self.py_neon.lib.dGrid_dField_update_host_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.dGrid_dField_update_host_data.restype = ctypes.c_int + + # field update device data + self.py_neon.lib.dGrid_dField_update_device_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.dGrid_dField_update_device_data.restype = ctypes.c_int + + + def help_new(self): if self.handle == 0: raise Exception('DGrid: Invalid handle') @@ -70,12 +96,12 @@ def get_partition(self, execution: NeExecution, c: ctypes.c_int, data_view: NeDataView - ) -> Wpne_NeonDensePartitionInt: + ) -> NeDPartition: if self.handle == 0: raise Exception('DField: Invalid handle') - partition = NePartitionInt() + partition = NeDPartition() res = self.py_neon.lib.dGrid_dField_get_partition(self.handle, partition, @@ -92,5 +118,17 @@ def get_partition(self, 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 + return partition + + def read(self, idx: Index_3d, cardinality: int): + return self.py_neon.lib.dGrid_dField_read(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 updateHostData(self, streamSetId: int): + return self.py_neon.lib.dGrid_dField_update_host_data(self.handle, streamSetId) + + def updateDeviceData(self, streamSetId: int): + return self.py_neon.lib.dGrid_dField_update_device_data(self.handle, streamSetId) + \ No newline at end of file diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py new file mode 100644 index 00000000..8132e2c8 --- /dev/null +++ b/py_neon/dense/dGrid.py @@ -0,0 +1,120 @@ +import copy +import ctypes +from enum import Enum + +import py_neon +from .dField import dField +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 py_neon.index_3d import Index_3d +import numpy as np + +import sys + +class dGrid(object): + + + def __init__(self, backend = None, dim = None): + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) + self.backend = backend if backend is not None else Backend() # @TODOMATT if the input is not the correct type, throw an error + self.dim = dim if dim is not None else Index_3d(10, 10, 10) # @TODOMATT if the input is not the correct type, throw an error + 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() + + def __del__(self): + if self.handle.value != 0: + self.help_grid_delete() + + 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, + py_neon.Index_3d] + 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_span.argtypes = [self.py_neon.handle_type, + ctypes.POINTER(dSpan), # 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.dGrid_get_span.restype = ctypes.c_int + + self.py_neon.lib.dGrid_span_size.argtypes = [ctypes.POINTER(dSpan)] + self.py_neon.lib.dGrid_span_size.restype = ctypes.c_int + + + self.py_neon.lib.dGrid_get_properties.argtypes = [self.py_neon.handle_type, + 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] + 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') + + if self.handle.value != 0: # Ensure the grid handle is uninitialized + 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), ctypes.byref(self.dim)) + if res != 0: + raise Exception('DGrid: Failed to initialize grid') + print(f"Grid 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 new_field(self) -> dField: + field = dField(self.py_neon, self.handle) + return field + + def get_span(self, + execution: Execution, + c: ctypes.c_int, + data_view: DataView) -> dSpan: + if self.handle == 0: + raise Exception('DGrid: Invalid handle') + + span = dSpan() + res = self.py_neon.lib.dGrid_get_span(self.handle, span, execution, c, data_view) + if res != 0: + raise Exception('Failed to get span') + + cpp_size = self.py_neon.lib.dGrid_span_size(span) + ctypes_size = ctypes.sizeof(span) + + if cpp_size != ctypes_size: + raise Exception(f'Failed to get span: cpp_size {cpp_size} != ctypes_size {ctypes_size}') + + return span + + def getProperties(self, idx: Index_3d): + return DataView.from_int(self.py_neon.lib.dGrid_get_properties(self.handle, idx)) + + def isInsideDomain(self, idx: Index_3d): + return self.py_neon.lib.dGrid_is_inside_domain(self.handle, idx) diff --git a/py_neon/dense/dPartition.py b/py_neon/dense/dPartition.py new file mode 100644 index 00000000..0989d44f --- /dev/null +++ b/py_neon/dense/dPartition.py @@ -0,0 +1,49 @@ +import copy +import ctypes +from enum import Enum + +import py_neon + + +class dPartitionInt(ctypes.Structure): + _fields_ = [ + ("mDataView", py_neon.DataView), + ("mDim", py_neon.Index_3d), + ("mMem", ctypes.POINTER(ctypes.c_int)), + ("mZHaloRadius", ctypes.c_int), + ("mZBoundaryRadius", ctypes.c_int), + ("mPitch1", ctypes.c_uint64), + ("mPitch2", ctypes.c_uint64), + ("mPitch3", ctypes.c_uint64), + ("mPitch4", ctypes.c_uint64), + ("mPrtID", ctypes.c_int), + ("mOrigin", py_neon.Index_3d), + ("mCardinality", ctypes.c_int), + ("mFullGridSize", py_neon.Index_3d), + ("mPeriodicZ", ctypes.c_bool), + ("mStencil", ctypes.POINTER(ctypes.c_int)), + ] + + def __str__(self): + def get_offset(field_name): + return ctypes.offsetof(dPartitionInt, field_name) + + 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 + + diff --git a/py_neon/dense/dSpan.py b/py_neon/dense/dSpan.py new file mode 100644 index 00000000..89353e5b --- /dev/null +++ b/py_neon/dense/dSpan.py @@ -0,0 +1,62 @@ +import copy +import ctypes +from enum import Enum + +from py_neon import DataView +from py_neon import Index_3d +from py_neon import Py_neon + + +class dSpan(ctypes.Structure): + 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): + + # grid_new + self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.restype = ctypes.POINTER(ctypes.c_size_t) + + def get_member_field_offsets(self): + length = ctypes.c_size_t() + offsets = self.py_neon.lib.dGrid_dSpan_get_member_field_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.offsetof(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')})" + 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')] + + @staticmethod + def fields_(): + return dSpan._fields_ + diff --git a/py_neon/dense/mField.py b/py_neon/dense/mField.py new file mode 100644 index 00000000..b9734158 --- /dev/null +++ b/py_neon/dense/mField.py @@ -0,0 +1,143 @@ +import copy +import ctypes +from enum import Enum +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 +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 mField(object): + def __init__(self, + py_neon: NePy_neon, + grid_handle: ctypes.c_uint64 + ): + + if grid_handle == 0: + raise Exception('mField: Invalid handle') + + self.py_neon = py_neon + 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() + + def __del__(self): + self.help_delete() + + def help_load_api(self): + # Importing new functions + ## new_field + self.py_neon.lib.mGrid_mField_new.argtypes = [self.handle_type, + self.handle_type] + self.py_neon.lib.mGrid_mField_new.restype = ctypes.c_int + + ## delete_field + self.py_neon.lib.mGrid_mField_delete.argtypes = [self.handle_type] + self.py_neon.lib.mGrid_mField_delete.restype = ctypes.c_int + + ## get_partition + self.py_neon.lib.mGrid_mField_get_partition.argtypes = [self.handle_type, + ctypes.POINTER(NePartitionInt), # the span object + ctypes.c_int, + NeExecution, # the execution type + ctypes.c_int, # the device id + NeDataView, # the data view + ] + 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.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.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.c_int, + ctypes.c_int] + self.py_neon.lib.mGrid_mField_write.restype = ctypes.c_int + + # field update host data + self.py_neon.lib.mGrid_mField_update_host_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.mGrid_mField_update_host_data.restype = ctypes.c_int + + # field update device data + self.py_neon.lib.mGrid_mField_update_device_data.argtypes = [self.handle_type, + ctypes.c_int] + self.py_neon.lib.mGrid_mField_update_device_data.restype = ctypes.c_int + + + + def help_new(self): + if self.handle == 0: + raise Exception('mGrid: Invalid handle') + + res = self.py_neon.lib.mGrid_mField_new(self.handle, self.grid_handle) + 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) + 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 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) + + 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) + + def updateHostData(self, streamSetId: ctypes.c_int): + return self.py_neon.lib.mGrid_mField_update_host_data(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 diff --git a/py_neon/dense/mGrid.py b/py_neon/dense/mGrid.py new file mode 100644 index 00000000..1809daae --- /dev/null +++ b/py_neon/dense/mGrid.py @@ -0,0 +1,121 @@ +import copy +import ctypes +from enum import Enum + +import py_neon +from .mField import mField +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 py_neon.index_3d import Index_3d + +class mGrid(object): + + + 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.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() + + def __del__(self): + if self.handle == 0: + return + self.help_grid_delete() + + 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, + ctypes.c_int] + self.py_neon.lib.mGrid_new.restype = ctypes.c_int + + # grid_delete + 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_span.argtypes = [self.py_neon.handle_type, + ctypes.c_int, # the grid index + ctypes.POINTER(dSpan), # 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.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] + 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] + 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) + + res = self.py_neon.lib.mGrid_new(self.handle, self.backend.handle, self.dim, self.depth) + if res != 0: + raise Exception('mGrid: Failed to initialize grid') + + def help_grid_delete(self): + if self.handle == 0: + return + res = self.py_neon.lib.mGrid_delete(self.handle) + if res != 0: + raise Exception('Failed to delete grid') + + def new_field(self) -> mField: + field = mField(self.py_neon, self.handle) + return field + + def get_span(self, + grid_level: ctypes.c_int, + execution: Execution, + c: ctypes.c_int, + data_view: DataView) -> dSpan: + 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) + if res != 0: + raise Exception('Failed to get span') + + cpp_size = self.py_neon.lib.mGrid_span_size(span) + ctypes_size = ctypes.sizeof(span) + + if cpp_size != ctypes_size: + raise Exception(f'Failed to get span: cpp_size {cpp_size} != ctypes_size {ctypes_size}') + + 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 isInsideDomain(self, grid_level: ctypes.c_int, idx: Index_3d): + return self.py_neon.lib.mGrid_is_inside_domain(self.handle, grid_level, idx) diff --git a/py_neon/dense/mPartition.py b/py_neon/dense/mPartition.py new file mode 100644 index 00000000..009752de --- /dev/null +++ b/py_neon/dense/mPartition.py @@ -0,0 +1,37 @@ +import copy +import ctypes +from enum import Enum + +import py_neon + + +class mPartitionInt(ctypes.Structure): + _fields_ = [ + ("mLevel", ctypes.c_int), + ("mMemParent", ctypes.POINTER(ctypes.c_int)), + ("mMemChild", ctypes.POINTER(ctypes.c_int)), + ("mParentBlockID", ctypes.POINTER(ctypes.c_uint32)), + ("mMaskLowerLevel", ctypes.POINTER(ctypes.c_uint32)), + ("mMaskUpperLevel", ctypes.POINTER(ctypes.c_uint32)), + ("mChildBlockID", ctypes.POINTER(ctypes.c_uint32)), + ("mParentNeighbourBlocks", ctypes.POINTER(ctypes.c_uint32)), + ("mRefFactors", ctypes.POINTER(ctypes.c_int)), + ("mSpacing", ctypes.POINTER(ctypes.c_int)) + ] + + def __str__(self): + def get_offset(field_name): + return ctypes.offsetof(mPartitionInt, field_name) + + 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 diff --git a/py_neon/dense/partition.py b/py_neon/dense/partition.py deleted file mode 100644 index da604dce..00000000 --- a/py_neon/dense/partition.py +++ /dev/null @@ -1,46 +0,0 @@ -import copy -import ctypes -from enum import Enum - -import py_neon - - -class PartitionInt(ctypes.Structure): - _fields_ = [ - ("mDataView", py_neon.DataView), - ("mDim", py_neon.Index_3d), - ("mMem", ctypes.POINTER(ctypes.c_int)), - ("mZHaloRadius", ctypes.c_int), - ("mZBoundaryRadius", ctypes.c_int), - ("mPitch1", ctypes.c_uint64), - ("mPitch2", ctypes.c_uint64), - ("mPitch3", ctypes.c_uint64), - ("mPitch4", ctypes.c_uint64), - ("mPrtID", ctypes.c_int), - ("mOrigin", py_neon.Index_3d), - ("mCardinality", ctypes.c_int), - ("mFullGridSize", py_neon.Index_3d), - ("mPeriodicZ", ctypes.c_bool), - ("mStencil", ctypes.POINTER(ctypes.c_int)), - ] - - def __str__(self): - str = "" % (ctypes.addressof(self)) - str += f"\n\tdataView: {self.mDataView}" - str += f"\n\tmMem: {self.mMem}" - str += f"\n\tmDim: {self.mDim}" - str += f"\n\tmZHaloRadius: {self.mZHaloRadius}" - str += f"\n\tmZBoundaryRadius: {self.mZBoundaryRadius}" - str += f"\n\tmPitch1: {self.mPitch1}" - str += f"\n\tmPitch2: {self.mPitch2}" - str += f"\n\tmPitch3: {self.mPitch3}" - str += f"\n\tmPitch4: {self.mPitch4}" - str += f"\n\tmPrtID: {self.mPrtID}" - str += f"\n\tmOrigin: {self.mOrigin}" - str += f"\n\tmCardinality: {self.mCardinality}" - str += f"\n\tmFullGridSize: {self.mFullGridSize}" - str += f"\n\tmPeriodicZ: {self.mPeriodicZ}" - str += f"\n\tmStencil: {self.mStencil}" - return str - - diff --git a/py_neon/dense/span.py b/py_neon/dense/span.py deleted file mode 100644 index ea1a43cc..00000000 --- a/py_neon/dense/span.py +++ /dev/null @@ -1,33 +0,0 @@ -import copy -import ctypes -from enum import Enum - -from py_neon import DataView -from py_neon import Index_3d - - -class Span(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 __str__(self): - str = "" % (ctypes.addressof(self)) - str += f"\n\tdataView: {self.dataView}" - str += f"\n\tz_ghost_radius: {self.z_ghost_radius}" - str += f"\n\tz_boundary_radius: {self.z_boundary_radius}" - str += f"\n\tmax_z_in_domain: {self.max_z_in_domain}" - str += f"\n\tspan_dim: {self.span_dim}" - return str - - def get_span_dim(self): - return copy.deepcopy(self.span_dim) - - @staticmethod - def fields_(): - return Span._fields_ - diff --git a/py_neon/index_1d.py b/py_neon/index_1d.py new file mode 100644 index 00000000..289ae0cc --- /dev/null +++ b/py_neon/index_1d.py @@ -0,0 +1,17 @@ +import copy +import ctypes +from enum import Enum + +import py_ne + +class Index_1d(ctypes.Structure): + _fields_ = [("x", ctypes.c_int32)] + + def __init__(self, x: int): + self.x = x + + def __str__(self): + str = "" % (ctypes.addressof(self)) + str += f"\n\tx: {self.x}" + return str + diff --git a/py_neon/index_3d.py b/py_neon/index_3d.py index 5a15955a..8288677d 100644 --- a/py_neon/index_3d.py +++ b/py_neon/index_3d.py @@ -5,7 +5,7 @@ import py_ne class Index_3d(ctypes.Structure): - _fields_ = [("x", ctypes.c_int), ("y", ctypes.c_int), ("z", ctypes.c_int)] + _fields_ = [("x", ctypes.c_int32), ("y", ctypes.c_int32), ("z", ctypes.c_int32)] def __init__(self, x: int, y: int, z: int): self.x = x From 2d9adf167bd6a2c9c5fa8fedfb67524a27c0170e Mon Sep 17 00:00:00 2001 From: mattloulou Date: Wed, 26 Jun 2024 07:25:42 -0700 Subject: [PATCH 04/10] fixed test 2 --- .../include/Neon/domain/details/dGrid/dSpan.h | 2 +- .../Neon/domain/details/dGrid/dSpan_imp.h | 10 ++++++++-- libNeonPy/include/Neon/py/dGrid.h | 8 +++++--- libNeonPy/src/Neon/py/bGrid.cpp | 2 +- libNeonPy/src/Neon/py/dGrid.cpp | 20 +++++++++---------- libNeonPy/src/Neon/py/mGrid.cpp | 2 +- py_neon/dense/dGrid.py | 6 ++++-- py_neon/dense/dSpan.py | 16 +++++++-------- 8 files changed, 38 insertions(+), 28 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h index d20b897b..d9234f96 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan.h @@ -46,7 +46,7 @@ class dSpan #if !defined(NEON_WARP_COMPILATION) // Function to get offsets of member variables - static std::vector getOffsets(); + static void getOffsets(size_t* offsets, size_t* length); #endif private: diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h index 2ba21146..6d78c04d 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dSpan_imp.h @@ -73,14 +73,20 @@ NEON_CUDA_HOST_DEVICE inline auto dSpan::helpGetDim() } #if !defined(NEON_WARP_COMPILATION) -inline std::vector dSpan::getOffsets() { - return { +inline void dSpan::getOffsets(size_t* offsets, size_t* length) { + std::cout << "dGrid_dSpan 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(dSpan, mDataView), offsetof(dSpan, mZghostRadius), offsetof(dSpan, mZboundaryRadius), offsetof(dSpan, mMaxZInDomain), offsetof(dSpan, mSpanDim) }; + + *length = cpp_offsets.size(); + for (size_t i = 0; i < cpp_offsets.size(); ++i) { + offsets[i] = cpp_offsets[i]; + } } #endif diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index 8f3a178f..f2a13c2c 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -9,7 +9,9 @@ extern "C" auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d& dim) + int32_t x, + int32_t y, + int32_t z) -> int; // extern "C" auto dGrid_new( // uint64_t& handle, @@ -96,5 +98,5 @@ extern "C" auto dGrid_dField_update_device_data( int streamSetId) -> int; -extern "C" auto bGrid_bSpan_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; \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index b0d91658..04143e82 100644 --- a/libNeonPy/src/Neon/py/bGrid.cpp +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -74,7 +74,7 @@ auto bGrid_get_span( device, Neon::DataViewUtil::fromInt(data_view)); (*spanRes) = gridSpan; - std::cout << "field_new - END" << &gridSpan << std::endl; + std::cout << "bGrid_get_span - END" << &gridSpan << std::endl; return 0; } diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index c20e29d9..90254506 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -6,7 +6,9 @@ auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d& dim) + int32_t x, + int32_t y, + int32_t z) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -21,9 +23,9 @@ auto dGrid_new( std::cerr << "Invalid backend pointer" << std::endl; return -1; } - std::cerr << dim.x << " " << dim.y << " " << dim.z << std::endl; + std::cerr << x << " " << y << " " << z << std::endl; - // Neon::int32_3d dim{x,y,z}; + Neon::int32_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); auto gridPtr = new (std::nothrow) Grid(g); @@ -80,7 +82,6 @@ auto dGrid_delete( { std::cout << "dGrid_delete - gridHandle " << handle << std::endl << std::flush; std::cout << "dGrid_delete - BEGIN" << std::endl; - std::cout << "test" << std::endl; using Grid = Neon::dGrid; Grid* gridPtr = reinterpret_cast(handle); @@ -358,10 +359,9 @@ auto dGrid_dField_update_device_data( return 0; } -extern "C" auto dGrid_dSpan_get_member_field_offsets(std::size_t* length) - -> std::size_t* +extern "C" auto dGrid_dSpan_get_member_field_offsets(size_t* offsets, size_t* length) + -> void { - std::vector offsets = Neon::domain::details::dGrid::dSpan::getOffsets(); - *length = offsets.size(); - return offsets.data(); -} \ No newline at end of file + Neon::domain::details::dGrid::dSpan::getOffsets(offsets, length); +} + diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp index 51002dce..9983031d 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -82,7 +82,7 @@ auto mGrid_get_span( device, Neon::DataViewUtil::fromInt(data_view)); (*spanRes) = gridSpan; - std::cout << "field_new - END" << &gridSpan << std::endl; + std::cout << "mGrid_get_span - END" << &gridSpan << std::endl; return 0; } diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index 8132e2c8..5f2b8ca1 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -41,7 +41,9 @@ def help_load_api(self): # py_neon.Index_3d] self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type, self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.c_int32, + ctypes.c_int32, + ctypes.c_int32] self.py_neon.lib.dGrid_new.restype = ctypes.c_int # grid_delete @@ -80,7 +82,7 @@ def help_grid_new(self): 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), ctypes.byref(self.dim)) + 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) if res != 0: raise Exception('DGrid: Failed to initialize grid') print(f"Grid initialized with handle {self.handle.value}") diff --git a/py_neon/dense/dSpan.py b/py_neon/dense/dSpan.py index 89353e5b..5a9772e9 100644 --- a/py_neon/dense/dSpan.py +++ b/py_neon/dense/dSpan.py @@ -17,14 +17,13 @@ def __init__(self): self.help_load_api() def help_load_api(self): - - # grid_new - self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t)] - self.py_neon.lib.dGrid_dSpan_get_member_field_offsets.restype = ctypes.POINTER(ctypes.c_size_t) + 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): length = ctypes.c_size_t() - offsets = self.py_neon.lib.dGrid_dSpan_get_member_field_offsets(ctypes.byref(length)) + offsets = (ctypes.c_size_t * 5)() # Assuming there are 5 offsets based on your C++ code + self.py_neon.lib.dGrid_dSpan_get_member_field_offsets(offsets, ctypes.byref(length)) return [offsets[i] for i in range(length.value)] @@ -52,9 +51,10 @@ 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')] + # 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 def fields_(): From e6bdf039608c50760e3683da147b5505fde6bae4 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Wed, 26 Jun 2024 12:10:09 -0700 Subject: [PATCH 05/10] reverted dGrid back to using Neon::int32_3d instead of 3 integers --- libNeonPy/include/Neon/py/dGrid.h | 4 +--- libNeonPy/src/Neon/py/dGrid.cpp | 8 +++----- py_neon/dense/dGrid.py | 7 +++---- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index f2a13c2c..28af7f06 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -9,9 +9,7 @@ extern "C" auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - int32_t x, - int32_t y, - int32_t z) + const Neon::int32_3d& dim) -> int; // extern "C" auto dGrid_new( // uint64_t& handle, diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index 90254506..4422cedf 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -6,9 +6,7 @@ auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - int32_t x, - int32_t y, - int32_t z) + const Neon::int32_3d& dim) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -23,9 +21,9 @@ auto dGrid_new( std::cerr << "Invalid backend pointer" << std::endl; return -1; } - std::cerr << x << " " << y << " " << z << std::endl; + std::cerr << dim.x << " " << dim.y << " " << dim.z << std::endl; - Neon::int32_3d dim{x,y,z}; + // Neon::int32_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); auto gridPtr = new (std::nothrow) Grid(g); diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index 5f2b8ca1..20e5f4c2 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -41,9 +41,7 @@ def help_load_api(self): # py_neon.Index_3d] self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type, self.py_neon.handle_type, - ctypes.c_int32, - ctypes.c_int32, - ctypes.c_int32] + py_neon.Index_3d] self.py_neon.lib.dGrid_new.restype = ctypes.c_int # grid_delete @@ -82,7 +80,8 @@ def help_grid_new(self): 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.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) if res != 0: raise Exception('DGrid: Failed to initialize grid') print(f"Grid initialized with handle {self.handle.value}") From b272bbbef814c4d20b212581a5233c944dcb0f5c Mon Sep 17 00:00:00 2001 From: mattloulou Date: Thu, 27 Jun 2024 08:27:43 -0700 Subject: [PATCH 06/10] used max's fix for py_neon.Index_3d --- libNeonPy/include/Neon/py/dGrid.h | 2 +- libNeonPy/src/Neon/py/dGrid.cpp | 6 +++--- py_neon/dense/dGrid.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index 28af7f06..201a24ae 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -9,7 +9,7 @@ extern "C" auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d& dim) + const Neon::int32_3d* dim) -> int; // extern "C" auto dGrid_new( // uint64_t& handle, diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index 4422cedf..3d67bc49 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -6,7 +6,7 @@ auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d& dim) + const Neon::int32_3d* dim) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -21,11 +21,11 @@ auto dGrid_new( std::cerr << "Invalid backend pointer" << std::endl; return -1; } - std::cerr << dim.x << " " << dim.y << " " << dim.z << std::endl; + std::cerr << dim->x << " " << dim->y << " " << dim->z << std::endl; // Neon::int32_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 true; }, d3q19); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index 20e5f4c2..820cda1f 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -41,7 +41,7 @@ def help_load_api(self): # py_neon.Index_3d] self.py_neon.lib.dGrid_new.argtypes = [self.py_neon.handle_type, self.py_neon.handle_type, - py_neon.Index_3d] + ctypes.POINTER(py_neon.Index_3d)] self.py_neon.lib.dGrid_new.restype = ctypes.c_int # grid_delete From c8a4aa975e06d88dc61d76ca43195a94424498e5 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Thu, 4 Jul 2024 13:21:40 -0700 Subject: [PATCH 07/10] mostly finished implementing and debugging dense tests --- .../Neon/domain/details/dGrid/dPartition.h | 28 +++++ .../src/domain/details/dGrid/dGrid.cpp | 1 - libNeonPy/include/Neon/py/dGrid.h | 32 +++--- libNeonPy/src/Neon/py/bGrid.cpp | 1 + libNeonPy/src/Neon/py/dGrid.cpp | 104 ++++++++++-------- libNeonPy/src/Neon/py/mGrid.cpp | 1 + py_neon/dataview.py | 5 + py_neon/dense/dField.py | 40 ++++--- py_neon/dense/dGrid.py | 30 +++-- py_neon/dense/dPartition.py | 26 +++++ py_neon/dense/dSpan.py | 22 ++-- py_neon/index_3d.py | 5 + 12 files changed, 198 insertions(+), 97 deletions(-) diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h b/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h index b324cddb..d855dc2d 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/src/domain/details/dGrid/dGrid.cpp b/libNeonDomain/src/domain/details/dGrid/dGrid.cpp index ec8b24d8..78a20ce4 100644 --- a/libNeonDomain/src/domain/details/dGrid/dGrid.cpp +++ b/libNeonDomain/src/domain/details/dGrid/dGrid.cpp @@ -32,7 +32,6 @@ auto dGrid::getSpan(Neon::Execution execution, return mData->spanTable.getSpan(execution, setIdx, dataView); } - auto dGrid::helpGetPartitionDim() const -> const Neon::set::DataSet { diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index 201a24ae..ef98711d 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -11,11 +11,7 @@ extern "C" auto dGrid_new( uint64_t& backendPtr, const Neon::int32_3d* dim) -> 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::int32_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,27 @@ 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, + Neon::DataView* dv) -> 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; @@ -97,4 +100,7 @@ extern "C" auto dGrid_dField_update_device_data( -> int; extern "C" auto bGrid_bSpan_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; \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index 04143e82..af41c822 100644 --- a/libNeonPy/src/Neon/py/bGrid.cpp +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -165,6 +165,7 @@ auto bGrid_bField_delete( delete fieldPtr; AllocationCounter::Deallocation(); } + handle = 0; std::cout << "bGrid_bField_delete - END" << std::endl; return 0; diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index 3d67bc49..8eac19d1 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -39,40 +39,7 @@ 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 +60,36 @@ auto dGrid_delete( return 0; } +extern "C" auto dGrid_get_dimensions( + uint64_t& gridHandle, + Neon::int32_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); + + std::cerr << dim->x << " " << dim->y << " " << dim->z << std::endl; + + 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 +123,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 +137,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 +209,7 @@ auto dGrid_dField_delete( delete fieldPtr; AllocationCounter::Deallocation(); } + handle = 0; std::cout << "dGrid_dField_delete - END" << std::endl; return 0; @@ -232,29 +231,33 @@ 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, + Neon::DataView* dv) -> 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()); + if (gridPtr == nullptr) { + return -1; + } + *dv = gridPtr->getProperties(*idx).getDataView(); std::cout << "dGrid_get_properties end" << std::endl; - return returnValue; + return 0; } 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 +267,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 +282,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 +291,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 +308,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 +366,10 @@ 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..31003cd0 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -180,6 +180,7 @@ auto mGrid_mField_delete( delete fieldPtr; AllocationCounter::Allocation(); } + handle = 0; std::cout << "mGrid_mField_delete - END" << std::endl; return 0; diff --git a/py_neon/dataview.py b/py_neon/dataview.py index 895177fd..8fe2b440 100644 --- a/py_neon/dataview.py +++ b/py_neon/dataview.py @@ -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/dField.py b/py_neon/dense/dField.py index 2911323d..f2b6ed6f 100644 --- a/py_neon/dense/dField.py +++ b/py_neon/dense/dField.py @@ -2,6 +2,7 @@ import ctypes from enum import Enum import py_neon +from py_neon import Py_neon from .dPartition import dPartitionInt as NeDPartition from py_neon.execution import Execution as NeExecution from py_neon.dataview import DataView as NeDataView @@ -11,17 +12,21 @@ 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.cardinality = cardinality self.help_load_api() self.help_new() @@ -32,7 +37,8 @@ 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 @@ -54,13 +60,13 @@ def help_load_api(self): # 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 @@ -81,14 +87,14 @@ def help_new(self): if self.handle == 0: 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') 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') @@ -120,15 +126,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 820cda1f..c61ba017 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -16,8 +16,7 @@ class dGrid(object): - - def __init__(self, backend = None, dim = None): + def __init__(self, backend = None, dim = None, sparsity_pattern = None): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend if backend is not None else Backend() # @TODOMATT if the input is not the correct type, throw an error self.dim = dim if dim is not None else Index_3d(10, 10, 10) # @TODOMATT if the input is not the correct type, throw an error @@ -48,6 +47,10 @@ def help_load_api(self): 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 @@ -61,11 +64,12 @@ 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), + ctypes.POINTER(DataView)] 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 @@ -89,9 +93,20 @@ def help_grid_new(self): 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, @@ -115,7 +130,8 @@ 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)) + dv = DataView(0) + return DataView(self.py_neon.lib.dGrid_get_properties(ctypes.byref(self.handle), idx, dv)) def isInsideDomain(self, idx: Index_3d): return self.py_neon.lib.dGrid_is_inside_domain(self.handle, idx) diff --git a/py_neon/dense/dPartition.py b/py_neon/dense/dPartition.py index 0989d44f..b6a938b8 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,6 +25,24 @@ class dPartitionInt(ctypes.Structure): ("mStencil", ctypes.POINTER(ctypes.c_int)), ] + 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.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): def get_offset(field_name): return ctypes.offsetof(dPartitionInt, field_name) @@ -45,5 +64,12 @@ def get_offset(field_name): str += f"\n\tmPeriodicZ: {self.mPeriodicZ} (offset: {get_offset('mPeriodicZ')})" str += f"\n\tmStencil: {self.mStencil} (offset: {get_offset('mStencil')})" 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 5a9772e9..ae75d111 100644 --- a/py_neon/dense/dSpan.py +++ b/py_neon/dense/dSpan.py @@ -8,6 +8,14 @@ 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() @@ -20,20 +28,13 @@ 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): @@ -51,9 +52,6 @@ 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) From 0e38e43a1b6b415ca5903c287a125b22ce612b58 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Tue, 9 Jul 2024 07:50:05 -0700 Subject: [PATCH 08/10] continued fixing issues with dense/block/multires grids --- .../Neon/domain/details/bGrid/bPartition.h | 20 ++++ .../include/Neon/domain/details/bGrid/bSpan.h | 9 +- .../Neon/domain/details/bGrid/bSpan_imp.h | 50 +++----- .../Neon/domain/details/dGrid/dPartition.h | 2 +- libNeonPy/include/Neon/py/bGrid.h | 21 ++-- libNeonPy/include/Neon/py/backend.h | 28 +---- libNeonPy/include/Neon/py/dGrid.h | 5 +- libNeonPy/include/Neon/py/mGrid.h | 12 +- libNeonPy/src/Neon/py/bGrid.cpp | 44 ++++--- libNeonPy/src/Neon/py/backend.cpp | 61 +++++----- libNeonPy/src/Neon/py/dGrid.cpp | 7 +- libNeonPy/src/Neon/py/mGrid.cpp | 29 +++-- libNeonSet/src/set/DevSet.cpp | 5 + py_neon/__init__.py | 3 + py_neon/{dense => }/allocationCounter.py | 4 +- py_neon/backend.py | 112 ++++++++++++++++++ py_neon/block/__init__.py | 8 ++ py_neon/{dense => block}/bField.py | 12 +- py_neon/{dense => block}/bGrid.py | 37 +++--- py_neon/block/bPartition.py | 52 ++++++++ py_neon/{dense => block}/bSpan.py | 39 +++--- py_neon/dense/__init__.py | 13 +- py_neon/dense/bPartition.py | 34 ------ py_neon/dense/backend.py | 98 --------------- py_neon/dense/dField.py | 4 +- py_neon/dense/dGrid.py | 32 +++-- py_neon/dense/dPartition.py | 43 ++++--- py_neon/dense/dSpan.py | 19 ++- py_neon/dense/mPartition.py | 37 ------ py_neon/multires/__init__.py | 8 ++ py_neon/{dense => multires}/mField.py | 12 +- py_neon/{dense => multires}/mGrid.py | 37 +++--- py_neon/multires/mPartition.py | 58 +++++++++ py_neon/py_ne.py | 12 +- py_neon/test/__init__.py | 51 ++++++++ 35 files changed, 565 insertions(+), 453 deletions(-) rename py_neon/{dense => }/allocationCounter.py (91%) create mode 100644 py_neon/backend.py create mode 100644 py_neon/block/__init__.py rename py_neon/{dense => block}/bField.py (94%) rename py_neon/{dense => block}/bGrid.py (76%) create mode 100644 py_neon/block/bPartition.py rename py_neon/{dense => block}/bSpan.py (62%) delete mode 100644 py_neon/dense/bPartition.py delete mode 100644 py_neon/dense/backend.py delete mode 100644 py_neon/dense/mPartition.py create mode 100644 py_neon/multires/__init__.py rename py_neon/{dense => multires}/mField.py (94%) rename py_neon/{dense => multires}/mGrid.py (77%) create mode 100644 py_neon/multires/mPartition.py create mode 100644 py_neon/test/__init__.py 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..0281e1a9 100644 --- a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h +++ b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan.h @@ -44,14 +44,15 @@ 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; Neon::DataView mDataView; - - // Function to get offsets of member variables - static std::vector getOffsets(); }; } // namespace Neon::domain::details::bGrid diff --git a/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h b/libNeonDomain/include/Neon/domain/details/bGrid/bSpan_imp.h index 61b9f8c9..1e3c3820 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 \ No newline at end of file diff --git a/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h b/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h index d855dc2d..2ed747f5 100644 --- a/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h +++ b/libNeonDomain/include/Neon/domain/details/dGrid/dPartition.h @@ -487,7 +487,7 @@ class dPartition return s.str(); } - #if !defined(NEON_WARP_COMPILATION) +#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 = { diff --git a/libNeonPy/include/Neon/py/bGrid.h b/libNeonPy/include/Neon/py/bGrid.h index 9e3944de..4a6b11bb 100644 --- a/libNeonPy/include/Neon/py/bGrid.h +++ b/libNeonPy/include/Neon/py/bGrid.h @@ -8,8 +8,8 @@ */ /* 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::index_3d* dim) -> int; /** @@ -60,23 +60,23 @@ 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 Neon::index_3d* idx, const int& cardinality) -> int; extern "C" auto bGrid_bField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, + const Neon::index_3d* idx, const int& cardinality, int newValue) -> int; @@ -91,5 +91,10 @@ 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; diff --git a/libNeonPy/include/Neon/py/backend.h b/libNeonPy/include/Neon/py/backend.h index 1ee3afbd..8630b953 100644 --- a/libNeonPy/include/Neon/py/backend.h +++ b/libNeonPy/include/Neon/py/backend.h @@ -2,36 +2,17 @@ #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_new3( +extern "C" auto dBackend_new( uint64_t& handle, - const int* devIds /*! Vectors of device ids. There are CUDA device ids */, - int runtime /*! Type of runtime to use */) + 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. */ @@ -42,3 +23,4 @@ extern "C" auto dBackend_delete( 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 ef98711d..09a0c58f 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -99,8 +99,9 @@ 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) +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; \ No newline at end of file + -> void; + diff --git a/libNeonPy/include/Neon/py/mGrid.h b/libNeonPy/include/Neon/py/mGrid.h index 4af9a507..02005f75 100644 --- a/libNeonPy/include/Neon/py/mGrid.h +++ b/libNeonPy/include/Neon/py/mGrid.h @@ -8,8 +8,8 @@ */ /* TODOMATT fix the constructor to have correct arguments */ extern "C" auto mGrid_new( uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim, + uint64_t& backendPtr, + const Neon::index_3d* dim, uint32_t& depth) -> int; @@ -64,26 +64,26 @@ 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) + 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) + 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 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 Neon::index_3d* idx, const int& cardinality, int newValue) -> int; diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index af41c822..168b329e 100644 --- a/libNeonPy/src/Neon/py/bGrid.cpp +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -6,7 +6,7 @@ auto bGrid_new( uint64_t& handle, uint64_t& backendPtr, - Neon::index_3d dim) + const Neon::index_3d* dim) -> int { std::cout << "bGrid_new - BEGIN" << std::endl; @@ -15,8 +15,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 true; }, d3q19); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); @@ -187,14 +194,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; @@ -202,14 +209,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; @@ -219,7 +226,7 @@ auto bGrid_is_inside_domain( auto bGrid_bField_read( uint64_t& fieldHandle, - const Neon::index_3d& idx, + const Neon::index_3d* idx, const int& cardinality) -> int { @@ -234,7 +241,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; @@ -243,7 +250,7 @@ auto bGrid_bField_read( auto bGrid_bField_write( uint64_t& fieldHandle, - const Neon::index_3d& idx, + const Neon::index_3d* idx, const int& cardinality, int newValue) -> int @@ -260,7 +267,7 @@ auto bGrid_bField_write( return -1; } - fieldPtr->getReference(idx, cardinality) = newValue; + fieldPtr->getReference(*idx, cardinality) = newValue; std::cout << "bGrid_bField_write end" << std::endl; return 0; @@ -312,10 +319,15 @@ 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 c3593400..406ce47f 100644 --- a/libNeonPy/src/Neon/py/backend.cpp +++ b/libNeonPy/src/Neon/py/backend.cpp @@ -1,6 +1,7 @@ #include "Neon/py/backend.h" #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; @@ -18,46 +19,19 @@ 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( +auto dBackend_new( uint64_t& handle, - int nGpus, - int runtime) + int runtime, + int numDevices, + const int* devIds) -> int { - std::cout << "second constructor" << std::endl; - AllocationCounter::Allocation(); + Neon::init(); backend_constructor_prologue(handle); - auto backendPtr = new (std::nothrow) Neon::Backend(nGpus, Neon::Runtime(runtime)); - - return backend_constructor_epilogue(handle, backendPtr); -} - -auto dBackend_new3( - uint64_t& handle, - const int* devIds, - int runtime) - -> int -{ - std::cout << "third constructor" << std::endl; - - backend_constructor_prologue(handle); + std::vector vec(devIds, devIds + numDevices); - auto backendPtr = new (std::nothrow) Neon::Backend(std::vector(*devIds), Neon::Runtime(runtime)); + auto backendPtr = new (std::nothrow) Neon::Backend(vec, Neon::Runtime(runtime)); AllocationCounter::Allocation(); return backend_constructor_epilogue(handle, backendPtr); @@ -88,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 8eac19d1..64cb77b7 100644 --- a/libNeonPy/src/Neon/py/dGrid.cpp +++ b/libNeonPy/src/Neon/py/dGrid.cpp @@ -6,7 +6,7 @@ auto dGrid_new( uint64_t& handle, uint64_t& backendPtr, - const Neon::int32_3d* dim) + const Neon::index_3d* dim) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -21,9 +21,8 @@ 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); auto gridPtr = new (std::nothrow) Grid(g); @@ -62,7 +61,7 @@ auto dGrid_delete( extern "C" auto dGrid_get_dimensions( uint64_t& gridHandle, - Neon::int32_3d* dim) + Neon::index_3d* dim) -> int { std::cout << "dGrid_get_dimension - BEGIN" << std::endl; diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp index 31003cd0..b7bf6a05 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -4,8 +4,8 @@ auto mGrid_new( uint64_t& handle, - Neon::Backend* backendPtr, - Neon::index_3d dim, + uint64_t& backendPtr, + const Neon::index_3d* dim, uint32_t& depth) -> int { @@ -15,9 +15,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 true; }}, d3q19, Grid::Descriptor(depth)); auto gridPtr = new (std::nothrow) Grid(g); AllocationCounter::Allocation(); @@ -203,7 +210,7 @@ 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) + const Neon::index_3d* idx) -> int { std::cout << "mGrid_get_properties begin" << std::endl; @@ -213,7 +220,7 @@ 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; @@ -222,7 +229,7 @@ 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 + const Neon::index_3d* idx ) -> bool { @@ -230,7 +237,7 @@ auto mGrid_is_inside_domain( using Grid = Neon::domain::mGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - bool returnValue = gridPtr->isInsideDomain(idx, grid_level); + bool returnValue = gridPtr->isInsideDomain(*idx, grid_level); std::cout << "mGrid_is_inside_domain end" << std::endl; @@ -241,7 +248,7 @@ auto mGrid_is_inside_domain( auto mGrid_mField_read( uint64_t& fieldHandle, uint64_t& field_level, - const Neon::index_3d& idx, + const Neon::index_3d* idx, const int& cardinality) -> int { @@ -256,7 +263,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; @@ -266,7 +273,7 @@ auto mGrid_mField_read( auto mGrid_mField_write( uint64_t& fieldHandle, uint64_t& field_level, - const Neon::index_3d& idx, + const Neon::index_3d* idx, const int& cardinality, int newValue) -> int @@ -283,7 +290,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; diff --git a/libNeonSet/src/set/DevSet.cpp b/libNeonSet/src/set/DevSet.cpp index ef1c037d..87b6a46b 100644 --- a/libNeonSet/src/set/DevSet.cpp +++ b/libNeonSet/src/set/DevSet.cpp @@ -70,6 +70,10 @@ auto DevSet::set(const Neon::DeviceType& devType, for (auto&& invalidID : invilidIdsVec) { exp << invalidID << " "; } + exp << "valid ids are:\n"; + for (auto&& invalidID : invilidIdsVec) { + exp << invalidID << " "; + } NEON_THROW(exp); } } @@ -168,6 +172,7 @@ auto DevSet::validateIds() if (m_devType == Neon::DeviceType::CUDA) { for (auto&& gpuId : this->m_devIds) { if (gpuId.idx() >= Neon::sys::globalSpace::gpuSysObj().numDevs()) { + std:: cout << "Neon::sys::globalSpace::gpuSysObj().numDevs() "<< Neon::sys::globalSpace::gpuSysObj().numDevs()< len(dev_idx_list): + dev_idx_list = list(range(n_dev)) + else: + n_dev = len(dev_idx_list) + + dev_idx_np = np.array(dev_idx_list, dtype=int) + dev_idx_ptr = dev_idx_np.ctypes.data_as(ctypes.POINTER(ctypes.c_int)) + + res = self.py_neon.lib.dBackend_new(ctypes.byref(self.handle), + runtime.value, + n_dev, + dev_idx_ptr) + if res != 0: + raise Exception('DBackend: Failed to initialize backend') + + def help_backend_delete(self): + if self.handle == 0: + return + 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') \ No newline at end of file diff --git a/py_neon/block/__init__.py b/py_neon/block/__init__.py new file mode 100644 index 00000000..5c893fce --- /dev/null +++ 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/dense/bField.py b/py_neon/block/bField.py similarity index 94% rename from py_neon/dense/bField.py rename to py_neon/block/bField.py index e7febaf1..27b1cd04 100644 --- a/py_neon/dense/bField.py +++ b/py_neon/block/bField.py @@ -24,13 +24,13 @@ def __init__(self, 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._help_load_api() + self._help_grid_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 +56,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 @@ -79,7 +79,7 @@ def help_load_api(self): - def help_new(self): + def _help_grid_new(self): if self.handle == 0: raise Exception('bGrid: Invalid handle') diff --git a/py_neon/dense/bGrid.py b/py_neon/block/bGrid.py similarity index 76% rename from py_neon/dense/bGrid.py rename to py_neon/block/bGrid.py index ca75034b..f5a7e779 100644 --- a/py_neon/dense/bGrid.py +++ b/py_neon/block/bGrid.py @@ -8,7 +8,7 @@ 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 class bGrid(object): @@ -23,20 +23,20 @@ def __init__(self, backend = None, dim = None): 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)] self.py_neon.lib.bGrid_new.restype = ctypes.c_int # grid_delete @@ -44,7 +44,7 @@ def help_load_api(self): self.py_neon.lib.bGrid_delete.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,15 +56,15 @@ 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): + def _help_grid_new(self): if self.handle == 0: raise Exception('bGrid: Invalid handle') @@ -73,15 +73,12 @@ def help_grid_new(self): if self.dim is None: self.dim = py_neon.Index_3d(10,10,10) - res = self.py_neon.lib.bGrid_new(self.handle, self.backend.handle, self.dim) + res = self.py_neon.lib.bGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim) if res != 0: raise Exception('bGrid: Failed to initialize grid') - 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: @@ -96,7 +93,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 +106,7 @@ 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.from_int(self.py_neon.lib.bGrid_get_properties(ctypes.byref(self.handle), idx)) def isInsideDomain(self, idx: Index_3d): - return self.py_neon.lib.bGrid_is_inside_domain(self.handle, idx) + return self.py_neon.lib.bGrid_is_inside_domain(ctypes.by_ref(self.handle), idx) diff --git a/py_neon/block/bPartition.py b/py_neon/block/bPartition.py new file mode 100644 index 00000000..933b03fe --- /dev/null +++ b/py_neon/block/bPartition.py @@ -0,0 +1,52 @@ +import copy +import ctypes +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)), + ("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)), + ("mDomainSize", py_neon.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() + + 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 * 8)() # Since there are 8 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: {bPartitionInt.setIdx.offset})" + 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\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\tmStencilNghIndex: {self.mStencilNghIndex} (offset: {bPartitionInt.mStencilNghIndex.offset})" + str_repr += f"\n\tmDomainSize: {self.mDomainSize} (offset: {bPartitionInt.mDomainSize.offset})" + return str_repr + + def get_offsets(self): + return [bPartitionInt.setIdx.offset, bPartitionInt.mCardinality.offset, bPartitionInt.mMem.offset, bPartitionInt.mBlockConnectivity.offset, + bPartitionInt.mMask.offset, bPartitionInt.mOrigin.offset, bPartitionInt.mStencilNghIndex.offset, bPartitionInt.mDomainSize.offset] diff --git a/py_neon/dense/bSpan.py b/py_neon/block/bSpan.py similarity index 62% rename from py_neon/dense/bSpan.py rename to py_neon/block/bSpan.py index 5b694b35..4207394d 100644 --- a/py_neon/dense/bSpan.py +++ b/py_neon/block/bSpan.py @@ -6,45 +6,40 @@ from py_neon import DataView class bSpan(ctypes.Structure): + _fields_ = [ + ("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/dense/__init__.py b/py_neon/dense/__init__.py index 196f94a5..fac3c129 100644 --- a/py_neon/dense/__init__.py +++ b/py_neon/dense/__init__.py @@ -1,14 +1,7 @@ -from .backend import Backend +from py_neon.backend import Backend from .dGrid import dGrid 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 .allocationCounter import allocationCounter -# from .partition import PartitionInt \ No newline at end of file + +from py_neon.allocationCounter import allocationCounter diff --git a/py_neon/dense/bPartition.py b/py_neon/dense/bPartition.py deleted file mode 100644 index 966db495..00000000 --- a/py_neon/dense/bPartition.py +++ /dev/null @@ -1,34 +0,0 @@ -import copy -import ctypes -from enum import Enum - -import py_neon - - -class bPartitionInt(ctypes.Structure): - _fields_ = [ - ("setIdx", ctypes.c_int), - ("mCardinality", ctypes.c_int), - ("mMem", 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)), - ("mDomainSize", py_neon.Index_3d) - ] - - def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(bPartitionInt, field_name) - - 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')})" - return str_repr - diff --git a/py_neon/dense/backend.py b/py_neon/dense/backend.py deleted file mode 100644 index ef60dd94..00000000 --- a/py_neon/dense/backend.py +++ /dev/null @@ -1,98 +0,0 @@ -import copy -import ctypes -from enum import Enum - -import py_neon -from py_neon.execution import Execution -from py_neon import Py_neon -from py_neon.dataview import DataView - - -class Backend(object): - - class Runtime(Enum): - none = 0 - system = 0 - stream = 1 - openmp = 2 - - def __init__(self, arg1 = None, arg2 = None): - self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) - 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_backend_new(arg1, arg2) - - def __del__(self): - if self.handle == 0: - return - self.help_backend_delete() - - def help_load_api(self): - - # backend_new - self.py_neon.lib.dBackend_new1.argtypes = [self.py_neon.handle_type] - self.py_neon.lib.dBackend_new1.restype = ctypes.c_int - - # backend_new - self.py_neon.lib.dBackend_new2.argtypes = [self.py_neon.handle_type, - ctypes.c_int, - ctypes.c_int] - self.py_neon.lib.dBackend_new2.restype = ctypes.c_int - - # backend_new - self.py_neon.lib.dBackend_new3.argtypes = [self.py_neon.handle_type, - ctypes.POINTER(ctypes.c_int), - ctypes.c_int] - self.py_neon.lib.dBackend_new3.restype = ctypes.c_int - - # backend_delete - self.py_neon.lib.dBackend_delete.argtypes = [self.py_neon.handle_type] - self.py_neon.lib.dBackend_delete.restype = ctypes.c_int - - # backend_get_string - 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 - - # TODOMATT get num devices - # TODOMATT get device type - - - - def help_backend_new(self, arg1=None, arg2=None): - if self.handle == 0: - raise Exception('DBackend: Invalid handle') - - if arg1 is None and arg2 is None: - # Call the empty constructor - res = self.py_neon.lib.dBackend_new1(ctypes.byref(self.handle)) - elif isinstance(arg1, int) and isinstance(arg2, Backend.Runtime): - # Call the constructor with nGpus and runtime - res = self.py_neon.lib.dBackend_new2(ctypes.byref(self.handle), arg1, arg2.value) - elif isinstance(arg1, list) and isinstance(arg2, Backend.Runtime): - # Call the constructor with devIds and runtime - from ctypes import c_int - - # Convert the list to a ctypes array - dev_ids = (c_int * len(arg1))(*arg1) - res = self.py_neon.lib.dBackend_new3(ctypes.byref(self.handle), dev_ids, arg2.value) - else: - raise Exception('DBackend: Invalid arguments provided') - - if res != 0: - raise Exception('DBackend: Failed to initialize backend') - - - def help_backend_delete(self): - if self.handle == 0: - return - res = self.py_neon.lib.dBackend_delete(self.handle) - if res != 0: - raise Exception('Failed to delete backend') - - def __str__(self): - return ctypes.cast(self.py_neon.lib.get_string(self.handle), ctypes.c_char_p).value.decode('utf-8') - \ No newline at end of file diff --git a/py_neon/dense/dField.py b/py_neon/dense/dField.py index f2b6ed6f..aece82c4 100644 --- a/py_neon/dense/dField.py +++ b/py_neon/dense/dField.py @@ -27,13 +27,13 @@ def __init__(self, self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.grid_handle = grid_handle self.cardinality = cardinality - 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, diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index c61ba017..d2386794 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 .backend import Backend +from ..backend import Backend from py_neon.index_3d import Index_3d import numpy as np @@ -16,23 +16,29 @@ class dGrid(object): - def __init__(self, backend = None, dim = None, sparsity_pattern = None): + def __init__(self, backend: Backend = None, dim: Index_3d = Index_3d(10,10,10), sparsity_pattern: np.ndarray = None): # @TODOMATT implement psarsity pattern self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) - self.backend = backend if backend is not None else Backend() # @TODOMATT if the input is not the correct type, throw an error - self.dim = dim if dim is not None else Index_3d(10, 10, 10) # @TODOMATT if the input is not the correct type, throw an error + self.backend = backend + self.dim = dim + self.sparsity_pattern = sparsity_pattern + if backend is None: + # rise exception + raise Exception('dGrid: backend pamrameter is missing') + 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.value != 0: - self.help_grid_delete() + if self.handle != 0: + 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, @@ -73,7 +79,7 @@ def help_load_api(self): self.py_neon.lib.dGrid_is_inside_domain.restype = ctypes.c_bool - def help_grid_new(self): + def _help_grid_new(self): if self.backend.handle.value == 0: # Check backend handle validity raise Exception('DGrid: Invalid backend handle') @@ -90,7 +96,7 @@ def help_grid_new(self): raise Exception('DGrid: Failed to initialize grid') print(f"Grid initialized with handle {self.handle.value}") - def help_grid_delete(self): + def _help_grid_delete(self): if self.py_neon.lib.dGrid_delete(ctypes.byref(self.handle)) != 0: raise Exception('Failed to delete grid') @@ -117,7 +123,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') @@ -134,4 +140,4 @@ def getProperties(self, idx: Index_3d): return DataView(self.py_neon.lib.dGrid_get_properties(ctypes.byref(self.handle), idx, dv)) 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 b6a938b8..69cfbc1e 100644 --- a/py_neon/dense/dPartition.py +++ b/py_neon/dense/dPartition.py @@ -31,9 +31,9 @@ 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): 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 @@ -43,30 +43,27 @@ def get_cpp_field_offsets(self): 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): - def get_offset(field_name): - return ctypes.offsetof(dPartitionInt, field_name) - - 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')})" + 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, + 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 ae75d111..cf224dee 100644 --- a/py_neon/dense/dSpan.py +++ b/py_neon/dense/dSpan.py @@ -22,9 +22,9 @@ 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): 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 @@ -37,15 +37,12 @@ def get_cpp_field_offsets(self): def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(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): diff --git a/py_neon/dense/mPartition.py b/py_neon/dense/mPartition.py deleted file mode 100644 index 009752de..00000000 --- a/py_neon/dense/mPartition.py +++ /dev/null @@ -1,37 +0,0 @@ -import copy -import ctypes -from enum import Enum - -import py_neon - - -class mPartitionInt(ctypes.Structure): - _fields_ = [ - ("mLevel", ctypes.c_int), - ("mMemParent", ctypes.POINTER(ctypes.c_int)), - ("mMemChild", ctypes.POINTER(ctypes.c_int)), - ("mParentBlockID", ctypes.POINTER(ctypes.c_uint32)), - ("mMaskLowerLevel", ctypes.POINTER(ctypes.c_uint32)), - ("mMaskUpperLevel", ctypes.POINTER(ctypes.c_uint32)), - ("mChildBlockID", ctypes.POINTER(ctypes.c_uint32)), - ("mParentNeighbourBlocks", ctypes.POINTER(ctypes.c_uint32)), - ("mRefFactors", ctypes.POINTER(ctypes.c_int)), - ("mSpacing", ctypes.POINTER(ctypes.c_int)) - ] - - def __str__(self): - def get_offset(field_name): - return ctypes.offsetof(mPartitionInt, field_name) - - 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 diff --git a/py_neon/multires/__init__.py b/py_neon/multires/__init__.py new file mode 100644 index 00000000..7831d4f4 --- /dev/null +++ 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/dense/mField.py b/py_neon/multires/mField.py similarity index 94% rename from py_neon/dense/mField.py rename to py_neon/multires/mField.py index b9734158..a628fcd0 100644 --- a/py_neon/dense/mField.py +++ b/py_neon/multires/mField.py @@ -24,13 +24,13 @@ def __init__(self, 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_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.mGrid_mField_new.argtypes = [self.handle_type, @@ -43,7 +43,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 +52,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 diff --git a/py_neon/dense/mGrid.py b/py_neon/multires/mGrid.py similarity index 77% rename from py_neon/dense/mGrid.py rename to py_neon/multires/mGrid.py index 1809daae..2226a8d9 100644 --- a/py_neon/dense/mGrid.py +++ b/py_neon/multires/mGrid.py @@ -7,8 +7,8 @@ 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 ..dense.dSpan import dSpan +from ..backend import Backend from py_neon.index_3d import Index_3d class mGrid(object): @@ -24,20 +24,20 @@ def __init__(self, backend = None, dim = None, depth = 0): 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.c_int] self.py_neon.lib.mGrid_new.restype = ctypes.c_int @@ -60,16 +60,16 @@ def help_load_api(self): 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): + def _help_grid_new(self): if self.handle == 0: raise Exception('mGrid: Invalid handle') @@ -78,15 +78,12 @@ def help_grid_new(self): if self.dim is None: self.dim = py_neon.Index_3d(10,10,10) - res = self.py_neon.lib.mGrid_new(self.handle, self.backend.handle, self.dim, self.depth) + res = self.py_neon.lib.mGrid_new(ctypes.byref(self.handle), ctypes.byref(self.backend.handle), self.dim, self.depth) if res != 0: raise Exception('mGrid: Failed to initialize grid') - 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: @@ -102,7 +99,7 @@ def get_span(self, raise Exception('mGrid: Invalid handle') span = dSpan() - res = self.py_neon.lib.mGrid_get_span(self.handle, grid_level, span, execution, c, data_view) + 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') @@ -115,7 +112,7 @@ 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)) + return DataView.from_int(self.py_neon.lib.mGrid_get_properties(ctypes.byref(self.handle), grid_inex, 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) + 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 new file mode 100644 index 00000000..4827da31 --- /dev/null +++ b/py_neon/multires/mPartition.py @@ -0,0 +1,58 @@ +import copy +import ctypes +from enum import Enum + +import py_neon +from py_neon import Py_neon + + +class mPartitionInt(ctypes.Structure): + _fields_ = [ + ("mLevel", ctypes.c_int), + ("mMemParent", ctypes.POINTER(ctypes.c_int)), + ("mMemChild", ctypes.POINTER(ctypes.c_int)), + ("mParentBlockID", ctypes.POINTER(ctypes.c_uint32)), + ("mMaskLowerLevel", ctypes.POINTER(ctypes.c_uint32)), + ("mMaskUpperLevel", ctypes.POINTER(ctypes.c_uint32)), + ("mChildBlockID", ctypes.POINTER(ctypes.c_uint32)), + ("mParentNeighbourBlocks", ctypes.POINTER(ctypes.c_uint32)), + ("mRefFactors", ctypes.POINTER(ctypes.c_int)), + ("mSpacing", ctypes.POINTER(ctypes.c_int)) + ] + + 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_dPartition_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] + self.py_neon.lib.mGrid_mField_dPartition_get_member_field_offsets.restype = None + + def get_cpp_field_offsets(self): + length = ctypes.c_size_t() + offsets = (ctypes.c_size_t * 10)() # Since there are 10 offsets + self.py_neon.lib.mGrid_mField_dPartition_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: {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.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] \ No newline at end of file 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') +# From 7f5571de742abd50668d05bc7c627eb19b199abd Mon Sep 17 00:00:00 2001 From: mattloulou Date: Wed, 10 Jul 2024 16:04:20 -0700 Subject: [PATCH 09/10] multires now passes tests --- .../Neon/domain/details/mGrid/mPartition.h | 36 +++++++- libNeonPy/include/Neon/py/bGrid.h | 14 ++- libNeonPy/include/Neon/py/dGrid.h | 8 +- libNeonPy/include/Neon/py/mGrid.h | 33 ++++--- libNeonPy/src/Neon/py/bGrid.cpp | 45 +++++++-- libNeonPy/src/Neon/py/dGrid.cpp | 18 ++-- libNeonPy/src/Neon/py/mGrid.cpp | 71 +++++++++++---- py_neon/block/bField.py | 35 ++++--- py_neon/block/bGrid.py | 28 +++++- py_neon/block/bPartition.py | 18 ++-- py_neon/block/bSpan.py | 1 + py_neon/dataview.py | 2 +- py_neon/dense/dField.py | 22 ++--- py_neon/dense/dGrid.py | 30 +++--- py_neon/multires/mField.py | 91 ++++++++++--------- py_neon/multires/mGrid.py | 38 ++++++-- py_neon/multires/mPartition.py | 31 ++++++- 17 files changed, 353 insertions(+), 168 deletions(-) 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::bPartition 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; /** @@ -71,13 +77,13 @@ extern "C" auto bGrid_is_inside_domain( extern "C" auto bGrid_bField_read( uint64_t& fieldHandle, const Neon::index_3d* idx, - const int& cardinality) + const int cardinality) -> int; extern "C" auto bGrid_bField_write( uint64_t& fieldHandle, const Neon::index_3d* idx, - const int& cardinality, + const int cardinality, int newValue) -> int; diff --git a/libNeonPy/include/Neon/py/dGrid.h b/libNeonPy/include/Neon/py/dGrid.h index 09a0c58f..b13582e6 100644 --- a/libNeonPy/include/Neon/py/dGrid.h +++ b/libNeonPy/include/Neon/py/dGrid.h @@ -9,7 +9,8 @@ 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; @@ -22,7 +23,7 @@ extern "C" auto dGrid_delete( extern "C" auto dGrid_get_dimensions( uint64_t& gridHandle, - Neon::int32_3d* dim) + Neon::index_3d* dim) -> int; /** @@ -67,8 +68,7 @@ extern "C" auto dGrid_dField_partition_size( extern "C" auto dGrid_get_properties( uint64_t& gridHandle, - const Neon::index_3d* const idx, - Neon::DataView* dv) + const Neon::index_3d* const idx) -> int; extern "C" auto dGrid_is_inside_domain( diff --git a/libNeonPy/include/Neon/py/mGrid.h b/libNeonPy/include/Neon/py/mGrid.h index 02005f75..fd69d90b 100644 --- a/libNeonPy/include/Neon/py/mGrid.h +++ b/libNeonPy/include/Neon/py/mGrid.h @@ -10,7 +10,7 @@ extern "C" auto mGrid_new( uint64_t& handle, uint64_t& backendPtr, const Neon::index_3d* dim, - uint32_t& depth) + uint32_t depth) -> int; /** @@ -20,12 +20,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 +44,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 +52,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 +69,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, + uint64_t grid_level, const Neon::index_3d* idx) -> int; extern "C" auto mGrid_is_inside_domain( uint64_t& gridHandle, - uint64_t& grid_level, + uint64_t grid_level, const Neon::index_3d* idx) -> bool; extern "C" auto mGrid_mField_read( uint64_t& fieldHandle, - uint64_t& field_level, + uint64_t field_level, const Neon::index_3d* idx, - const int& cardinality) + const int cardinality) -> int; extern "C" auto mGrid_mField_write( uint64_t& fieldHandle, - uint64_t& field_level, + uint64_t field_level, const Neon::index_3d* idx, - const int& cardinality, + const int cardinality, int newValue) -> int; @@ -96,4 +102,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; \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index 168b329e..ff006ed1 100644 --- a/libNeonPy/src/Neon/py/bGrid.cpp +++ b/libNeonPy/src/Neon/py/bGrid.cpp @@ -57,6 +57,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, @@ -89,13 +117,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); @@ -103,7 +132,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(); @@ -112,8 +141,8 @@ 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; } @@ -227,7 +256,7 @@ auto bGrid_is_inside_domain( auto bGrid_bField_read( uint64_t& fieldHandle, const Neon::index_3d* idx, - const int& cardinality) + const int cardinality) -> int { std::cout << "bGrid_bField_read begin" << std::endl; @@ -251,7 +280,7 @@ auto bGrid_bField_read( auto bGrid_bField_write( uint64_t& fieldHandle, const Neon::index_3d* idx, - const int& cardinality, + const int cardinality, int newValue) -> int { diff --git a/libNeonPy/src/Neon/py/dGrid.cpp b/libNeonPy/src/Neon/py/dGrid.cpp index 64cb77b7..7466e899 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::index_3d* dim) + const Neon::index_3d* dim, + int* sparsity_pattern) -> int { std::cout << "dGrid_new - BEGIN" << std::endl; @@ -24,7 +25,7 @@ auto dGrid_new( // 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(); @@ -71,8 +72,6 @@ extern "C" auto dGrid_get_dimensions( using Grid = Neon::dGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - std::cerr << dim->x << " " << dim->y << " " << dim->z << std::endl; - if (gridPtr == nullptr) { std::cout << "NeonPy: gridHandle is invalid " << std::endl; return -1; @@ -230,21 +229,18 @@ 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* const idx, - Neon::DataView* dv) + const Neon::index_3d* const idx) -> int { std::cout << "dGrid_get_properties begin" << std::endl; using Grid = Neon::dGrid; Grid* gridPtr = reinterpret_cast(gridHandle); - if (gridPtr == nullptr) { - return -1; - } - *dv = gridPtr->getProperties(*idx).getDataView(); + + int result = static_cast(gridPtr->getProperties(*idx).getDataView()); std::cout << "dGrid_get_properties end" << std::endl; - return 0; + return result; } auto dGrid_is_inside_domain( diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp index b7bf6a05..3d2ed43b 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -6,7 +6,7 @@ auto mGrid_new( uint64_t& handle, uint64_t& backendPtr, const Neon::index_3d* dim, - uint32_t& depth) + uint32_t depth) -> int { std::cout << "mGrid_new - BEGIN" << std::endl; @@ -60,9 +60,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, @@ -97,29 +125,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; } @@ -131,7 +160,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) @@ -185,7 +214,7 @@ auto mGrid_mField_delete( if (fieldPtr != nullptr) { delete fieldPtr; - AllocationCounter::Allocation(); + AllocationCounter::Deallocation(); } handle = 0; std::cout << "mGrid_mField_delete - END" << std::endl; @@ -209,7 +238,7 @@ 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, + uint64_t grid_level, const Neon::index_3d* idx) -> int { @@ -228,7 +257,7 @@ 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, + uint64_t grid_level, const Neon::index_3d* idx ) -> bool @@ -247,9 +276,9 @@ auto mGrid_is_inside_domain( auto mGrid_mField_read( uint64_t& fieldHandle, - uint64_t& field_level, + uint64_t field_level, const Neon::index_3d* idx, - const int& cardinality) + const int cardinality) -> int { std::cout << "mGrid_mField_read begin" << std::endl; @@ -272,9 +301,9 @@ auto mGrid_mField_read( auto mGrid_mField_write( uint64_t& fieldHandle, - uint64_t& field_level, + uint64_t field_level, const Neon::index_3d* idx, - const int& cardinality, + const int cardinality, int newValue) -> int { @@ -340,4 +369,10 @@ auto mGrid_mField_update_device_data( std::cout << "mGrid_mField_update_device_data end" << std::endl; return 0; +} + +extern "C" auto mGrid_mField_mPartition_get_member_field_offsets(size_t* offsets, size_t* length) + -> void +{ + Neon::domain::mGrid::Partition::getOffsets(offsets, length); } \ No newline at end of file diff --git a/py_neon/block/bField.py b/py_neon/block/bField.py index 27b1cd04..2b8205c6 100644 --- a/py_neon/block/bField.py +++ b/py_neon/block/bField.py @@ -2,6 +2,7 @@ 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 @@ -13,19 +14,23 @@ 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.cardinality = cardinality self._help_load_api() - self._help_grid_new() + self._help_field_new() def __del__(self): self.help_delete() @@ -79,18 +84,18 @@ def _help_load_api(self): - def _help_grid_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 +129,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 f5a7e779..ac95c7b1 100644 --- a/py_neon/block/bGrid.py +++ b/py_neon/block/bGrid.py @@ -43,6 +43,10 @@ def _help_load_api(self): 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(bSpan), # the span object py_neon.Execution, # the execution type @@ -81,8 +85,19 @@ 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, @@ -106,7 +121,10 @@ def get_span(self, return span def getProperties(self, idx: Index_3d): - return DataView.from_int(self.py_neon.lib.bGrid_get_properties(ctypes.byref(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(ctypes.by_ref(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 933b03fe..17938b99 100644 --- a/py_neon/block/bPartition.py +++ b/py_neon/block/bPartition.py @@ -7,14 +7,16 @@ 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 __init__(self): @@ -31,22 +33,24 @@ def _help_load_api(self): def get_cpp_field_offsets(self): length = ctypes.c_size_t() - offsets = (ctypes.c_size_t * 8)() # Since there are 8 offsets + 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: {bPartitionInt.setIdx.offset})" 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\tmStencilNghIndex: {self.mStencilNghIndex} (offset: {bPartitionInt.mStencilNghIndex.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.setIdx.offset, bPartitionInt.mCardinality.offset, bPartitionInt.mMem.offset, bPartitionInt.mBlockConnectivity.offset, - bPartitionInt.mMask.offset, bPartitionInt.mOrigin.offset, bPartitionInt.mStencilNghIndex.offset, bPartitionInt.mDomainSize.offset] + 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 4207394d..91539e6f 100644 --- a/py_neon/block/bSpan.py +++ b/py_neon/block/bSpan.py @@ -7,6 +7,7 @@ class bSpan(ctypes.Structure): _fields_ = [ + ("vtablePtr", ctypes.c_uint64), ("mFirstDataBlockOffset", ctypes.c_uint32), ("mActiveMask", ctypes.POINTER(ctypes.c_uint32)), ("mDataView", DataView) diff --git a/py_neon/dataview.py b/py_neon/dataview.py index 8fe2b440..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 diff --git a/py_neon/dense/dField.py b/py_neon/dense/dField.py index aece82c4..bb01950f 100644 --- a/py_neon/dense/dField.py +++ b/py_neon/dense/dField.py @@ -3,7 +3,7 @@ from enum import Enum import py_neon from py_neon import Py_neon -from .dPartition import dPartitionInt as NeDPartition +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 @@ -28,7 +28,7 @@ def __init__(self, self.grid_handle = grid_handle self.cardinality = cardinality self._help_load_api() - self.help_new() + self._help_field_new() def __del__(self): self.help_delete() @@ -47,7 +47,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 @@ -55,7 +55,7 @@ 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 @@ -83,13 +83,13 @@ 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(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: @@ -102,12 +102,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, @@ -115,7 +115,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) diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index d2386794..b6d5e051 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -17,14 +17,20 @@ class dGrid(object): def __init__(self, backend: Backend = None, dim: Index_3d = Index_3d(10,10,10), sparsity_pattern: np.ndarray = None): # @TODOMATT implement psarsity pattern + 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') + self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend self.dim = dim self.sparsity_pattern = sparsity_pattern - if backend is None: - # rise exception - raise Exception('dGrid: backend pamrameter is missing') - + + try: self.py_neon: Py_neon = Py_neon() except Exception as e: @@ -46,7 +52,8 @@ def _help_load_api(self): # 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 @@ -70,8 +77,7 @@ def _help_load_api(self): self.py_neon.lib.dGrid_get_properties.argtypes = [self.py_neon.handle_type, - ctypes.POINTER(py_neon.Index_3d), - ctypes.POINTER(DataView)] + 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, @@ -88,10 +94,9 @@ def _help_grid_new(self): 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}") @@ -136,8 +141,7 @@ def get_span(self, return span def getProperties(self, idx: Index_3d): - dv = DataView(0) - return DataView(self.py_neon.lib.dGrid_get_properties(ctypes.byref(self.handle), idx, dv)) + 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(ctypes.byref(self.handle), idx) diff --git a/py_neon/multires/mField.py b/py_neon/multires/mField.py index a628fcd0..a17ebb77 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,19 +14,23 @@ 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.cardinality = cardinality self._help_load_api() - self.help_new() + self._help_field_new() def __del__(self): self.help_delete() @@ -82,62 +87,60 @@ def _help_load_api(self): - 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) + 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 2226a8d9..bc2e2f09 100644 --- a/py_neon/multires/mGrid.py +++ b/py_neon/multires/mGrid.py @@ -7,14 +7,14 @@ from py_neon.execution import Execution from py_neon import Py_neon from py_neon.dataview import DataView -from ..dense.dSpan import dSpan +from ..block.bSpan import bSpan from ..backend import Backend from py_neon.index_3d import Index_3d class mGrid(object): - def __init__(self, backend = None, dim = None, depth = 0): + def __init__(self, backend = None, dim = None, depth = 1): self.handle: ctypes.c_uint64 = ctypes.c_uint64(0) self.backend = backend self.dim = dim @@ -45,16 +45,21 @@ 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 @@ -86,19 +91,30 @@ 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() + 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') @@ -111,8 +127,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(ctypes.byref(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): + 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 4827da31..4332d358 100644 --- a/py_neon/multires/mPartition.py +++ b/py_neon/multires/mPartition.py @@ -8,6 +8,15 @@ 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)), @@ -29,17 +38,26 @@ def __init__(self): self._help_load_api() def _help_load_api(self): - self.py_neon.lib.mGrid_mField_dPartition_get_member_field_offsets.argtypes = [ctypes.POINTER(ctypes.c_size_t), ctypes.POINTER(ctypes.c_size_t)] - self.py_neon.lib.mGrid_mField_dPartition_get_member_field_offsets.restype = None + 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 * 10)() # Since there are 10 offsets - self.py_neon.lib.mGrid_mField_dPartition_get_member_field_offsets(offsets, ctypes.byref(length)) + 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\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})" @@ -53,6 +71,9 @@ def __str__(self): return str_repr def get_offsets(self): - return [mPartitionInt.mLevel.offset, mPartitionInt.mMemParent.offset, mPartitionInt.mMemChild.offset, mPartitionInt.mParentBlockID.offset, + 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] \ No newline at end of file From 4498ab293a30e6b8ae49fe36fc37f9d2f2946439 Mon Sep 17 00:00:00 2001 From: mattloulou Date: Wed, 10 Jul 2024 16:30:42 -0700 Subject: [PATCH 10/10] sparsity_pattern is implemented for dense/block/multires but probably isn't implemented correctly --- libNeonPy/include/Neon/py/bGrid.h | 5 +++-- libNeonPy/include/Neon/py/mGrid.h | 2 ++ libNeonPy/src/Neon/py/bGrid.cpp | 5 +++-- libNeonPy/src/Neon/py/mGrid.cpp | 3 ++- py_neon/block/bGrid.py | 34 ++++++++++++++++++++++--------- py_neon/dense/dGrid.py | 17 +++++----------- py_neon/multires/mGrid.py | 32 +++++++++++++++++++++-------- 7 files changed, 62 insertions(+), 36 deletions(-) diff --git a/libNeonPy/include/Neon/py/bGrid.h b/libNeonPy/include/Neon/py/bGrid.h index 2689923a..148f5c2a 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, uint64_t& backendPtr, - const Neon::index_3d* dim) + const Neon::int32_3d* dim, + int* sparsity_pattern) -> int; /** diff --git a/libNeonPy/include/Neon/py/mGrid.h b/libNeonPy/include/Neon/py/mGrid.h index fd69d90b..fb0c1eeb 100644 --- a/libNeonPy/include/Neon/py/mGrid.h +++ b/libNeonPy/include/Neon/py/mGrid.h @@ -10,9 +10,11 @@ extern "C" auto mGrid_new( uint64_t& handle, uint64_t& backendPtr, const Neon::index_3d* dim, + int* sparsity_pattern, uint32_t depth) -> int; + /** * Delete a grid object on the heap. */ diff --git a/libNeonPy/src/Neon/py/bGrid.cpp b/libNeonPy/src/Neon/py/bGrid.cpp index ff006ed1..b1425d05 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, - const Neon::index_3d* dim) + const Neon::index_3d* dim, + int* sparsity_pattern) -> int { std::cout << "bGrid_new - BEGIN" << std::endl; @@ -23,7 +24,7 @@ auto bGrid_new( } 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(); diff --git a/libNeonPy/src/Neon/py/mGrid.cpp b/libNeonPy/src/Neon/py/mGrid.cpp index 3d2ed43b..b4521e8a 100644 --- a/libNeonPy/src/Neon/py/mGrid.cpp +++ b/libNeonPy/src/Neon/py/mGrid.cpp @@ -6,6 +6,7 @@ auto mGrid_new( uint64_t& handle, uint64_t& backendPtr, const Neon::index_3d* dim, + int* sparsity_pattern, uint32_t depth) -> int { @@ -24,7 +25,7 @@ auto mGrid_new( 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(*backend, *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(); diff --git a/py_neon/block/bGrid.py b/py_neon/block/bGrid.py index ac95c7b1..b2ab1b2a 100644 --- a/py_neon/block/bGrid.py +++ b/py_neon/block/bGrid.py @@ -10,19 +10,32 @@ from .bSpan import bSpan 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): + 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') + 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() @@ -36,7 +49,8 @@ def _help_load_api(self): # grid_new self.py_neon.lib.bGrid_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.bGrid_new.restype = ctypes.c_int # grid_delete @@ -69,17 +83,17 @@ def _help_load_api(self): def _help_grid_new(self): - if self.handle == 0: - raise Exception('bGrid: Invalid handle') + if self.backend.handle.value == 0: # Check backend handle validity + raise Exception('bGrid: Invalid backend handle') - if self.backend is None: - self.backend = Backend() - if self.dim is None: - self.dim = py_neon.Index_3d(10,10,10) - - res = self.py_neon.lib.bGrid_new(ctypes.byref(self.handle), ctypes.byref(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.py_neon.lib.bGrid_delete(ctypes.byref(self.handle)) != 0: diff --git a/py_neon/dense/dGrid.py b/py_neon/dense/dGrid.py index b6d5e051..709028ee 100644 --- a/py_neon/dense/dGrid.py +++ b/py_neon/dense/dGrid.py @@ -16,7 +16,7 @@ class dGrid(object): - def __init__(self, backend: Backend = None, dim: Index_3d = Index_3d(10,10,10), sparsity_pattern: np.ndarray = None): # @TODOMATT implement psarsity pattern + 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: @@ -46,10 +46,6 @@ 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), @@ -87,19 +83,16 @@ def _help_load_api(self): 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 - 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: diff --git a/py_neon/multires/mGrid.py b/py_neon/multires/mGrid.py index bc2e2f09..642230fd 100644 --- a/py_neon/multires/mGrid.py +++ b/py_neon/multires/mGrid.py @@ -10,20 +10,33 @@ 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): + 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') + 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() @@ -38,6 +51,7 @@ def _help_load_api(self): self.py_neon.lib.mGrid_new.argtypes = [self.py_neon.handle_type, 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 @@ -75,17 +89,17 @@ def _help_load_api(self): def _help_grid_new(self): - if self.handle == 0: - raise Exception('mGrid: Invalid handle') + if self.backend.handle.value == 0: # Check backend handle validity + raise Exception('mGrid: Invalid backend handle') - if self.backend is None: - self.backend = Backend() - if self.dim is None: - self.dim = py_neon.Index_3d(10,10,10) - - res = self.py_neon.lib.mGrid_new(ctypes.byref(self.handle), ctypes.byref(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.py_neon.lib.mGrid_delete(ctypes.byref(self.handle)) != 0: