diff --git a/python/src/kp/__init__.py b/python/src/kp/__init__.py new file mode 100644 index 00000000..368d167d --- /dev/null +++ b/python/src/kp/__init__.py @@ -0,0 +1 @@ +from .kp import * diff --git a/python/src/main.cpp b/python/src/main.cpp index 8da69669..72f546a3 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -3,12 +3,14 @@ #include #include +#include #include #include "docstrings.hpp" #include "utils.hpp" +typedef unsigned char byte; namespace py = pybind11; // used in Core.hpp @@ -24,31 +26,35 @@ opAlgoDispatchPyInit(std::shared_ptr& algorithm, push_consts.size(), std::string(py::str(push_consts.dtype()))); - if (push_consts.dtype().is(py::dtype::of())) { - std::vector dataVec((float*)info.ptr, - ((float*)info.ptr) + info.size); - return std::unique_ptr{ new kp::OpAlgoDispatch( - algorithm, dataVec) }; - } else if (push_consts.dtype().is(py::dtype::of())) { - std::vector dataVec((uint32_t*)info.ptr, - ((uint32_t*)info.ptr) + info.size); - return std::unique_ptr{ new kp::OpAlgoDispatch( - algorithm, dataVec) }; - } else if (push_consts.dtype().is(py::dtype::of())) { - std::vector dataVec((int32_t*)info.ptr, - ((int32_t*)info.ptr) + info.size); - return std::unique_ptr{ new kp::OpAlgoDispatch( - algorithm, dataVec) }; - } else if (push_consts.dtype().is(py::dtype::of())) { - std::vector dataVec((double*)info.ptr, - ((double*)info.ptr) + info.size); - return std::unique_ptr{ new kp::OpAlgoDispatch( - algorithm, dataVec) }; - } else { - throw std::runtime_error("Kompute Python no valid dtype supported"); - } + std::vector dataVec((byte*)info.ptr, + ((byte*)info.ptr) + info.size); + return std::unique_ptr{ new kp::OpAlgoDispatch( + algorithm, dataVec) }; } +class PyTypeContainer : public ABCTypeContainer +{ + public: + PyTypeContainer(py::object clazz) + : clazz_(clazz) + {} + + bool compare(ABCTypeContainer& obj) override + { + // Implement comparison logic here + auto other = dynamic_cast(&obj); + return other && clazz_.is(other->clazz_); + } + + std::string name() override + { + // Return the name here + return py::str(clazz_); + } + + py::object clazz_; +}; + PYBIND11_MODULE(kp, m) { @@ -131,34 +137,32 @@ PYBIND11_MODULE(kp, m) m, "Tensor", DOC(kp, Tensor)) .def( "data", - [](kp::Tensor& self) { + [np](kp::Tensor& self) { // Non-owning container exposing the underlying pointer - switch (self.dataType()) { - case kp::Tensor::TensorDataTypes::eFloat: - return py::array( - self.size(), self.data(), py::cast(&self)); - case kp::Tensor::TensorDataTypes::eUnsignedInt: - return py::array( - self.size(), self.data(), py::cast(&self)); - case kp::Tensor::TensorDataTypes::eInt: - return py::array( - self.size(), self.data(), py::cast(&self)); - case kp::Tensor::TensorDataTypes::eDouble: - return py::array( - self.size(), self.data(), py::cast(&self)); - case kp::Tensor::TensorDataTypes::eBool: - return py::array( - self.size(), self.data(), py::cast(&self)); - default: - throw std::runtime_error( - "Kompute Python data type not supported"); - } + auto frombuffer = np.attr("frombuffer"); + + auto dtype = + dynamic_cast(&(*self.dataType()))->clazz_; + + auto buffer = + py::array(self.size() * dtype.attr("itemsize").cast(), + self.data(), + py::cast(&self)); + + + + return frombuffer(buffer, dtype); }, DOC(kp, Tensor, data)) .def("size", &kp::Tensor::size, DOC(kp, Tensor, size)) .def("__len__", &kp::Tensor::size, DOC(kp, Tensor, size)) .def("tensor_type", &kp::Tensor::tensorType, DOC(kp, Tensor, tensorType)) - .def("data_type", &kp::Tensor::dataType, DOC(kp, Tensor, dataType)) + .def( + "data_type", + [](kp::Tensor& self) { + return dynamic_cast(&(*self.dataType()))->clazz_; + }, + DOC(kp, Tensor, dataType)) .def("is_init", &kp::Tensor::isInit, DOC(kp, Tensor, isInit)) .def("destroy", &kp::Tensor::destroy, DOC(kp, Tensor, destroy)); @@ -236,10 +240,13 @@ PYBIND11_MODULE(kp, m) KP_LOG_DEBUG("Kompute Python Manager tensor() creating tensor " "float with data size {}", flatdata.size()); + + std::shared_ptr typeContainer = + std::make_shared(flatdata.dtype()); return self.tensor(info.ptr, flatdata.size(), - sizeof(float), - kp::Tensor::TensorDataTypes::eFloat, + flatdata.dtype().itemsize(), + typeContainer, tensor_type); }, DOC(kp, Manager, tensor), @@ -257,31 +264,14 @@ PYBIND11_MODULE(kp, m) "size {} dtype {}", flatdata.size(), std::string(py::str(flatdata.dtype()))); - if (flatdata.dtype().is(py::dtype::of())) { - return self.tensor(info.ptr, - flatdata.size(), - tensor_type); - } else if (flatdata.dtype().is(py::dtype::of())) { - return self.tensor( - info.ptr, - flatdata.size(), - tensor_type); - } else if (flatdata.dtype().is(py::dtype::of())) { - return self.tensor(info.ptr, - flatdata.size(), - tensor_type); - } else if (flatdata.dtype().is(py::dtype::of())) { - return self.tensor(info.ptr, - flatdata.size(), - tensor_type); - } else if (flatdata.dtype().is(py::dtype::of())) { - return self.tensor(info.ptr, - flatdata.size(), - tensor_type); - } else { - throw std::runtime_error( - "Kompute Python no valid dtype supported"); - } + + std::shared_ptr typeContainer = + std::make_shared(flatdata.dtype()); + return self.tensor(info.ptr, + flatdata.size(), + flatdata.dtype().itemsize(), + typeContainer, + tensor_type); }, DOC(kp, Manager, tensorT), py::arg("data"), @@ -333,186 +323,14 @@ PYBIND11_MODULE(kp, m) spec_consts.size(), std::string(py::str(spec_consts.dtype()))); - // We have to iterate across a combination of parameters due to the - // lack of support for templating - if (spec_consts.dtype().is(py::dtype::of())) { - std::vector specConstsVec( - (float*)specInfo.ptr, ((float*)specInfo.ptr) + specInfo.size); - if (spec_consts.dtype().is(py::dtype::of())) { - std::vector pushConstsVec((float*)pushInfo.ptr, - ((float*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specConstsVec, - pushConstsVec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushConstsVec( - (int32_t*)pushInfo.ptr, - ((int32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specConstsVec, - pushConstsVec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushConstsVec( - (uint32_t*)pushInfo.ptr, - ((uint32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specConstsVec, - pushConstsVec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushConstsVec((double*)pushInfo.ptr, - ((double*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specConstsVec, - pushConstsVec); - } - } else if (spec_consts.dtype().is(py::dtype::of())) { - std::vector specconstsvec((int32_t*)specInfo.ptr, - ((int32_t*)specInfo.ptr) + - specInfo.size); - if (spec_consts.dtype().is(py::dtype::of())) { - std::vector pushconstsvec((float*)pushInfo.ptr, - ((float*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec( - (int32_t*)pushInfo.ptr, - ((int32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec( - (uint32_t*)pushInfo.ptr, - ((uint32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec((double*)pushInfo.ptr, - ((double*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } - } else if (spec_consts.dtype().is(py::dtype::of())) { - std::vector specconstsvec((uint32_t*)specInfo.ptr, - ((uint32_t*)specInfo.ptr) + - specInfo.size); - if (spec_consts.dtype().is(py::dtype::of())) { - std::vector pushconstsvec((float*)pushInfo.ptr, - ((float*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec( - (int32_t*)pushInfo.ptr, - ((int32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec( - (uint32_t*)pushInfo.ptr, - ((uint32_t*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec((double*)pushInfo.ptr, - ((double*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } - } else if (spec_consts.dtype().is(py::dtype::of())) { - std::vector specconstsvec((double*)specInfo.ptr, - ((double*)specInfo.ptr) + - specInfo.size); - if (spec_consts.dtype().is(py::dtype::of())) { - std::vector pushconstsvec((float*)pushInfo.ptr, - ((float*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec((int32_t*)pushInfo.ptr, - ((int32_t*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec((uint32_t*)pushInfo.ptr, - ((uint32_t*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } else if (spec_consts.dtype().is( - py::dtype::of())) { - std::vector pushconstsvec((double*)pushInfo.ptr, - ((double*)pushInfo.ptr) + - pushInfo.size); - return self.algorithm(tensors, - spirvVec, - workgroup, - specconstsvec, - pushconstsvec); - } - } - // If reach then no valid dtype supported - throw std::runtime_error("Kompute Python no valid dtype supported"); + std::vector specconstsvec( + (byte*)specInfo.ptr, ((byte*)specInfo.ptr) + specInfo.size); + + std::vector pushconstsvec( + (byte*)pushInfo.ptr, ((byte*)pushInfo.ptr) + pushInfo.size); + + return self.algorithm( + tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); }, DOC(kp, Manager, algorithm), py::arg("tensors"), diff --git a/setup.py b/setup.py index 09faa8d1..0f5b8c4c 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ import sysconfig import subprocess -from setuptools import setup, Extension +from setuptools import setup, Extension, find_packages from setuptools.command.build_ext import build_ext from distutils.version import LooseVersion @@ -83,7 +83,11 @@ def build_extension(self, ext): description='Kompute: Blazing fast, mobile-enabled, asynchronous, and optimized for advanced GPU processing usecases.', long_description=long_description, long_description_content_type='text/markdown', - ext_modules=[CMakeExtension('kp')], + ext_modules=[CMakeExtension('kp/kp')], + packages = find_packages(where="python/src"), + package_dir={ + 'kp': 'python/src/kp' + }, install_requires=[ "numpy<2.0.0" ], diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dbb47dbe..e2407d37 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,7 +17,8 @@ add_library(kompute Algorithm.cpp OpTensorSyncLocal.cpp Sequence.cpp Tensor.cpp - Core.cpp) + Core.cpp + TypeContainer.cpp) add_library(kompute::kompute ALIAS kompute) diff --git a/src/OpTensorCopy.cpp b/src/OpTensorCopy.cpp index 116d4ff7..6ea5d0f3 100644 --- a/src/OpTensorCopy.cpp +++ b/src/OpTensorCopy.cpp @@ -17,10 +17,11 @@ OpTensorCopy::OpTensorCopy(const std::vector>& tensors) "Kompute OpTensorCopy called with less than 2 tensor"); } - const std::type_info& dataType = this->mTensors[0]->dataType(); + std::shared_ptr dataType = this->mTensors[0]->dataType(); + uint32_t size = this->mTensors[0]->size(); for (const std::shared_ptr& tensor : tensors) { - if (tensor->dataType() != dataType) { + if (!(*dataType).compare(*tensor->dataType())) { throw std::runtime_error(fmt::format( "Attempting to copy tensors of different types from {} to {}", Tensor::toString(dataType), diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 9359bd68..ab44e170 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -6,9 +6,9 @@ namespace kp { std::string -Tensor::toString(const std::type_info& dt) +Tensor::toString(std::shared_ptr dt) { - return dt.name(); + return (*dt).name(); } std::string @@ -31,7 +31,7 @@ Tensor::Tensor(std::shared_ptr physicalDevice, void* data, uint32_t elementTotalCount, uint32_t elementMemorySize, - const std::type_info& dataType, + std::shared_ptr dataType, const TensorTypes& tensorType) : mDataType(dataType) { @@ -113,7 +113,7 @@ Tensor::memorySize() return this->mSize * this->mDataTypeMemorySize; } -const std::type_info& +std::shared_ptr Tensor::dataType() { return this->mDataType; diff --git a/src/TypeContainer.cpp b/src/TypeContainer.cpp new file mode 100644 index 00000000..7142356c --- /dev/null +++ b/src/TypeContainer.cpp @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 + +#include "kompute/TypeContainer.hpp" + +size_t IdCounter::counter = 0; \ No newline at end of file diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt index e1652fdd..214c8b30 100644 --- a/src/include/CMakeLists.txt +++ b/src/include/CMakeLists.txt @@ -15,6 +15,8 @@ target_sources(kompute PRIVATE kompute/Manager.hpp kompute/Sequence.hpp kompute/Tensor.hpp + kompute/TypeContainer.hpp + kompute/ABCTypeContainer.hpp kompute/operations/OpAlgoDispatch.hpp kompute/operations/OpBase.hpp diff --git a/src/include/kompute/ABCTypeContainer.hpp b/src/include/kompute/ABCTypeContainer.hpp new file mode 100644 index 00000000..af3e4a76 --- /dev/null +++ b/src/include/kompute/ABCTypeContainer.hpp @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: Apache-2.0 +#pragma once +#include + +class ABCTypeContainer +{ + public: + // Pure Virtual Function + virtual bool compare(ABCTypeContainer& obj) = 0; + virtual std::string name() = 0; +}; \ No newline at end of file diff --git a/src/include/kompute/Manager.hpp b/src/include/kompute/Manager.hpp index 3d3fc084..b90cdbf6 100644 --- a/src/include/kompute/Manager.hpp +++ b/src/include/kompute/Manager.hpp @@ -9,6 +9,7 @@ #include "kompute/Sequence.hpp" #include "logger/Logger.hpp" +#include #define KP_DEFAULT_SESSION "DEFAULT" @@ -107,12 +108,15 @@ class Manager std::shared_ptr tensor( void* data, uint32_t elementTotalCount, + uint32_t elementMemorySize = sizeof(T), + std::shared_ptr dataType = + std::make_shared>(), Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice) { - return tensor(data, - elementTotalCount, - sizeof(T), - typeid(T), + return this->tensor(data, + elementTotalCount, + elementMemorySize, + dataType, tensorType); } @@ -120,16 +124,17 @@ class Manager void* data, uint32_t elementTotalCount, uint32_t elementMemorySize, - const std::type_info& dataType, + std::shared_ptr dataType, Tensor::TensorTypes tensorType = Tensor::TensorTypes::eDevice) { - std::shared_ptr tensor{ new kp::Tensor(this->mPhysicalDevice, - this->mDevice, - data, - elementTotalCount, - elementMemorySize, - dataType, - tensorType) }; + std::shared_ptr tensor = + std::make_shared(this->mPhysicalDevice, + this->mDevice, + data, + elementTotalCount, + elementMemorySize, + dataType, + tensorType); if (this->mManageResources) { this->mManagedTensors.push_back(tensor); diff --git a/src/include/kompute/Tensor.hpp b/src/include/kompute/Tensor.hpp index 67f08f3b..43c765cd 100644 --- a/src/include/kompute/Tensor.hpp +++ b/src/include/kompute/Tensor.hpp @@ -6,6 +6,7 @@ #include #include #include +#include "TypeContainer.hpp" namespace kp { @@ -33,7 +34,7 @@ class Tensor eStorage = 2, ///< Type is Device memory (only) }; - static std::string toString(const std::type_info& dt); + static std::string toString(std::shared_ptr dt); static std::string toString(TensorTypes dt); /** @@ -51,7 +52,7 @@ class Tensor void* data, uint32_t elementTotalCount, uint32_t elementMemorySize, - const std::type_info& dataType, + std::shared_ptr dataType, const TensorTypes& tensorType = TensorTypes::eDevice); /** @@ -194,7 +195,7 @@ class Tensor * * @return Data type of tensor of type kp::Tensor::TensorDataTypes */ - const std::type_info& dataType(); + std::shared_ptr dataType(); /** * Retrieve the raw data via the pointer to the memory that contains the raw @@ -240,7 +241,7 @@ class Tensor protected: // -------------- ALWAYS OWNED RESOURCES TensorTypes mTensorType; - const std::type_info& mDataType; + std::shared_ptr mDataType; uint32_t mSize; uint32_t mDataTypeMemorySize; void* mRawData; @@ -334,9 +335,9 @@ class TensorT : public Tensor Tensor::setRawData(data.data()); } - const std::type_info& dataType() + std::shared_ptr dataType() { - return typeid(T); + return std::make_shared>(); } }; diff --git a/src/include/kompute/TypeContainer.hpp b/src/include/kompute/TypeContainer.hpp new file mode 100644 index 00000000..f562c6c9 --- /dev/null +++ b/src/include/kompute/TypeContainer.hpp @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include "ABCTypeContainer.hpp" +#include + + +struct IdCounter +{ + static size_t counter; +}; + +template +class TypeContainer : public ABCTypeContainer, IdCounter +{ + private: + size_t classId() + { + static size_t id = counter++; + return id; + } + + public: + TypeContainer() : dt(typeid(T)) {} + + bool compare(ABCTypeContainer& other) override + { + TypeContainer& obj = static_cast(other); + return this->classId() == obj.classId(); + } + + std::string name() override { return this->dt.name(); } + + const std::type_info& dt; +}; \ No newline at end of file