From 32e1779c5410bc04ced5b0d0ed45ea4f30e1fea3 Mon Sep 17 00:00:00 2001 From: Massimiliano Meneghin Date: Tue, 27 Aug 2024 22:46:31 +0200 Subject: [PATCH] WIP - warp skeleton --- libNeonPy/include/Neon/py/macros.h | 4 +- libNeonPy/src/Neon/py/Container.cpp | 27 +++--- libNeonPy/src/Neon/py/Skeleton.cpp | 109 +++++++++++++++++++++++ libNeonSet/include/Neon/set/Containter.h | 3 + libNeonSet/src/set/Containter.cpp | 6 ++ py_neon/skeleton.py | 96 ++++++++++++++++++++ 6 files changed, 233 insertions(+), 12 deletions(-) create mode 100644 libNeonPy/src/Neon/py/Skeleton.cpp create mode 100644 py_neon/skeleton.py diff --git a/libNeonPy/include/Neon/py/macros.h b/libNeonPy/include/Neon/py/macros.h index 58ca1e91..6560886d 100644 --- a/libNeonPy/include/Neon/py/macros.h +++ b/libNeonPy/include/Neon/py/macros.h @@ -5,8 +5,8 @@ #pragma once #define NEON_PY_PRINT_BEGIN(handel) \ - //std::cout <<"NEON BEGIN "<<__func__<< " (void* handle = " << handel << ")"<(handle_cudaDriver); @@ -207,23 +210,28 @@ extern "C" void warp_dgrid_container_new( cudaDriverPtr, dGridPtr, kernels_matrix); + Neon::set::Container* container = nullptr; + std::shared_ptr tmp(warp_container); - if (warp_container == nullptr) { + container = Neon::set::Container::factoryNewWarp(tmp); + + if (container == nullptr) { Neon::NeonException e("warp_dgrid_container_new"); NEON_THROW(e); } - *out_handle = reinterpret_cast(warp_container); + *out_handle = reinterpret_cast(container); + NEON_PY_PRINT_END(*out_handle); } extern "C" void warp_container_delete( uint64_t** handle) { - auto* warp_container = - reinterpret_cast*>(*handle); - if (warp_container != nullptr) { - delete warp_container; + auto* c = reinterpret_cast(*handle); + + if (c != nullptr) { + delete c; } (*handle) = 0; @@ -234,8 +242,7 @@ extern "C" void warp_container_run( int streamIdx, Neon::DataView dataView) { - auto* warpContainerPtr = - reinterpret_cast*>(handle); + auto* c = reinterpret_cast(handle); - warpContainerPtr->run(streamIdx, dataView); + c->run(streamIdx, dataView); } \ No newline at end of file diff --git a/libNeonPy/src/Neon/py/Skeleton.cpp b/libNeonPy/src/Neon/py/Skeleton.cpp new file mode 100644 index 00000000..8949131b --- /dev/null +++ b/libNeonPy/src/Neon/py/Skeleton.cpp @@ -0,0 +1,109 @@ +#include + +#include +#include +#include + +#include "Neon/Neon.h" +#include "Neon/core/core.h" +#include "Neon/domain/Grids.h" +#include "Neon/domain/interface/GridBase.h" +#include "Neon/py/CudaDriver.h" +#include "Neon/set/container/ContainerAPI.h" +#include "Neon/set/container/Loader.h" + +#include "Neon/py/macros.h" +#include "Neon/skeleton/Skeleton.h" + +extern "C" auto warp_skeleton_new( + void** out_handle, + void* bkPtr) -> int +{ + NEON_PY_PRINT_BEGIN(*out_handle); + + Neon::Backend& bk = *static_cast(bkPtr); + std::cout << "warp_skeleton_new " + << "bk " << bkPtr << " " << bk.toString() << std::endl; + auto* skeleton = new (std::nothrow) Neon::skeleton::Skeleton(bk); + if (skeleton == nullptr) { + return -1; + } + (*out_handle) = skeleton; + NEON_PY_PRINT_END(*out_handle); + return 0; +} + +extern "C" auto warp_skeleton_delete( + void** out_handle) -> int +{ + try { + auto* skeleton = static_cast(*out_handle); + delete skeleton; + (*out_handle) = nullptr; + return 0; + } catch (...) { + return -1; + } +} + +extern "C" void warp_skeleton_sequence( + void* handle, + const char* graphName, + int numContainers, + Neon::set::Container** containers) +{ + // # Load the shared library + // # On Linux + // lib = ctypes.CDLL('./libexample.so') + // + // # On Windows + // # lib = ctypes.CDLL('example.dll') + // + // # Define the argument type for the C++ function + // lib.print_message.argtypes = [ctypes.c_char_p] + // + // # Convert Python string to bytes (C char array) + // message = "Hello from Python".encode('utf-8') + // + // # Call the C++ function + // lib.print_message(message) + NEON_PY_PRINT_BEGIN(handle); + + Neon::skeleton::Skeleton* skeleton = static_cast(handle); + std::string name(graphName); + std::vector operations; + for (int i = 0; i < numContainers; i++) { + operations.push_back(*containers[i]); + } + skeleton->sequence(operations, name, Neon::skeleton::Options()); + NEON_PY_PRINT_END(handle); +} + +extern "C" auto warp_skeleton_run( + void* handle) -> int +{ + try { + auto* s = static_cast(handle); + s->run(); + return 0; + } catch (...) { + return -1; + } +} + +extern "C" auto warp_skeleton_ioToDot( + void* handle, + const char* fname, + const char* gname, + int debug) + -> int +{ + try { + + auto* s = static_cast(handle); + s->ioToDot(fname, gname, debug == 1); + } catch (...) { + return -1; + } + return 0; +} diff --git a/libNeonSet/include/Neon/set/Containter.h b/libNeonSet/include/Neon/set/Containter.h index 76e63940..7a916c87 100644 --- a/libNeonSet/include/Neon/set/Containter.h +++ b/libNeonSet/include/Neon/set/Containter.h @@ -141,6 +141,9 @@ struct Container static auto factoryAnchor(const std::string& name /**< A user's string to identify the computation done by the Container. */) -> Container; + static auto factoryNewWarp( std::shared_ptr warpContainer) + -> Container*; + auto getName() const -> const std::string&; diff --git a/libNeonSet/src/set/Containter.cpp b/libNeonSet/src/set/Containter.cpp index ba5c424c..814ff996 100644 --- a/libNeonSet/src/set/Containter.cpp +++ b/libNeonSet/src/set/Containter.cpp @@ -60,6 +60,12 @@ auto Container::factoryAnchor(const std::string& name) -> Container return Container(tmp); } +auto Container::factoryNewWarp(std::shared_ptr warpContainer) + -> Container* +{ + auto* containerPtr = new (std::nothrow) Neon::set::Container(warpContainer); + return containerPtr; +} auto Container::getName() const -> const std::string& diff --git a/py_neon/skeleton.py b/py_neon/skeleton.py new file mode 100644 index 00000000..6cacf923 --- /dev/null +++ b/py_neon/skeleton.py @@ -0,0 +1,96 @@ +import ctypes +from typing import List + +from py_neon import Backend +from py_neon import Py_neon +from wpne import Container + + +class Skeleton(object): + def __init__(self, + backend: Backend): + + self.skeleton_handle: ctypes.c_void_p = ctypes.c_void_p(0) + self.backend = backend + + try: + self.py_neon: Py_neon = Py_neon() + except Exception as e: + self.skeleton_handle = ctypes.c_void_p(0) + raise Exception('Failed to initialize PyNeon: ' + str(e)) + + self.help_load_api() + self.help_skeleton_new() + + def __del__(self): + if self.skeleton_handle == 0: + return + self.help_skeleton_new() + pass + + def help_load_api(self): + lib_obj = self.py_neon.lib + # ------------------------------------------------------------------ + # warp_skeleton_new + self.api_new = lib_obj.warp_skeleton_new + self.api_new.argtypes = [ctypes.POINTER(self.py_neon.handle_type), + self.py_neon.handle_type] + self.api_new.restype = ctypes.c_int + # ------------------------------------------------------------------ + # warp_skeleton_delete + self.api_delete = lib_obj.warp_skeleton_delete + self.api_delete.argtypes = [ctypes.POINTER(self.py_neon.handle_type)] + self.api_delete.restype = ctypes.c_int + # ------------------------------------------------------------------ + # warp_skeleton_sequence + self.api_sequence = lib_obj.warp_skeleton_sequence + self.api_sequence.argtypes = [self.py_neon.handle_type, + ctypes.c_char_p, + ctypes.c_int, + ctypes.POINTER(self.py_neon.handle_type)] + self.api_sequence.restype = ctypes.c_int + # ------------------------------------------------------------------ + # warp_skeleton_run + self.api_run = lib_obj.warp_skeleton_run + self.api_run.argtypes = [self.py_neon.handle_type] + self.api_run.restype = ctypes.c_int + # ------------------------------------------------------------------ + # warp_skeleton_ioToDot + self.api_run = lib_obj.warp_skeleton_ioToDot + self.api_run.argtypes = [self.py_neon.handle_type, + ctypes.c_char_p, + ctypes.c_char_p, + ctypes.c_int] + self.api_run.restype = ctypes.c_int + + def help_skeleton_new(self): + if self.skeleton_handle.value != ctypes.c_void_p(0).value: + raise Exception(f'Skeleton: Invalid handle {self.skeleton_handle}') + + res = self.py_neon.lib.warp_skeleton_new(ctypes.pointer(self.skeleton_handle), + self.backend.backend_handle) + + if res != 0: + raise Exception('Backend: Failed to initialize backend') + + def help_skeleton_delete(self): + if self.skeleton_handle == 0: + return + res = self.api_delete(ctypes.pointer(self.skeleton_handle)) + if res != 0: + raise Exception('Failed to delete backend') + + def sequence(self, name: str, containers: List[Container]): + self.containers = containers + self.handle_list = (ctypes.c_void_p * len(containers))() + for i in range(len(self.handle_list)): + self.handle_list[i] = containers[i].container_handle + print(f"PYTHON handle_list {self.handle_list}") + print(f"PYTHON handle_list[0] {hex(self.handle_list[0])}") + self.api_sequence(self.skeleton_handle, + name.encode('utf-8'), + len(self.handle_list), + self.handle_list) + + def run(self): + self.api_run(self.skeleton_handle) \ No newline at end of file