From f01bcb68a502e361a887830d2fcd650b2e3bea53 Mon Sep 17 00:00:00 2001 From: Fabian Sauter Date: Fri, 20 May 2022 16:12:18 +0200 Subject: [PATCH] New logging framework Signed-off-by: Fabian Sauter --- CMakeLists.txt | 28 +- python/src/main.cpp | 751 +++++++++++++++++--------- src/CMakeLists.txt | 15 +- src/Manager.cpp | 18 +- src/OpTensorCopy.cpp | 5 +- src/Tensor.cpp | 38 +- src/include/CMakeLists.txt | 20 + src/include/kompute/Algorithm.hpp | 1 + src/include/kompute/Core.hpp | 119 ---- src/include/kompute/Manager.hpp | 1 + src/include/kompute/Tensor.hpp | 65 +-- src/include/kompute/logger/Logger.hpp | 36 ++ src/logger/CMakeLists.txt | 37 ++ src/logger/Logger.cpp | 192 +++++++ test/TestPushConstant.cpp | 2 - 15 files changed, 848 insertions(+), 480 deletions(-) create mode 100644 src/include/kompute/logger/Logger.hpp create mode 100644 src/logger/CMakeLists.txt create mode 100644 src/logger/Logger.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e6ce10cc3..e9302b643 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,8 +74,7 @@ kompute_option(KOMPUTE_OPT_INSTALL "Enable if you want to enable installation" O # Build options kompute_option(KOMPUTE_OPT_BUILD_PYTHON "Enable if you want to build python bindings" OFF) -kompute_option(KOMPUTE_OPT_ENABLE_LOGGING "Internally we use spdlog for logging. The log output can be either enabled or disabled." OFF) -kompute_log_level(KOMPUTE_OPT_LOG_LEVEL "Internally we use spdlog for logging. The log level used can be changed here." "Debug") +kompute_log_level(KOMPUTE_OPT_LOG_LEVEL "Internally we use spdlog for logging. The log level used can be changed here." "Off") kompute_option(KOMPUTE_OPT_ANDROID_BUILD "Enable android compilation flags required" OFF) kompute_option(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS "Explicitly disable debug layers even on debug" OFF) kompute_option(KOMPUTE_OPT_DISABLE_VULKAN_VERSION_CHECK "Whether to check if your driver supports the Vulkan Header version you are linking against. This might be useful in case you build shared on a different system than you run later." OFF) @@ -124,26 +123,21 @@ else() endif() # Spdlog -if(KOMPUTE_OPT_ENABLE_LOGGING) - if(KOMPUTE_OPT_ENABLE_SPDLOG) - if(KOMPUTE_OPT_USE_BUILD_IN_SPDLOG) - set(SPDLOG_INSTALL ${KOMPUTE_OPT_INSTALL}) - set(SPDLOG_BUILD_SHARED ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS}) +if(KOMPUTE_OPT_USE_BUILD_IN_SPDLOG) + set(SPDLOG_INSTALL ${KOMPUTE_OPT_INSTALL}) + set(SPDLOG_BUILD_SHARED ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS}) - FetchContent_Declare(spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git - GIT_TAG v1.10.0) # Source: https://github.com/gabime/spdlog/releases - FetchContent_MakeAvailable(spdlog) - else() - find_package(spdlog REQUIRED) - endif() - endif() + FetchContent_Declare(spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git + GIT_TAG v1.10.0) # Source: https://github.com/gabime/spdlog/releases + FetchContent_MakeAvailable(spdlog) +else() + find_package(spdlog REQUIRED) endif() # fmt if(KOMPUTE_OPT_USE_BUILD_IN_FMT) set(FMT_INSTALL ${KOMPUTE_OPT_INSTALL}) set(BUILD_SHARED_LIBS_BKP ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS}) - set(SPDLOG_BUILD_SHARED ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS}) FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG 8.1.1) # Source: https://github.com/fmtlib/fmt/releases FetchContent_MakeAvailable(fmt) @@ -200,10 +194,6 @@ if(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS) add_compile_definitions(KOMPUTE_DISABLE_VK_DEBUG_LAYERS=1) endif() -if(KOMPUTE_OPT_ENABLE_LOGGING) - add_compile_definitions(KOMPUTE_OPT_ENABLE_LOGGING=1) -endif() - ##################################################### # Misc Options ##################################################### diff --git a/python/src/main.cpp b/python/src/main.cpp index d0447fe8e..0ea2793cb 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -1,333 +1,555 @@ +#include #include #include -#include #include -#include "fmt/ranges.h" - -#include "utils.hpp" #include "docstrings.hpp" +#include "utils.hpp" namespace py = pybind11; -//used in Core.hpp +// used in Core.hpp py::object kp_debug, kp_info, kp_warning, kp_error; -std::unique_ptr opAlgoDispatchPyInit( - std::shared_ptr& algorithm, - const py::array& push_consts) { - const py::buffer_info info = push_consts.request(); - KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with push_consts size {} dtype {}", - push_consts.size(), std::string(py::str(push_consts.dtype()))); - +std::unique_ptr +opAlgoDispatchPyInit(std::shared_ptr& algorithm, + const py::array& push_consts) +{ + const py::buffer_info info = push_consts.request(); + KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with push_consts " + "size {} dtype {}", + push_consts.size(), + std::string(py::str(push_consts.dtype()))); if (push_consts.dtype() == py::dtype::of()) { - std::vector dataVec((float*)info.ptr, ((float*)info.ptr) + info.size); - return std::unique_ptr{new kp::OpAlgoDispatch(algorithm, dataVec)}; + 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() == 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)}; + 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() == 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)}; + 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() == py::dtype::of()) { - std::vector dataVec((double*)info.ptr, ((double*)info.ptr) + info.size); - return std::unique_ptr{new kp::OpAlgoDispatch(algorithm, dataVec)}; + 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"); } } -PYBIND11_MODULE(kp, m) { +PYBIND11_MODULE(kp, m) +{ // The logging modules are used in the Kompute.hpp file - py::module_ logging = py::module_::import("logging"); + py::module_ logging = py::module_::import("logging"); py::object kp_logger = logging.attr("getLogger")("kp"); - kp_debug = kp_logger.attr("debug"); - kp_info = kp_logger.attr("info"); - kp_warning = kp_logger.attr("warning"); - kp_error = kp_logger.attr("error"); + kp_debug = kp_logger.attr("debug"); + kp_info = kp_logger.attr("info"); + kp_warning = kp_logger.attr("warning"); + kp_error = kp_logger.attr("error"); logging.attr("basicConfig")(); py::module_ np = py::module_::import("numpy"); py::enum_(m, "TensorTypes") - .value("device", kp::Tensor::TensorTypes::eDevice, DOC(kp, Tensor, TensorTypes, eDevice)) - .value("host", kp::Tensor::TensorTypes::eHost, DOC(kp, Tensor, TensorTypes, eHost)) - .value("storage", kp::Tensor::TensorTypes::eStorage, DOC(kp, Tensor, TensorTypes, eStorage)) - .export_values(); + .value("device", + kp::Tensor::TensorTypes::eDevice, + DOC(kp, Tensor, TensorTypes, eDevice)) + .value("host", + kp::Tensor::TensorTypes::eHost, + DOC(kp, Tensor, TensorTypes, eHost)) + .value("storage", + kp::Tensor::TensorTypes::eStorage, + DOC(kp, Tensor, TensorTypes, eStorage)) + .export_values(); - py::class_>(m, "OpBase", DOC(kp, OpBase)); + py::class_>( + m, "OpBase", DOC(kp, OpBase)); py::class_>( - m, "OpTensorSyncDevice", py::base(), DOC(kp, OpTensorSyncDevice)) - .def(py::init>&>(), DOC(kp, OpTensorSyncDevice, OpTensorSyncDevice)); + m, + "OpTensorSyncDevice", + py::base(), + DOC(kp, OpTensorSyncDevice)) + .def(py::init>&>(), + DOC(kp, OpTensorSyncDevice, OpTensorSyncDevice)); py::class_>( - m, "OpTensorSyncLocal", py::base(), DOC(kp, OpTensorSyncLocal)) - .def(py::init>&>(), DOC(kp, OpTensorSyncLocal, OpTensorSyncLocal)); + m, + "OpTensorSyncLocal", + py::base(), + DOC(kp, OpTensorSyncLocal)) + .def(py::init>&>(), + DOC(kp, OpTensorSyncLocal, OpTensorSyncLocal)); py::class_>( - m, "OpTensorCopy", py::base(), DOC(kp, OpTensorCopy)) - .def(py::init>&>(), DOC(kp, OpTensorCopy, OpTensorCopy)); + m, "OpTensorCopy", py::base(), DOC(kp, OpTensorCopy)) + .def(py::init>&>(), + DOC(kp, OpTensorCopy, OpTensorCopy)); py::class_>( - m, "OpAlgoDispatch", py::base(), DOC(kp, OpAlgoDispatch)) - .def(py::init&,const std::vector&>(), - DOC(kp, OpAlgoDispatch, OpAlgoDispatch), - py::arg("algorithm"), py::arg("push_consts") = std::vector()) - .def(py::init(&opAlgoDispatchPyInit), - DOC(kp, OpAlgoDispatch, OpAlgoDispatch), - py::arg("algorithm"), py::arg("push_consts")); + m, "OpAlgoDispatch", py::base(), DOC(kp, OpAlgoDispatch)) + .def(py::init&, + const std::vector&>(), + DOC(kp, OpAlgoDispatch, OpAlgoDispatch), + py::arg("algorithm"), + py::arg("push_consts") = std::vector()) + .def(py::init(&opAlgoDispatchPyInit), + DOC(kp, OpAlgoDispatch, OpAlgoDispatch), + py::arg("algorithm"), + py::arg("push_consts")); py::class_>( - m, "OpMult", py::base(), DOC(kp, OpMult)) - .def(py::init>&,const std::shared_ptr&>(), - DOC(kp, OpMult, OpMult)); + m, "OpMult", py::base(), DOC(kp, OpMult)) + .def(py::init>&, + const std::shared_ptr&>(), + DOC(kp, OpMult, OpMult)); - py::class_>(m, "Algorithm", DOC(kp, Algorithm, Algorithm)) - .def("get_tensors", &kp::Algorithm::getTensors, DOC(kp, Algorithm, getTensors)) - .def("destroy", &kp::Algorithm::destroy, DOC(kp, Algorithm, destroy)) - .def("is_init", &kp::Algorithm::isInit, DOC(kp, Algorithm, isInit)); + py::class_>( + m, "Algorithm", DOC(kp, Algorithm, Algorithm)) + .def("get_tensors", + &kp::Algorithm::getTensors, + DOC(kp, Algorithm, getTensors)) + .def("destroy", &kp::Algorithm::destroy, DOC(kp, Algorithm, destroy)) + .def("is_init", &kp::Algorithm::isInit, DOC(kp, Algorithm, isInit)); - py::class_>(m, "Tensor", DOC(kp, Tensor)) - .def("data", [](kp::Tensor& self) { - // Non-owning container exposing the underlying pointer - switch (self.dataType()) { + py::class_>( + m, "Tensor", DOC(kp, Tensor)) + .def( + "data", + [](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)); + 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)); + 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)); + 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)); + 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)); + return py::array( + self.size(), self.data(), py::cast(&self)); default: - throw std::runtime_error("Kompute Python data type not supported"); - } - }, 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("is_init", &kp::Tensor::isInit, DOC(kp, Tensor, isInit)) - .def("destroy", &kp::Tensor::destroy, DOC(kp, Tensor, destroy)); + throw std::runtime_error( + "Kompute Python data type not supported"); + } + }, + 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("is_init", &kp::Tensor::isInit, DOC(kp, Tensor, isInit)) + .def("destroy", &kp::Tensor::destroy, DOC(kp, Tensor, destroy)); py::class_>(m, "Sequence") - .def("record", [](kp::Sequence& self, std::shared_ptr op) { return self.record(op); }, - DOC(kp, Sequence, record)) - .def("eval", [](kp::Sequence& self) { return self.eval(); }, - DOC(kp, Sequence, eval)) - .def("eval", [](kp::Sequence& self, std::shared_ptr op) { return self.eval(op); }, - DOC(kp, Sequence, eval_2)) - .def("eval_async", [](kp::Sequence& self) { return self.eval(); }, - DOC(kp, Sequence, evalAwait)) - .def("eval_async", [](kp::Sequence& self, std::shared_ptr op) { return self.evalAsync(op); }, - DOC(kp, Sequence, evalAsync)) - .def("eval_await", [](kp::Sequence& self) { return self.evalAwait(); }, - DOC(kp, Sequence, evalAwait)) - .def("eval_await", [](kp::Sequence& self, uint32_t wait) { return self.evalAwait(wait); }, - DOC(kp, Sequence, evalAwait)) - .def("is_recording", &kp::Sequence::isRecording, - DOC(kp, Sequence, isRecording)) - .def("is_running", &kp::Sequence::isRunning, - DOC(kp, Sequence, isRunning)) - .def("is_init", &kp::Sequence::isInit, - DOC(kp, Sequence, isInit)) - .def("clear", &kp::Sequence::clear, - DOC(kp, Sequence, clear)) - .def("rerecord", &kp::Sequence::rerecord, - DOC(kp, Sequence, rerecord)) - .def("get_timestamps", &kp::Sequence::getTimestamps, - DOC(kp, Sequence, getTimestamps)) - .def("destroy", &kp::Sequence::destroy, - DOC(kp, Sequence, destroy)); + .def( + "record", + [](kp::Sequence& self, std::shared_ptr op) { + return self.record(op); + }, + DOC(kp, Sequence, record)) + .def( + "eval", + [](kp::Sequence& self) { return self.eval(); }, + DOC(kp, Sequence, eval)) + .def( + "eval", + [](kp::Sequence& self, std::shared_ptr op) { + return self.eval(op); + }, + DOC(kp, Sequence, eval_2)) + .def( + "eval_async", + [](kp::Sequence& self) { return self.eval(); }, + DOC(kp, Sequence, evalAwait)) + .def( + "eval_async", + [](kp::Sequence& self, std::shared_ptr op) { + return self.evalAsync(op); + }, + DOC(kp, Sequence, evalAsync)) + .def( + "eval_await", + [](kp::Sequence& self) { return self.evalAwait(); }, + DOC(kp, Sequence, evalAwait)) + .def( + "eval_await", + [](kp::Sequence& self, uint32_t wait) { return self.evalAwait(wait); }, + DOC(kp, Sequence, evalAwait)) + .def("is_recording", + &kp::Sequence::isRecording, + DOC(kp, Sequence, isRecording)) + .def("is_running", &kp::Sequence::isRunning, DOC(kp, Sequence, isRunning)) + .def("is_init", &kp::Sequence::isInit, DOC(kp, Sequence, isInit)) + .def("clear", &kp::Sequence::clear, DOC(kp, Sequence, clear)) + .def("rerecord", &kp::Sequence::rerecord, DOC(kp, Sequence, rerecord)) + .def("get_timestamps", + &kp::Sequence::getTimestamps, + DOC(kp, Sequence, getTimestamps)) + .def("destroy", &kp::Sequence::destroy, DOC(kp, Sequence, destroy)); - py::class_>(m, "Manager", DOC(kp, Manager)) - .def(py::init(), DOC(kp, Manager, Manager)) - .def(py::init(), DOC(kp, Manager, Manager_2)) - .def(py::init&,const std::vector&>(), - DOC(kp, Manager, Manager_2), - py::arg("device") = 0, - py::arg("family_queue_indices") = std::vector(), - py::arg("desired_extensions") = std::vector()) - .def("destroy", &kp::Manager::destroy, - DOC(kp, Manager, destroy)) - .def("sequence", &kp::Manager::sequence, DOC(kp, Manager, sequence), - py::arg("queue_index") = 0, py::arg("total_timestamps") = 0) - .def("tensor", [np](kp::Manager& self, - const py::array_t& data, - kp::Tensor::TensorTypes tensor_type) { - const py::array_t& flatdata = np.attr("ravel")(data); - const py::buffer_info info = flatdata.request(); - KP_LOG_DEBUG("Kompute Python Manager tensor() creating tensor float with data size {}", flatdata.size()); - return self.tensor( - info.ptr, - flatdata.size(), - sizeof(float), - kp::Tensor::TensorDataTypes::eFloat, - tensor_type); - }, - DOC(kp, Manager, tensor), - py::arg("data"), py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) - .def("tensor_t", [np](kp::Manager& self, - const py::array& data, - kp::Tensor::TensorTypes tensor_type) { - // TODO: Suppport strides in numpy format - const py::array& flatdata = np.attr("ravel")(data); - const py::buffer_info info = flatdata.request(); - KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with data size {} dtype {}", - flatdata.size(), std::string(py::str(flatdata.dtype()))); - if (flatdata.dtype() == py::dtype::of()) { - return self.tensor( - info.ptr, flatdata.size(), sizeof(float), kp::Tensor::TensorDataTypes::eFloat, tensor_type); - } else if (flatdata.dtype() == py::dtype::of()) { - return self.tensor( - info.ptr, flatdata.size(), sizeof(uint32_t), kp::Tensor::TensorDataTypes::eUnsignedInt, tensor_type); - } else if (flatdata.dtype() == py::dtype::of()) { - return self.tensor( - info.ptr, flatdata.size(), sizeof(int32_t), kp::Tensor::TensorDataTypes::eInt, tensor_type); - } else if (flatdata.dtype() == py::dtype::of()) { - return self.tensor( - info.ptr, flatdata.size(), sizeof(double), kp::Tensor::TensorDataTypes::eDouble, tensor_type); - } else if (flatdata.dtype() == py::dtype::of()) { - return self.tensor( - info.ptr, flatdata.size(), sizeof(bool), kp::Tensor::TensorDataTypes::eBool, tensor_type); - } else { - throw std::runtime_error("Kompute Python no valid dtype supported"); - } - }, - DOC(kp, Manager, tensorT), - py::arg("data"), py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) - .def("algorithm", [](kp::Manager& self, - const std::vector>& tensors, - const py::bytes& spirv, - const kp::Workgroup& workgroup, - const std::vector& spec_consts, - const std::vector& push_consts) { - py::buffer_info info(py::buffer(spirv).request()); - const char *data = reinterpret_cast(info.ptr); - size_t length = static_cast(info.size); - std::vector spirvVec((uint32_t*)data, (uint32_t*)(data + length)); - return self.algorithm(tensors, spirvVec, workgroup, spec_consts, push_consts); - }, - DOC(kp, Manager, algorithm), - py::arg("tensors"), - py::arg("spirv"), - py::arg("workgroup") = kp::Workgroup(), - py::arg("spec_consts") = std::vector(), - py::arg("push_consts") = std::vector()) - .def("algorithm", [np](kp::Manager& self, - const std::vector>& tensors, - const py::bytes& spirv, - const kp::Workgroup& workgroup, - const py::array& spec_consts, - const py::array& push_consts) { + py::class_>( + m, "Manager", DOC(kp, Manager)) + .def(py::init(), DOC(kp, Manager, Manager)) + .def(py::init(), DOC(kp, Manager, Manager_2)) + .def(py::init&, + const std::vector&>(), + DOC(kp, Manager, Manager_2), + py::arg("device") = 0, + py::arg("family_queue_indices") = std::vector(), + py::arg("desired_extensions") = std::vector()) + .def("destroy", &kp::Manager::destroy, DOC(kp, Manager, destroy)) + .def("sequence", + &kp::Manager::sequence, + DOC(kp, Manager, sequence), + py::arg("queue_index") = 0, + py::arg("total_timestamps") = 0) + .def( + "tensor", + [np](kp::Manager& self, + const py::array_t& data, + kp::Tensor::TensorTypes tensor_type) { + const py::array_t& flatdata = np.attr("ravel")(data); + const py::buffer_info info = flatdata.request(); + KP_LOG_DEBUG("Kompute Python Manager tensor() creating tensor " + "float with data size {}", + flatdata.size()); + return self.tensor(info.ptr, + flatdata.size(), + sizeof(float), + kp::Tensor::TensorDataTypes::eFloat, + tensor_type); + }, + DOC(kp, Manager, tensor), + py::arg("data"), + py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) + .def( + "tensor_t", + [np](kp::Manager& self, + const py::array& data, + kp::Tensor::TensorTypes tensor_type) { + // TODO: Suppport strides in numpy format + const py::array& flatdata = np.attr("ravel")(data); + const py::buffer_info info = flatdata.request(); + KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with data " + "size {} dtype {}", + flatdata.size(), + std::string(py::str(flatdata.dtype()))); + if (flatdata.dtype() == py::dtype::of()) { + return self.tensor(info.ptr, + flatdata.size(), + sizeof(float), + kp::Tensor::TensorDataTypes::eFloat, + tensor_type); + } else if (flatdata.dtype() == py::dtype::of()) { + return self.tensor(info.ptr, + flatdata.size(), + sizeof(uint32_t), + kp::Tensor::TensorDataTypes::eUnsignedInt, + tensor_type); + } else if (flatdata.dtype() == py::dtype::of()) { + return self.tensor(info.ptr, + flatdata.size(), + sizeof(int32_t), + kp::Tensor::TensorDataTypes::eInt, + tensor_type); + } else if (flatdata.dtype() == py::dtype::of()) { + return self.tensor(info.ptr, + flatdata.size(), + sizeof(double), + kp::Tensor::TensorDataTypes::eDouble, + tensor_type); + } else if (flatdata.dtype() == py::dtype::of()) { + return self.tensor(info.ptr, + flatdata.size(), + sizeof(bool), + kp::Tensor::TensorDataTypes::eBool, + tensor_type); + } else { + throw std::runtime_error( + "Kompute Python no valid dtype supported"); + } + }, + DOC(kp, Manager, tensorT), + py::arg("data"), + py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) + .def( + "algorithm", + [](kp::Manager& self, + const std::vector>& tensors, + const py::bytes& spirv, + const kp::Workgroup& workgroup, + const std::vector& spec_consts, + const std::vector& push_consts) { + py::buffer_info info(py::buffer(spirv).request()); + const char* data = reinterpret_cast(info.ptr); + size_t length = static_cast(info.size); + std::vector spirvVec((uint32_t*)data, + (uint32_t*)(data + length)); + return self.algorithm( + tensors, spirvVec, workgroup, spec_consts, push_consts); + }, + DOC(kp, Manager, algorithm), + py::arg("tensors"), + py::arg("spirv"), + py::arg("workgroup") = kp::Workgroup(), + py::arg("spec_consts") = std::vector(), + py::arg("push_consts") = std::vector()) + .def( + "algorithm", + [np](kp::Manager& self, + const std::vector>& tensors, + const py::bytes& spirv, + const kp::Workgroup& workgroup, + const py::array& spec_consts, + const py::array& push_consts) { + py::buffer_info info(py::buffer(spirv).request()); + const char* data = reinterpret_cast(info.ptr); + size_t length = static_cast(info.size); + std::vector spirvVec((uint32_t*)data, + (uint32_t*)(data + length)); - py::buffer_info info(py::buffer(spirv).request()); - const char *data = reinterpret_cast(info.ptr); - size_t length = static_cast(info.size); - std::vector spirvVec((uint32_t*)data, (uint32_t*)(data + length)); + const py::buffer_info pushInfo = push_consts.request(); + const py::buffer_info specInfo = spec_consts.request(); - const py::buffer_info pushInfo = push_consts.request(); - const py::buffer_info specInfo = spec_consts.request(); + KP_LOG_DEBUG("Kompute Python Manager creating Algorithm_T with " + "push consts data size {} dtype {} and spec const " + "data size {} dtype {}", + push_consts.size(), + std::string(py::str(push_consts.dtype())), + spec_consts.size(), + std::string(py::str(spec_consts.dtype()))); - KP_LOG_DEBUG("Kompute Python Manager creating Algorithm_T with " - "push consts data size {} dtype {} and spec const data size {} dtype {}", - push_consts.size(), std::string(py::str(push_consts.dtype())), - 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 + // We have to iterate across a combination of parameters due to the + // lack of support for templating + if (spec_consts.dtype() == py::dtype::of()) { + std::vector specConstsVec( + (float*)specInfo.ptr, ((float*)specInfo.ptr) + specInfo.size); if (spec_consts.dtype() == py::dtype::of()) { - std::vector specConstsVec((float*)specInfo.ptr, ((float*)specInfo.ptr) + specInfo.size); - if (spec_consts.dtype() == 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() == 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() == 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() == 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() == py::dtype::of()) { - std::vector specconstsvec((int32_t*)specInfo.ptr, ((int32_t*)specInfo.ptr) + specInfo.size); - if (spec_consts.dtype() == 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() == 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() == 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() == 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() == py::dtype::of()) { - std::vector specconstsvec((uint32_t*)specInfo.ptr, ((uint32_t*)specInfo.ptr) + specInfo.size); - if (spec_consts.dtype() == 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() == 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() == 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() == 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() == py::dtype::of()) { - std::vector specconstsvec((double*)specInfo.ptr, ((double*)specInfo.ptr) + specInfo.size); - if (spec_consts.dtype() == 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() == 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() == 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() == py::dtype::of()) { - std::vector pushconstsvec((double*)pushInfo.ptr, ((double*)pushInfo.ptr) + pushInfo.size); - return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); - } - } else { - // If reach then no valid dtype supported - throw std::runtime_error("Kompute Python no valid dtype supported"); + std::vector pushConstsVec((float*)pushInfo.ptr, + ((float*)pushInfo.ptr) + + pushInfo.size); + return self.algorithm(tensors, + spirvVec, + workgroup, + specConstsVec, + pushConstsVec); + } else if (spec_consts.dtype() == + 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() == + 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() == + py::dtype::of()) { + std::vector pushConstsVec((double*)pushInfo.ptr, + ((double*)pushInfo.ptr) + + pushInfo.size); + return self.algorithm(tensors, + spirvVec, + workgroup, + specConstsVec, + pushConstsVec); } - }, - DOC(kp, Manager, algorithm), - py::arg("tensors"), - py::arg("spirv"), - py::arg("workgroup") = kp::Workgroup(), - py::arg("spec_consts") = std::vector(), - py::arg("push_consts") = std::vector()) - .def("list_devices", [](kp::Manager& self){ + } else if (spec_consts.dtype() == py::dtype::of()) { + std::vector specconstsvec((int32_t*)specInfo.ptr, + ((int32_t*)specInfo.ptr) + + specInfo.size); + if (spec_consts.dtype() == 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() == + 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() == + 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() == + 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() == py::dtype::of()) { + std::vector specconstsvec((uint32_t*)specInfo.ptr, + ((uint32_t*)specInfo.ptr) + + specInfo.size); + if (spec_consts.dtype() == 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() == + 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() == + 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() == + 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() == py::dtype::of()) { + std::vector specconstsvec((double*)specInfo.ptr, + ((double*)specInfo.ptr) + + specInfo.size); + if (spec_consts.dtype() == 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() == + 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() == + 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() == + py::dtype::of()) { + std::vector pushconstsvec((double*)pushInfo.ptr, + ((double*)pushInfo.ptr) + + pushInfo.size); + return self.algorithm(tensors, + spirvVec, + workgroup, + specconstsvec, + pushconstsvec); + } + } else { + // If reach then no valid dtype supported + throw std::runtime_error( + "Kompute Python no valid dtype supported"); + } + }, + DOC(kp, Manager, algorithm), + py::arg("tensors"), + py::arg("spirv"), + py::arg("workgroup") = kp::Workgroup(), + py::arg("spec_consts") = std::vector(), + py::arg("push_consts") = std::vector()) + .def( + "list_devices", + [](kp::Manager& self) { const std::vector devices = self.listDevices(); py::list list; for (const vk::PhysicalDevice& device : devices) { list.append(kp::py::vkPropertiesToDict(device.getProperties())); } return list; - }, "Return a dict containing information about the device") - .def("get_device_properties", [](kp::Manager& self){ - const vk::PhysicalDeviceProperties properties = self.getDeviceProperties(); + }, + "Return a dict containing information about the device") + .def( + "get_device_properties", + [](kp::Manager& self) { + const vk::PhysicalDeviceProperties properties = + self.getDeviceProperties(); return kp::py::vkPropertiesToDict(properties); - }, "Return a dict containing information about the device"); + }, + "Return a dict containing information about the device"); auto atexit = py::module_::import("atexit"); - atexit.attr("register")(py::cpp_function([](){ + atexit.attr("register")(py::cpp_function([]() { kp_debug = py::none(); kp_info = py::none(); kp_warning = py::none(); @@ -340,4 +562,3 @@ PYBIND11_MODULE(kp, m) { m.attr("__version__") = "dev"; #endif } - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c312bde52..3ed805d14 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,24 +80,23 @@ endif() ##################################################### if(KOMPUTE_OPT_ANDROID_BUILD) - target_link_libraries(kompute PUBLIC fmt::fmt - kompute_vk_ndk_wrapper + target_link_libraries(kompute PUBLIC kompute_vk_ndk_wrapper + fmt::fmt log - android) + android + logger) else() target_link_libraries(kompute PUBLIC Vulkan::Vulkan - fmt::fmt) + fmt::fmt + logger) endif() if(KOMPUTE_OPT_USE_BUILD_IN_VULKAN_HEADER) target_link_libraries(kompute PUBLIC Vulkan-Headers) endif() -if(KOMPUTE_OPT_ENABLE_LOGGING) - target_link_libraries(kompute PUBLIC spdlog::spdlog) -endif() - ##################################################### # Misc ##################################################### +add_subdirectory(logger) add_subdirectory(include) diff --git a/src/Manager.cpp b/src/Manager.cpp index fd6e654e9..2e58d714a 100644 --- a/src/Manager.cpp +++ b/src/Manager.cpp @@ -6,8 +6,8 @@ #include #include "kompute/Manager.hpp" - -#include "fmt/ranges.h" +#include "kompute/logger/Logger.hpp" +#include "spdlog/common.h" namespace kp { @@ -40,6 +40,9 @@ Manager::Manager(uint32_t physicalDeviceIndex, { this->mManageResources = true; + // Make sure the logger is setup + logger::setupLogger(); + this->createInstance(); this->createDevice( familyQueueIndices, physicalDeviceIndex, desiredExtensions); @@ -54,6 +57,9 @@ Manager::Manager(std::shared_ptr instance, this->mInstance = instance; this->mPhysicalDevice = physicalDevice; this->mDevice = device; + + // Make sure the logger is setup + logger::setupLogger(); } Manager::~Manager() @@ -311,8 +317,10 @@ Manager::createDevice(const std::vector& familyQueueIndices, this->mPhysicalDevice = std::make_shared(physicalDevice); +#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO vk::PhysicalDeviceProperties physicalDeviceProperties = physicalDevice.getProperties(); +#endif KP_LOG_INFO("Using physical device index {} found {}", physicalDeviceIndex, @@ -369,7 +377,7 @@ Manager::createDevice(const std::vector& familyQueueIndices, } KP_LOG_DEBUG("Kompute Manager desired extension layers {}", - desiredExtensions); + logger::vecToString(desiredExtensions)); std::vector deviceExtensions = this->mPhysicalDevice->enumerateDeviceExtensionProperties(); @@ -379,7 +387,7 @@ Manager::createDevice(const std::vector& familyQueueIndices, uniqueExtensionNames.insert(ext.extensionName); } KP_LOG_DEBUG("Kompute Manager available extensions {}", - uniqueExtensionNames); + logger::setToString(uniqueExtensionNames)); std::vector validExtensions; for (const std::string& ext : desiredExtensions) { if (uniqueExtensionNames.count(ext) != 0) { @@ -388,7 +396,7 @@ Manager::createDevice(const std::vector& familyQueueIndices, } if (desiredExtensions.size() != validExtensions.size()) { KP_LOG_ERROR("Kompute Manager not all extensions were added: {}", - validExtensions); + logger::vecToString(validExtensions)); } vk::DeviceCreateInfo deviceCreateInfo(vk::DeviceCreateFlags(), diff --git a/src/OpTensorCopy.cpp b/src/OpTensorCopy.cpp index 3180fa3cd..aae727533 100644 --- a/src/OpTensorCopy.cpp +++ b/src/OpTensorCopy.cpp @@ -1,6 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 #include "kompute/operations/OpTensorCopy.hpp" +#include "kompute/Tensor.hpp" namespace kp { @@ -21,8 +22,8 @@ OpTensorCopy::OpTensorCopy(const std::vector>& tensors) if (tensor->dataType() != dataType) { throw std::runtime_error(fmt::format( "Attempting to copy tensors of different types from {} to {}", - dataType, - tensor->dataType())); + Tensor::toString(dataType), + Tensor::toString(tensor->dataType()))); } if (tensor->size() != size) { throw std::runtime_error(fmt::format( diff --git a/src/Tensor.cpp b/src/Tensor.cpp index 4f5e866f9..ab62eb828 100644 --- a/src/Tensor.cpp +++ b/src/Tensor.cpp @@ -4,6 +4,40 @@ namespace kp { +std::string +Tensor::toString(Tensor::TensorDataTypes dt) +{ + switch (dt) { + case TensorDataTypes::eBool: + return "eBool"; + case TensorDataTypes::eInt: + return "eInt"; + case TensorDataTypes::eUnsignedInt: + return "eUnsignedInt"; + case TensorDataTypes::eFloat: + return "eFloat"; + case TensorDataTypes::eDouble: + return "eDouble"; + default: + return "unknown"; + } +} + +std::string +Tensor::toString(Tensor::TensorTypes dt) +{ + switch (dt) { + case TensorTypes::eDevice: + return "eDevice"; + case TensorTypes::eHost: + return "eHost"; + case TensorTypes::eStorage: + return "eStorage"; + default: + return "unknown"; + } +} + Tensor::Tensor(std::shared_ptr physicalDevice, std::shared_ptr device, void* data, @@ -14,7 +48,7 @@ Tensor::Tensor(std::shared_ptr physicalDevice, { KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}", elementTotalCount, - tensorType); + Tensor::toString(tensorType)); this->mPhysicalDevice = physicalDevice; this->mDevice = device; @@ -27,7 +61,7 @@ Tensor::Tensor(std::shared_ptr physicalDevice, Tensor::~Tensor() { KP_LOG_DEBUG("Kompute Tensor destructor started. Type: {}", - this->tensorType()); + Tensor::toString(this->tensorType())); if (this->mDevice) { this->destroy(); diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt index 9f75d06a0..6535a1222 100644 --- a/src/include/CMakeLists.txt +++ b/src/include/CMakeLists.txt @@ -1,5 +1,9 @@ cmake_minimum_required(VERSION 3.15) +##################################################### +# Kompute +##################################################### + target_include_directories(kompute PUBLIC $ $) @@ -22,6 +26,22 @@ target_sources(kompute PRIVATE kompute/shaders/shaderlogisticregression.hpp kompute/shaders/shaderopmult.hpp + + kompute/logger/Logger.hpp ) install(DIRECTORY kompute DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +##################################################### +# Logger +##################################################### + +target_include_directories(logger PUBLIC $ + $) + +target_sources(logger PRIVATE + # Header files (useful in IDEs) + kompute/logger/Logger.hpp +) + +install(DIRECTORY logger DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) \ No newline at end of file diff --git a/src/include/kompute/Algorithm.hpp b/src/include/kompute/Algorithm.hpp index bb6b9faa5..804a70900 100644 --- a/src/include/kompute/Algorithm.hpp +++ b/src/include/kompute/Algorithm.hpp @@ -4,6 +4,7 @@ #include "kompute/Core.hpp" #include "kompute/Tensor.hpp" +#include "logger/Logger.hpp" namespace kp { diff --git a/src/include/kompute/Core.hpp b/src/include/kompute/Core.hpp index 2c49f29ef..65936460d 100644 --- a/src/include/kompute/Core.hpp +++ b/src/include/kompute/Core.hpp @@ -2,15 +2,11 @@ #pragma once #if VK_USE_PLATFORM_ANDROID_KHR -#include #include // VK_NO_PROTOTYPES required before vulkan import but after wrapper.hpp #undef VK_NO_PROTOTYPES -static const char* KOMPUTE_LOG_TAG = "KomputeLog"; #endif -#include - #include // Typedefs to simplify interaction with core types @@ -32,124 +28,9 @@ typedef std::vector Constants; KOMPUTE_VK_API_MAJOR_VERSION, KOMPUTE_VK_API_MINOR_VERSION, 0) #endif // KOMPUTE_VK_API_VERSION -// Defining kompute log levels analogous to spdlog log levels -#define KOMPUTE_LOG_LEVEL_TRACE 0 -#define KOMPUTE_LOG_LEVEL_DEBUG 1 -#define KOMPUTE_LOG_LEVEL_INFO 2 -#define KOMPUTE_LOG_LEVEL_WARN 3 -#define KOMPUTE_LOG_LEVEL_ERROR 4 -#define KOMPUTE_LOG_LEVEL_CRITICAL 5 -#define KOMPUTE_LOG_LEVEL_OFF 6 - -#ifndef KOMPUTE_LOG_LEVEL -#if DEBUG -#define KOMPUTE_LOG_LEVEL KOMPUTE_LOG_LEVEL_DEBUG -#else -#define KOMPUTE_LOG_LEVEL KOMPUTE_LOG_LEVEL_INFO -#endif -#endif // KOMPUTE_LOG_LEVEL - -// SPDLOG_ACTIVE_LEVEL must be defined before spdlog.h import -// It is recommended that it's set via KOMPUTE_LOG_LEVEL -// but if required it can be set directly as override -#ifndef SPDLOG_ACTIVE_LEVEL -#define SPDLOG_ACTIVE_LEVEL KOMPUTE_LOG_LEVEL -#endif - #if defined(KOMPUTE_BUILD_PYTHON) #include namespace py = pybind11; // from python/src/main.cpp extern py::object kp_debug, kp_info, kp_warning, kp_error; #endif - -#ifndef KOMPUTE_LOG_OVERRIDE -#if KOMPUTE_ENABLE_SPDLOG -#include -#define KP_LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__) -#define KP_LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__) -#define KP_LOG_WARN(...) SPDLOG_WARN(__VA_ARGS__) -#define KP_LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__) -#else -#include -#if KOMPUTE_LOG_LEVEL > 1 -#define KP_LOG_DEBUG(...) -#else -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -#define KP_LOG_DEBUG(...) \ - ((void)__android_log_write( \ - ANDROID_LOG_DEBUG, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__).c_str())) -#elif defined(KOMPUTE_BUILD_PYTHON) -#define KP_LOG_DEBUG(...) kp_debug(fmt::format(__VA_ARGS__)) -#else -#define KP_LOG_DEBUG(...) \ - fmt::print("[{} {}] [debug] [{}:{}] {}\n", \ - __DATE__, \ - __TIME__, \ - __FILE__, \ - __LINE__, \ - fmt::format(__VA_ARGS__)) -#endif // VK_USE_PLATFORM_ANDROID_KHR -#endif // KOMPUTE_LOG_LEVEL > 1 - -#if KOMPUTE_LOG_LEVEL > 2 -#define KP_LOG_INFO(...) -#else -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -#define KP_LOG_INFO(...) \ - ((void)__android_log_write( \ - ANDROID_LOG_INFO, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__).c_str())) -#elif defined(KOMPUTE_BUILD_PYTHON) -#define KP_LOG_INFO(...) kp_info(fmt::format(__VA_ARGS__)) -#else -#define KP_LOG_INFO(...) \ - fmt::print("[{} {}] [debug] [{}:{}] {}\n", \ - __DATE__, \ - __TIME__, \ - __FILE__, \ - __LINE__, \ - fmt::format(__VA_ARGS__)) -#endif // VK_USE_PLATFORM_ANDROID_KHR -#endif // KOMPUTE_LOG_LEVEL > 2 - -#if KOMPUTE_LOG_LEVEL > 3 -#define KP_LOG_WARN(...) -#else -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -#define KP_LOG_WARN(...) \ - ((void)__android_log_write( \ - ANDROID_LOG_WARN, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__).c_str())) -#elif defined(KOMPUTE_BUILD_PYTHON) -#define KP_LOG_WARN(...) kp_warning(fmt::format(__VA_ARGS__)) -#else -#define KP_LOG_WARN(...) \ - fmt::print("[{} {}] [debug] [{}:{}] {}\n", \ - __DATE__, \ - __TIME__, \ - __FILE__, \ - __LINE__, \ - fmt::format(__VA_ARGS__)) -#endif // VK_USE_PLATFORM_ANDROID_KHR -#endif // KOMPUTE_LOG_LEVEL > 3 - -#if KOMPUTE_LOG_LEVEL > 4 -#define KP_LOG_ERROR(...) -#else -#if defined(VK_USE_PLATFORM_ANDROID_KHR) -#define KP_LOG_ERROR(...) \ - ((void)__android_log_write( \ - ANDROID_LOG_ERROR, KOMPUTE_LOG_TAG, fmt::format(__VA_ARGS__).c_str())) -#elif defined(KOMPUTE_BUILD_PYTHON) -#define KP_LOG_ERROR(...) kp_error(fmt::format(__VA_ARGS__)) -#else -#define KP_LOG_ERROR(...) \ - fmt::print("[{} {}] [debug] [{}:{}] {}\n", \ - __DATE__, \ - __TIME__, \ - __FILE__, \ - __LINE__, \ - fmt::format(__VA_ARGS__)) -#endif // VK_USE_PLATFORM_ANDROID_KHR -#endif // KOMPUTE_LOG_LEVEL > 4 -#endif // KOMPUTE_SPDLOG_ENABLED -#endif // KOMPUTE_LOG_OVERRIDE diff --git a/src/include/kompute/Manager.hpp b/src/include/kompute/Manager.hpp index 5ff325225..53261c06d 100644 --- a/src/include/kompute/Manager.hpp +++ b/src/include/kompute/Manager.hpp @@ -7,6 +7,7 @@ #include "kompute/Core.hpp" #include "kompute/Sequence.hpp" +#include "logger/Logger.hpp" #define KP_DEFAULT_SESSION "DEFAULT" diff --git a/src/include/kompute/Tensor.hpp b/src/include/kompute/Tensor.hpp index 05c402ac4..948a55130 100644 --- a/src/include/kompute/Tensor.hpp +++ b/src/include/kompute/Tensor.hpp @@ -1,10 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once -#include "kompute/Core.hpp" -#include #include +#include "kompute/Core.hpp" + +#include "logger/Logger.hpp" + namespace kp { /** @@ -39,6 +41,9 @@ class Tensor eDouble = 4, }; + static std::string toString(TensorDataTypes dt); + static std::string toString(TensorTypes dt); + /** * Constructor with data provided which would be used to create the * respective vulkan buffer and memory. @@ -341,59 +346,3 @@ class TensorT : public Tensor }; } // End namespace kp - -/** - * fmt fromater for kp::Tensor::TensorDataTypes. - */ -template<> -struct fmt::formatter : formatter -{ - template - auto format(kp::Tensor::TensorDataTypes dt, FormatContext& ctx) - { - std::string name = "unknown"; - switch (dt) { - case kp::Tensor::TensorDataTypes::eBool: - name = "eBool"; - break; - case kp::Tensor::TensorDataTypes::eDouble: - name = "eDouble"; - break; - case kp::Tensor::TensorDataTypes::eFloat: - name = "eFloat"; - break; - case kp::Tensor::TensorDataTypes::eInt: - name = "eInt"; - break; - case kp::Tensor::TensorDataTypes::eUnsignedInt: - name = "eUnsignedInt"; - break; - } - return formatter::format(name, ctx); - } -}; - -/** - * fmt fromater for kp::Tensor::TensorTypes. - */ -template<> -struct fmt::formatter : formatter -{ - template - auto format(kp::Tensor::TensorTypes dt, FormatContext& ctx) - { - std::string name = "unknown"; - switch (dt) { - case kp::Tensor::TensorTypes::eDevice: - name = "eDevice"; - break; - case kp::Tensor::TensorTypes::eHost: - name = "eHost"; - break; - case kp::Tensor::TensorTypes::eStorage: - name = "eStorage"; - break; - } - return formatter::format(name, ctx); - } -}; diff --git a/src/include/kompute/logger/Logger.hpp b/src/include/kompute/logger/Logger.hpp new file mode 100644 index 000000000..92b2872c5 --- /dev/null +++ b/src/include/kompute/logger/Logger.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include +#include + +#define KP_LOG_TRACE(...) SPDLOG_TRACE(__VA_ARGS__) +#define KP_LOG_DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__) +#define KP_LOG_INFO(...) SPDLOG_INFO(__VA_ARGS__) +#define KP_LOG_WARN(...) SPDLOG_WARN(__VA_ARGS__) +#define KP_LOG_ERROR(...) SPDLOG_ERROR(__VA_ARGS__) + +namespace logger { +const std::string logFolder("kompute_logs"); +// Setup the logger, note the loglevel can not be set below the CMake log level +// (To change this use -DKOMPUTE_OPT_LOG_LEVEL=...) +void +setupLogger(); +void +setLogLevel(spdlog::level::level_enum level); +void +deactivateLogger(); + +spdlog::level::level_enum +getLogLevel(); + +std::string +setToString(const std::set& set); + +std::string +vecToString(const std::vector& vec); + +std::string +vecToString(const std::vector& vec); +} // namespace logger diff --git a/src/logger/CMakeLists.txt b/src/logger/CMakeLists.txt new file mode 100644 index 000000000..02c50f612 --- /dev/null +++ b/src/logger/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16) + +set(LOGGER_SOURCES Logger.cpp) + +add_library(logger ${LOGGER_SOURCES}) +target_link_libraries(logger PUBLIC spdlog::spdlog) + +if(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Trace") + set (KOMPUTE_OPT_LOG_LEVEL TRACE) + message(STATUS "Using log level Trace") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Debug") + set (KOMPUTE_OPT_LOG_LEVEL DEBUG) + message(STATUS "Using log level Debug") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Info") + set (KOMPUTE_OPT_LOG_LEVEL INFO) + message(STATUS "Using log level Info") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Warn") + set (KOMPUTE_OPT_LOG_LEVEL WARN) + message(STATUS "Using log level Warn") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Error") + set (KOMPUTE_OPT_LOG_LEVEL ERROR) + message(STATUS "Using log level Error") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL "Critical") + set (KOMPUTE_OPT_LOG_LEVEL CRITICAL) + message(STATUS "Using log level Critical") +elseif(${KOMPUTE_OPT_LOG_LEVEL} STREQUAL Off) + set (KOMPUTE_OPT_LOG_LEVEL OFF) + message(STATUS "Using log level Off") +else() + if((NOT ${KOMPUTE_OPT_LOG_LEVEL} STREQUAL Default) AND (NOT KOMPUTE_OPT_LOG_LEVEL STREQUAL "")) + message(WARNING "Log level '${KOMPUTE_OPT_LOG_LEVEL}' unknown, use -DKOMPUTE_OPT_LOG_LEVEL=[Trace, Debug, Info, Warn, Error, Critical, Off]") + endif() + set (KOMPUTE_OPT_LOG_LEVEL $,DEBUG,INFO>) + message(STATUS "Setting KOMPUTE_OPT_LOG_LEVEL to according to build type") +endif() + +target_compile_definitions(logger INTERFACE SPDLOG_ACTIVE_LEVEL=SPDLOG_LEVEL_${KOMPUTE_OPT_LOG_LEVEL}) diff --git a/src/logger/Logger.cpp b/src/logger/Logger.cpp new file mode 100644 index 000000000..698ead8e5 --- /dev/null +++ b/src/logger/Logger.cpp @@ -0,0 +1,192 @@ +#include "kompute/logger/Logger.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef _WIN32 +#include +#endif // _WIN32 + +namespace logger { +constexpr int THREAD_QUEUE_LENGTH = 8192; +constexpr int FILE_ROTATION_TIME = 1048576 * 5; + +/** + * Should be replaced with: + * std::filesystem::exists(path) + * when switching to cpp17 + **/ +bool +exists(const std::string& path) +{ + struct stat info + {}; + if (stat(path.c_str(), &info) != 0) { + // std::cerr << "Failed to check if '" << path + // << "' exists. Cannot access!\n"; + // assert(false); + return false; + } + return info.st_mode & S_IFDIR; +} + +/** + * Based on: https://stackoverflow.com/a/35109823 + * Should be replaced with: + * std::filesystem::create_directory(path); + * when switching to cpp17 + **/ +void +createDir(const std::string& path) +{ + mode_t nMode = 0733; // UNIX style permissions + int nError = 0; +#if defined(_WIN32) + nError = _mkdir(sPath.c_str()); // can be used on Windows +#else + nError = mkdir(path.c_str(), nMode); // can be used on non-Windows +#endif + if (nError != 0) { + std::cerr << "Failed to create '" << path << "' with: " << nError + << '\n'; + assert(false); + } +} + +void +setupLogger() +{ + // Ensure we setup the logger only once + static bool setup = false; + static std::mutex setupMutex{}; + setupMutex.lock(); + if (setup) { + setupMutex.unlock(); + return; + } + setup = true; + setupMutex.unlock(); + + if (!exists(logger::logFolder)) { + createDir(logger::logFolder); + } + spdlog::init_thread_pool(THREAD_QUEUE_LENGTH, 1); + spdlog::sink_ptr console_sink = + std::make_shared(); + console_sink->set_pattern("[%H:%M:%S %z] [%=8l] [thread %t] [%@]\t%v"); +#ifdef _WIN32 + std::string s = (logger::log_folder / "kompute.log").string(); + spdlog::sink_ptr file_sink = + std::make_shared( + s, FILE_ROTATION_TIME, 3); +#else // _WIN32 + spdlog::sink_ptr file_sink = + std::make_shared( + logger::logFolder + "/kompute.log", FILE_ROTATION_TIME, 3); +#endif + file_sink->set_pattern("[%H:%M:%S %z] [%=8l] [thread %t] [%@]\t%v"); + std::vector sinks{ file_sink, console_sink }; + std::shared_ptr logger = + std::make_shared( + "", + sinks.begin(), + sinks.end(), + spdlog::thread_pool(), + spdlog::async_overflow_policy::block); + + logger->set_level(getLogLevel()); + spdlog::set_default_logger(logger); +} + +spdlog::level::level_enum +getLogLevel() +{ +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_TRACE + return spdlog::level::trace; +#endif + +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_DEBUG + return spdlog::level::debug; +#endif + +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_INFO + return spdlog::level::info; +#endif + +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_WARN + return spdlog::level::warn; +#endif + +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_ERROR + return spdlog::level::error; +#endif + +#if SPDLOG_ACTIVE_LEVEL == SPDLOG_LEVEL_CRITICAL + return spdlog::level::critical; +#endif + + return spdlog::level::off; +} + +void +setLogLevel(const spdlog::level::level_enum level) +{ + spdlog::default_logger()->set_level(level); +} + +void +deactivateLogger() +{ + logger::setLogLevel(spdlog::level::off); +} + +std::string +setToString(const std::set& set) +{ + std::string result; + for (const std::string& entry : set) { + result += entry + ", "; + } + if (result.empty()) { + return result; + } + return result.substr(0, result.size() - 2); // Remove the tailing ", " +} + +std::string +vecToString(const std::vector& vec) +{ + std::string result; + for (const char* entry : vec) { + result += std::string(entry) + ", "; + } + if (result.empty()) { + return result; + } + return result.substr(0, result.size() - 2); // Remove the tailing ", " +} + +std::string +vecToString(const std::vector& vec) +{ + std::string result; + for (const std::string& entry : vec) { + result += entry + ", "; + } + if (result.empty()) { + return result; + } + return result.substr(0, result.size() - 2); // Remove the tailing ", " +} +} // namespace logger diff --git a/test/TestPushConstant.cpp b/test/TestPushConstant.cpp index a78224fc0..777ac95ec 100644 --- a/test/TestPushConstant.cpp +++ b/test/TestPushConstant.cpp @@ -6,8 +6,6 @@ #include "shaders/Utils.hpp" -#include "fmt/ranges.h" - TEST(TestPushConstants, TestConstantsAlgoDispatchOverride) { {