New logging framework

Signed-off-by: Fabian Sauter <sauter.fabian@mailbox.org>
This commit is contained in:
Fabian Sauter 2022-05-20 16:12:18 +02:00
parent 2fe219ee3a
commit f01bcb68a5
15 changed files with 848 additions and 480 deletions

View file

@ -74,8 +74,7 @@ kompute_option(KOMPUTE_OPT_INSTALL "Enable if you want to enable installation" O
# Build options # Build options
kompute_option(KOMPUTE_OPT_BUILD_PYTHON "Enable if you want to build python bindings" OFF) 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." "Off")
kompute_log_level(KOMPUTE_OPT_LOG_LEVEL "Internally we use spdlog for logging. The log level used can be changed here." "Debug")
kompute_option(KOMPUTE_OPT_ANDROID_BUILD "Enable android compilation flags required" 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_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) 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() endif()
# Spdlog # Spdlog
if(KOMPUTE_OPT_ENABLE_LOGGING) if(KOMPUTE_OPT_USE_BUILD_IN_SPDLOG)
if(KOMPUTE_OPT_ENABLE_SPDLOG) set(SPDLOG_INSTALL ${KOMPUTE_OPT_INSTALL})
if(KOMPUTE_OPT_USE_BUILD_IN_SPDLOG) set(SPDLOG_BUILD_SHARED ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS})
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 FetchContent_Declare(spdlog GIT_REPOSITORY https://github.com/gabime/spdlog.git
GIT_TAG v1.10.0) # Source: https://github.com/gabime/spdlog/releases GIT_TAG v1.10.0) # Source: https://github.com/gabime/spdlog/releases
FetchContent_MakeAvailable(spdlog) FetchContent_MakeAvailable(spdlog)
else() else()
find_package(spdlog REQUIRED) find_package(spdlog REQUIRED)
endif()
endif()
endif() endif()
# fmt # fmt
if(KOMPUTE_OPT_USE_BUILD_IN_FMT) if(KOMPUTE_OPT_USE_BUILD_IN_FMT)
set(FMT_INSTALL ${KOMPUTE_OPT_INSTALL}) set(FMT_INSTALL ${KOMPUTE_OPT_INSTALL})
set(BUILD_SHARED_LIBS_BKP ${KOMPUTE_OPT_DEPENDENCIES_SHARED_LIBS}) 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 FetchContent_Declare(fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 8.1.1) # Source: https://github.com/fmtlib/fmt/releases GIT_TAG 8.1.1) # Source: https://github.com/fmtlib/fmt/releases
FetchContent_MakeAvailable(fmt) FetchContent_MakeAvailable(fmt)
@ -200,10 +194,6 @@ if(KOMPUTE_OPT_DISABLE_VK_DEBUG_LAYERS)
add_compile_definitions(KOMPUTE_DISABLE_VK_DEBUG_LAYERS=1) add_compile_definitions(KOMPUTE_DISABLE_VK_DEBUG_LAYERS=1)
endif() endif()
if(KOMPUTE_OPT_ENABLE_LOGGING)
add_compile_definitions(KOMPUTE_OPT_ENABLE_LOGGING=1)
endif()
##################################################### #####################################################
# Misc Options # Misc Options
##################################################### #####################################################

View file

@ -1,333 +1,555 @@
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/numpy.h>
#include <kompute/Kompute.hpp> #include <kompute/Kompute.hpp>
#include "fmt/ranges.h"
#include "utils.hpp"
#include "docstrings.hpp" #include "docstrings.hpp"
#include "utils.hpp"
namespace py = pybind11; namespace py = pybind11;
//used in Core.hpp // used in Core.hpp
py::object kp_debug, kp_info, kp_warning, kp_error; py::object kp_debug, kp_info, kp_warning, kp_error;
std::unique_ptr<kp::OpAlgoDispatch> opAlgoDispatchPyInit( std::unique_ptr<kp::OpAlgoDispatch>
std::shared_ptr<kp::Algorithm>& algorithm, opAlgoDispatchPyInit(std::shared_ptr<kp::Algorithm>& algorithm,
const py::array& push_consts) { 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 {}", const py::buffer_info info = push_consts.request();
push_consts.size(), std::string(py::str(push_consts.dtype()))); 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::float_t>()) { if (push_consts.dtype() == py::dtype::of<std::float_t>()) {
std::vector<float> dataVec((float*)info.ptr, ((float*)info.ptr) + info.size); std::vector<float> dataVec((float*)info.ptr,
return std::unique_ptr<kp::OpAlgoDispatch>{new kp::OpAlgoDispatch(algorithm, dataVec)}; ((float*)info.ptr) + info.size);
return std::unique_ptr<kp::OpAlgoDispatch>{ new kp::OpAlgoDispatch(
algorithm, dataVec) };
} else if (push_consts.dtype() == py::dtype::of<std::uint32_t>()) { } else if (push_consts.dtype() == py::dtype::of<std::uint32_t>()) {
std::vector<uint32_t> dataVec((uint32_t*)info.ptr, ((uint32_t*)info.ptr) + info.size); std::vector<uint32_t> dataVec((uint32_t*)info.ptr,
return std::unique_ptr<kp::OpAlgoDispatch>{new kp::OpAlgoDispatch(algorithm, dataVec)}; ((uint32_t*)info.ptr) + info.size);
return std::unique_ptr<kp::OpAlgoDispatch>{ new kp::OpAlgoDispatch(
algorithm, dataVec) };
} else if (push_consts.dtype() == py::dtype::of<std::int32_t>()) { } else if (push_consts.dtype() == py::dtype::of<std::int32_t>()) {
std::vector<int32_t> dataVec((int32_t*)info.ptr, ((int32_t*)info.ptr) + info.size); std::vector<int32_t> dataVec((int32_t*)info.ptr,
return std::unique_ptr<kp::OpAlgoDispatch>{new kp::OpAlgoDispatch(algorithm, dataVec)}; ((int32_t*)info.ptr) + info.size);
return std::unique_ptr<kp::OpAlgoDispatch>{ new kp::OpAlgoDispatch(
algorithm, dataVec) };
} else if (push_consts.dtype() == py::dtype::of<std::double_t>()) { } else if (push_consts.dtype() == py::dtype::of<std::double_t>()) {
std::vector<double> dataVec((double*)info.ptr, ((double*)info.ptr) + info.size); std::vector<double> dataVec((double*)info.ptr,
return std::unique_ptr<kp::OpAlgoDispatch>{new kp::OpAlgoDispatch(algorithm, dataVec)}; ((double*)info.ptr) + info.size);
return std::unique_ptr<kp::OpAlgoDispatch>{ new kp::OpAlgoDispatch(
algorithm, dataVec) };
} else { } else {
throw std::runtime_error("Kompute Python no valid dtype supported"); 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 // 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"); py::object kp_logger = logging.attr("getLogger")("kp");
kp_debug = kp_logger.attr("debug"); kp_debug = kp_logger.attr("debug");
kp_info = kp_logger.attr("info"); kp_info = kp_logger.attr("info");
kp_warning = kp_logger.attr("warning"); kp_warning = kp_logger.attr("warning");
kp_error = kp_logger.attr("error"); kp_error = kp_logger.attr("error");
logging.attr("basicConfig")(); logging.attr("basicConfig")();
py::module_ np = py::module_::import("numpy"); py::module_ np = py::module_::import("numpy");
py::enum_<kp::Tensor::TensorTypes>(m, "TensorTypes") py::enum_<kp::Tensor::TensorTypes>(m, "TensorTypes")
.value("device", kp::Tensor::TensorTypes::eDevice, DOC(kp, Tensor, TensorTypes, eDevice)) .value("device",
.value("host", kp::Tensor::TensorTypes::eHost, DOC(kp, Tensor, TensorTypes, eHost)) kp::Tensor::TensorTypes::eDevice,
.value("storage", kp::Tensor::TensorTypes::eStorage, DOC(kp, Tensor, TensorTypes, eStorage)) DOC(kp, Tensor, TensorTypes, eDevice))
.export_values(); .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_<kp::OpBase, std::shared_ptr<kp::OpBase>>(m, "OpBase", DOC(kp, OpBase)); py::class_<kp::OpBase, std::shared_ptr<kp::OpBase>>(
m, "OpBase", DOC(kp, OpBase));
py::class_<kp::OpTensorSyncDevice, std::shared_ptr<kp::OpTensorSyncDevice>>( py::class_<kp::OpTensorSyncDevice, std::shared_ptr<kp::OpTensorSyncDevice>>(
m, "OpTensorSyncDevice", py::base<kp::OpBase>(), DOC(kp, OpTensorSyncDevice)) m,
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(), DOC(kp, OpTensorSyncDevice, OpTensorSyncDevice)); "OpTensorSyncDevice",
py::base<kp::OpBase>(),
DOC(kp, OpTensorSyncDevice))
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(),
DOC(kp, OpTensorSyncDevice, OpTensorSyncDevice));
py::class_<kp::OpTensorSyncLocal, std::shared_ptr<kp::OpTensorSyncLocal>>( py::class_<kp::OpTensorSyncLocal, std::shared_ptr<kp::OpTensorSyncLocal>>(
m, "OpTensorSyncLocal", py::base<kp::OpBase>(), DOC(kp, OpTensorSyncLocal)) m,
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(), DOC(kp, OpTensorSyncLocal, OpTensorSyncLocal)); "OpTensorSyncLocal",
py::base<kp::OpBase>(),
DOC(kp, OpTensorSyncLocal))
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(),
DOC(kp, OpTensorSyncLocal, OpTensorSyncLocal));
py::class_<kp::OpTensorCopy, std::shared_ptr<kp::OpTensorCopy>>( py::class_<kp::OpTensorCopy, std::shared_ptr<kp::OpTensorCopy>>(
m, "OpTensorCopy", py::base<kp::OpBase>(), DOC(kp, OpTensorCopy)) m, "OpTensorCopy", py::base<kp::OpBase>(), DOC(kp, OpTensorCopy))
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(), DOC(kp, OpTensorCopy, OpTensorCopy)); .def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&>(),
DOC(kp, OpTensorCopy, OpTensorCopy));
py::class_<kp::OpAlgoDispatch, std::shared_ptr<kp::OpAlgoDispatch>>( py::class_<kp::OpAlgoDispatch, std::shared_ptr<kp::OpAlgoDispatch>>(
m, "OpAlgoDispatch", py::base<kp::OpBase>(), DOC(kp, OpAlgoDispatch)) m, "OpAlgoDispatch", py::base<kp::OpBase>(), DOC(kp, OpAlgoDispatch))
.def(py::init<const std::shared_ptr<kp::Algorithm>&,const std::vector<float>&>(), .def(py::init<const std::shared_ptr<kp::Algorithm>&,
DOC(kp, OpAlgoDispatch, OpAlgoDispatch), const std::vector<float>&>(),
py::arg("algorithm"), py::arg("push_consts") = std::vector<float>()) DOC(kp, OpAlgoDispatch, OpAlgoDispatch),
.def(py::init(&opAlgoDispatchPyInit), py::arg("algorithm"),
DOC(kp, OpAlgoDispatch, OpAlgoDispatch), py::arg("push_consts") = std::vector<float>())
py::arg("algorithm"), py::arg("push_consts")); .def(py::init(&opAlgoDispatchPyInit),
DOC(kp, OpAlgoDispatch, OpAlgoDispatch),
py::arg("algorithm"),
py::arg("push_consts"));
py::class_<kp::OpMult, std::shared_ptr<kp::OpMult>>( py::class_<kp::OpMult, std::shared_ptr<kp::OpMult>>(
m, "OpMult", py::base<kp::OpBase>(), DOC(kp, OpMult)) m, "OpMult", py::base<kp::OpBase>(), DOC(kp, OpMult))
.def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&,const std::shared_ptr<kp::Algorithm>&>(), .def(py::init<const std::vector<std::shared_ptr<kp::Tensor>>&,
DOC(kp, OpMult, OpMult)); const std::shared_ptr<kp::Algorithm>&>(),
DOC(kp, OpMult, OpMult));
py::class_<kp::Algorithm, std::shared_ptr<kp::Algorithm>>(m, "Algorithm", DOC(kp, Algorithm, Algorithm)) py::class_<kp::Algorithm, std::shared_ptr<kp::Algorithm>>(
.def("get_tensors", &kp::Algorithm::getTensors, DOC(kp, Algorithm, getTensors)) m, "Algorithm", DOC(kp, Algorithm, Algorithm))
.def("destroy", &kp::Algorithm::destroy, DOC(kp, Algorithm, destroy)) .def("get_tensors",
.def("is_init", &kp::Algorithm::isInit, DOC(kp, Algorithm, isInit)); &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_<kp::Tensor, std::shared_ptr<kp::Tensor>>(m, "Tensor", DOC(kp, Tensor)) py::class_<kp::Tensor, std::shared_ptr<kp::Tensor>>(
.def("data", [](kp::Tensor& self) { m, "Tensor", DOC(kp, Tensor))
// Non-owning container exposing the underlying pointer .def(
switch (self.dataType()) { "data",
[](kp::Tensor& self) {
// Non-owning container exposing the underlying pointer
switch (self.dataType()) {
case kp::Tensor::TensorDataTypes::eFloat: case kp::Tensor::TensorDataTypes::eFloat:
return py::array(self.size(), self.data<float>(), py::cast(&self)); return py::array(
self.size(), self.data<float>(), py::cast(&self));
case kp::Tensor::TensorDataTypes::eUnsignedInt: case kp::Tensor::TensorDataTypes::eUnsignedInt:
return py::array(self.size(), self.data<uint32_t>(), py::cast(&self)); return py::array(
self.size(), self.data<uint32_t>(), py::cast(&self));
case kp::Tensor::TensorDataTypes::eInt: case kp::Tensor::TensorDataTypes::eInt:
return py::array(self.size(), self.data<int32_t>(), py::cast(&self)); return py::array(
self.size(), self.data<int32_t>(), py::cast(&self));
case kp::Tensor::TensorDataTypes::eDouble: case kp::Tensor::TensorDataTypes::eDouble:
return py::array(self.size(), self.data<double>(), py::cast(&self)); return py::array(
self.size(), self.data<double>(), py::cast(&self));
case kp::Tensor::TensorDataTypes::eBool: case kp::Tensor::TensorDataTypes::eBool:
return py::array(self.size(), self.data<bool>(), py::cast(&self)); return py::array(
self.size(), self.data<bool>(), py::cast(&self));
default: default:
throw std::runtime_error("Kompute Python data type not supported"); 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)) DOC(kp, Tensor, data))
.def("tensor_type", &kp::Tensor::tensorType, DOC(kp, Tensor, tensorType)) .def("size", &kp::Tensor::size, DOC(kp, Tensor, size))
.def("data_type", &kp::Tensor::dataType, DOC(kp, Tensor, dataType)) .def("__len__", &kp::Tensor::size, DOC(kp, Tensor, size))
.def("is_init", &kp::Tensor::isInit, DOC(kp, Tensor, isInit)) .def("tensor_type", &kp::Tensor::tensorType, DOC(kp, Tensor, tensorType))
.def("destroy", &kp::Tensor::destroy, DOC(kp, Tensor, destroy)); .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_<kp::Sequence, std::shared_ptr<kp::Sequence>>(m, "Sequence") py::class_<kp::Sequence, std::shared_ptr<kp::Sequence>>(m, "Sequence")
.def("record", [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) { return self.record(op); }, .def(
DOC(kp, Sequence, record)) "record",
.def("eval", [](kp::Sequence& self) { return self.eval(); }, [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) {
DOC(kp, Sequence, eval)) return self.record(op);
.def("eval", [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) { return self.eval(op); }, },
DOC(kp, Sequence, eval_2)) DOC(kp, Sequence, record))
.def("eval_async", [](kp::Sequence& self) { return self.eval(); }, .def(
DOC(kp, Sequence, evalAwait)) "eval",
.def("eval_async", [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) { return self.evalAsync(op); }, [](kp::Sequence& self) { return self.eval(); },
DOC(kp, Sequence, evalAsync)) DOC(kp, Sequence, eval))
.def("eval_await", [](kp::Sequence& self) { return self.evalAwait(); }, .def(
DOC(kp, Sequence, evalAwait)) "eval",
.def("eval_await", [](kp::Sequence& self, uint32_t wait) { return self.evalAwait(wait); }, [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) {
DOC(kp, Sequence, evalAwait)) return self.eval(op);
.def("is_recording", &kp::Sequence::isRecording, },
DOC(kp, Sequence, isRecording)) DOC(kp, Sequence, eval_2))
.def("is_running", &kp::Sequence::isRunning, .def(
DOC(kp, Sequence, isRunning)) "eval_async",
.def("is_init", &kp::Sequence::isInit, [](kp::Sequence& self) { return self.eval(); },
DOC(kp, Sequence, isInit)) DOC(kp, Sequence, evalAwait))
.def("clear", &kp::Sequence::clear, .def(
DOC(kp, Sequence, clear)) "eval_async",
.def("rerecord", &kp::Sequence::rerecord, [](kp::Sequence& self, std::shared_ptr<kp::OpBase> op) {
DOC(kp, Sequence, rerecord)) return self.evalAsync(op);
.def("get_timestamps", &kp::Sequence::getTimestamps, },
DOC(kp, Sequence, getTimestamps)) DOC(kp, Sequence, evalAsync))
.def("destroy", &kp::Sequence::destroy, .def(
DOC(kp, Sequence, destroy)); "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_<kp::Manager, std::shared_ptr<kp::Manager>>(m, "Manager", DOC(kp, Manager)) py::class_<kp::Manager, std::shared_ptr<kp::Manager>>(
.def(py::init(), DOC(kp, Manager, Manager)) m, "Manager", DOC(kp, Manager))
.def(py::init<uint32_t>(), DOC(kp, Manager, Manager_2)) .def(py::init(), DOC(kp, Manager, Manager))
.def(py::init<uint32_t,const std::vector<uint32_t>&,const std::vector<std::string>&>(), .def(py::init<uint32_t>(), DOC(kp, Manager, Manager_2))
DOC(kp, Manager, Manager_2), .def(py::init<uint32_t,
py::arg("device") = 0, const std::vector<uint32_t>&,
py::arg("family_queue_indices") = std::vector<uint32_t>(), const std::vector<std::string>&>(),
py::arg("desired_extensions") = std::vector<std::string>()) DOC(kp, Manager, Manager_2),
.def("destroy", &kp::Manager::destroy, py::arg("device") = 0,
DOC(kp, Manager, destroy)) py::arg("family_queue_indices") = std::vector<uint32_t>(),
.def("sequence", &kp::Manager::sequence, DOC(kp, Manager, sequence), py::arg("desired_extensions") = std::vector<std::string>())
py::arg("queue_index") = 0, py::arg("total_timestamps") = 0) .def("destroy", &kp::Manager::destroy, DOC(kp, Manager, destroy))
.def("tensor", [np](kp::Manager& self, .def("sequence",
const py::array_t<float>& data, &kp::Manager::sequence,
kp::Tensor::TensorTypes tensor_type) { DOC(kp, Manager, sequence),
const py::array_t<float>& flatdata = np.attr("ravel")(data); py::arg("queue_index") = 0,
const py::buffer_info info = flatdata.request(); py::arg("total_timestamps") = 0)
KP_LOG_DEBUG("Kompute Python Manager tensor() creating tensor float with data size {}", flatdata.size()); .def(
return self.tensor( "tensor",
info.ptr, [np](kp::Manager& self,
flatdata.size(), const py::array_t<float>& data,
sizeof(float), kp::Tensor::TensorTypes tensor_type) {
kp::Tensor::TensorDataTypes::eFloat, const py::array_t<float>& flatdata = np.attr("ravel")(data);
tensor_type); const py::buffer_info info = flatdata.request();
}, KP_LOG_DEBUG("Kompute Python Manager tensor() creating tensor "
DOC(kp, Manager, tensor), "float with data size {}",
py::arg("data"), py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) flatdata.size());
.def("tensor_t", [np](kp::Manager& self, return self.tensor(info.ptr,
const py::array& data, flatdata.size(),
kp::Tensor::TensorTypes tensor_type) { sizeof(float),
// TODO: Suppport strides in numpy format kp::Tensor::TensorDataTypes::eFloat,
const py::array& flatdata = np.attr("ravel")(data); tensor_type);
const py::buffer_info info = flatdata.request(); },
KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with data size {} dtype {}", DOC(kp, Manager, tensor),
flatdata.size(), std::string(py::str(flatdata.dtype()))); py::arg("data"),
if (flatdata.dtype() == py::dtype::of<std::float_t>()) { py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice)
return self.tensor( .def(
info.ptr, flatdata.size(), sizeof(float), kp::Tensor::TensorDataTypes::eFloat, tensor_type); "tensor_t",
} else if (flatdata.dtype() == py::dtype::of<std::uint32_t>()) { [np](kp::Manager& self,
return self.tensor( const py::array& data,
info.ptr, flatdata.size(), sizeof(uint32_t), kp::Tensor::TensorDataTypes::eUnsignedInt, tensor_type); kp::Tensor::TensorTypes tensor_type) {
} else if (flatdata.dtype() == py::dtype::of<std::int32_t>()) { // TODO: Suppport strides in numpy format
return self.tensor( const py::array& flatdata = np.attr("ravel")(data);
info.ptr, flatdata.size(), sizeof(int32_t), kp::Tensor::TensorDataTypes::eInt, tensor_type); const py::buffer_info info = flatdata.request();
} else if (flatdata.dtype() == py::dtype::of<std::double_t>()) { KP_LOG_DEBUG("Kompute Python Manager creating tensor_T with data "
return self.tensor( "size {} dtype {}",
info.ptr, flatdata.size(), sizeof(double), kp::Tensor::TensorDataTypes::eDouble, tensor_type); flatdata.size(),
} else if (flatdata.dtype() == py::dtype::of<bool>()) { std::string(py::str(flatdata.dtype())));
return self.tensor( if (flatdata.dtype() == py::dtype::of<std::float_t>()) {
info.ptr, flatdata.size(), sizeof(bool), kp::Tensor::TensorDataTypes::eBool, tensor_type); return self.tensor(info.ptr,
} else { flatdata.size(),
throw std::runtime_error("Kompute Python no valid dtype supported"); sizeof(float),
} kp::Tensor::TensorDataTypes::eFloat,
}, tensor_type);
DOC(kp, Manager, tensorT), } else if (flatdata.dtype() == py::dtype::of<std::uint32_t>()) {
py::arg("data"), py::arg("tensor_type") = kp::Tensor::TensorTypes::eDevice) return self.tensor(info.ptr,
.def("algorithm", [](kp::Manager& self, flatdata.size(),
const std::vector<std::shared_ptr<kp::Tensor>>& tensors, sizeof(uint32_t),
const py::bytes& spirv, kp::Tensor::TensorDataTypes::eUnsignedInt,
const kp::Workgroup& workgroup, tensor_type);
const std::vector<float>& spec_consts, } else if (flatdata.dtype() == py::dtype::of<std::int32_t>()) {
const std::vector<float>& push_consts) { return self.tensor(info.ptr,
py::buffer_info info(py::buffer(spirv).request()); flatdata.size(),
const char *data = reinterpret_cast<const char *>(info.ptr); sizeof(int32_t),
size_t length = static_cast<size_t>(info.size); kp::Tensor::TensorDataTypes::eInt,
std::vector<uint32_t> spirvVec((uint32_t*)data, (uint32_t*)(data + length)); tensor_type);
return self.algorithm(tensors, spirvVec, workgroup, spec_consts, push_consts); } else if (flatdata.dtype() == py::dtype::of<std::double_t>()) {
}, return self.tensor(info.ptr,
DOC(kp, Manager, algorithm), flatdata.size(),
py::arg("tensors"), sizeof(double),
py::arg("spirv"), kp::Tensor::TensorDataTypes::eDouble,
py::arg("workgroup") = kp::Workgroup(), tensor_type);
py::arg("spec_consts") = std::vector<float>(), } else if (flatdata.dtype() == py::dtype::of<bool>()) {
py::arg("push_consts") = std::vector<float>()) return self.tensor(info.ptr,
.def("algorithm", [np](kp::Manager& self, flatdata.size(),
const std::vector<std::shared_ptr<kp::Tensor>>& tensors, sizeof(bool),
const py::bytes& spirv, kp::Tensor::TensorDataTypes::eBool,
const kp::Workgroup& workgroup, tensor_type);
const py::array& spec_consts, } else {
const py::array& push_consts) { 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<std::shared_ptr<kp::Tensor>>& tensors,
const py::bytes& spirv,
const kp::Workgroup& workgroup,
const std::vector<float>& spec_consts,
const std::vector<float>& push_consts) {
py::buffer_info info(py::buffer(spirv).request());
const char* data = reinterpret_cast<const char*>(info.ptr);
size_t length = static_cast<size_t>(info.size);
std::vector<uint32_t> 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<float>(),
py::arg("push_consts") = std::vector<float>())
.def(
"algorithm",
[np](kp::Manager& self,
const std::vector<std::shared_ptr<kp::Tensor>>& 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<const char*>(info.ptr);
size_t length = static_cast<size_t>(info.size);
std::vector<uint32_t> spirvVec((uint32_t*)data,
(uint32_t*)(data + length));
py::buffer_info info(py::buffer(spirv).request()); const py::buffer_info pushInfo = push_consts.request();
const char *data = reinterpret_cast<const char *>(info.ptr); const py::buffer_info specInfo = spec_consts.request();
size_t length = static_cast<size_t>(info.size);
std::vector<uint32_t> spirvVec((uint32_t*)data, (uint32_t*)(data + length));
const py::buffer_info pushInfo = push_consts.request(); KP_LOG_DEBUG("Kompute Python Manager creating Algorithm_T with "
const py::buffer_info specInfo = spec_consts.request(); "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 " // We have to iterate across a combination of parameters due to the
"push consts data size {} dtype {} and spec const data size {} dtype {}", // lack of support for templating
push_consts.size(), std::string(py::str(push_consts.dtype())), if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
spec_consts.size(), std::string(py::str(spec_consts.dtype()))); std::vector<float> specConstsVec(
(float*)specInfo.ptr, ((float*)specInfo.ptr) + specInfo.size);
// 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::float_t>()) { if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
std::vector<float> specConstsVec((float*)specInfo.ptr, ((float*)specInfo.ptr) + specInfo.size); std::vector<float> pushConstsVec((float*)pushInfo.ptr,
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) { ((float*)pushInfo.ptr) +
std::vector<float> pushConstsVec((float*)pushInfo.ptr, ((float*)pushInfo.ptr) + pushInfo.size); pushInfo.size);
return self.algorithm(tensors, spirvVec, workgroup, specConstsVec, pushConstsVec); return self.algorithm(tensors,
} else if (spec_consts.dtype() == py::dtype::of<std::int32_t>()) { spirvVec,
std::vector<int32_t> pushConstsVec((int32_t*)pushInfo.ptr, ((int32_t*)pushInfo.ptr) + pushInfo.size); workgroup,
return self.algorithm(tensors, spirvVec, workgroup, specConstsVec, pushConstsVec); specConstsVec,
} else if (spec_consts.dtype() == py::dtype::of<std::uint32_t>()) { pushConstsVec);
std::vector<uint32_t> pushConstsVec((uint32_t*)pushInfo.ptr, ((uint32_t*)pushInfo.ptr) + pushInfo.size); } else if (spec_consts.dtype() ==
return self.algorithm(tensors, spirvVec, workgroup, specConstsVec, pushConstsVec); py::dtype::of<std::int32_t>()) {
} else if (spec_consts.dtype() == py::dtype::of<std::double_t>()) { std::vector<int32_t> pushConstsVec(
std::vector<double> pushConstsVec((double*)pushInfo.ptr, ((double*)pushInfo.ptr) + pushInfo.size); (int32_t*)pushInfo.ptr,
return self.algorithm(tensors, spirvVec, workgroup, specConstsVec, pushConstsVec); ((int32_t*)pushInfo.ptr) + pushInfo.size);
} return self.algorithm(tensors,
} else if (spec_consts.dtype() == py::dtype::of<std::int32_t>()) { spirvVec,
std::vector<int32_t> specconstsvec((int32_t*)specInfo.ptr, ((int32_t*)specInfo.ptr) + specInfo.size); workgroup,
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) { specConstsVec,
std::vector<float> pushconstsvec((float*)pushInfo.ptr, ((float*)pushInfo.ptr) + pushInfo.size); pushConstsVec);
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); } else if (spec_consts.dtype() ==
} else if (spec_consts.dtype() == py::dtype::of<std::int32_t>()) { py::dtype::of<std::uint32_t>()) {
std::vector<int32_t> pushconstsvec((int32_t*)pushInfo.ptr, ((int32_t*)pushInfo.ptr) + pushInfo.size); std::vector<uint32_t> pushConstsVec(
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); (uint32_t*)pushInfo.ptr,
} else if (spec_consts.dtype() == py::dtype::of<std::uint32_t>()) { ((uint32_t*)pushInfo.ptr) + pushInfo.size);
std::vector<uint32_t> pushconstsvec((uint32_t*)pushInfo.ptr, ((uint32_t*)pushInfo.ptr) + pushInfo.size); return self.algorithm(tensors,
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); spirvVec,
} else if (spec_consts.dtype() == py::dtype::of<std::double_t>()) { workgroup,
std::vector<double> pushconstsvec((double*)pushInfo.ptr, ((double*)pushInfo.ptr) + pushInfo.size); specConstsVec,
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); pushConstsVec);
} } else if (spec_consts.dtype() ==
} else if (spec_consts.dtype() == py::dtype::of<std::uint32_t>()) { py::dtype::of<std::double_t>()) {
std::vector<uint32_t> specconstsvec((uint32_t*)specInfo.ptr, ((uint32_t*)specInfo.ptr) + specInfo.size); std::vector<double> pushConstsVec((double*)pushInfo.ptr,
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) { ((double*)pushInfo.ptr) +
std::vector<float> pushconstsvec((float*)pushInfo.ptr, ((float*)pushInfo.ptr) + pushInfo.size); pushInfo.size);
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); return self.algorithm(tensors,
} else if (spec_consts.dtype() == py::dtype::of<std::int32_t>()) { spirvVec,
std::vector<int32_t> pushconstsvec((int32_t*)pushInfo.ptr, ((int32_t*)pushInfo.ptr) + pushInfo.size); workgroup,
return self.algorithm(tensors, spirvVec, workgroup, specconstsvec, pushconstsvec); specConstsVec,
} else if (spec_consts.dtype() == py::dtype::of<std::uint32_t>()) { pushConstsVec);
std::vector<uint32_t> 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::double_t>()) {
std::vector<double> 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::double_t>()) {
std::vector<double> specconstsvec((double*)specInfo.ptr, ((double*)specInfo.ptr) + specInfo.size);
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
std::vector<float> 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::int32_t>()) {
std::vector<float> 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::uint32_t>()) {
std::vector<float> 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::double_t>()) {
std::vector<float> 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");
} }
}, } else if (spec_consts.dtype() == py::dtype::of<std::int32_t>()) {
DOC(kp, Manager, algorithm), std::vector<int32_t> specconstsvec((int32_t*)specInfo.ptr,
py::arg("tensors"), ((int32_t*)specInfo.ptr) +
py::arg("spirv"), specInfo.size);
py::arg("workgroup") = kp::Workgroup(), if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
py::arg("spec_consts") = std::vector<float>(), std::vector<float> pushconstsvec((float*)pushInfo.ptr,
py::arg("push_consts") = std::vector<float>()) ((float*)pushInfo.ptr) +
.def("list_devices", [](kp::Manager& self){ pushInfo.size);
return self.algorithm(tensors,
spirvVec,
workgroup,
specconstsvec,
pushconstsvec);
} else if (spec_consts.dtype() ==
py::dtype::of<std::int32_t>()) {
std::vector<int32_t> 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::uint32_t>()) {
std::vector<uint32_t> 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::double_t>()) {
std::vector<double> 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::uint32_t>()) {
std::vector<uint32_t> specconstsvec((uint32_t*)specInfo.ptr,
((uint32_t*)specInfo.ptr) +
specInfo.size);
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
std::vector<float> 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::int32_t>()) {
std::vector<int32_t> 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::uint32_t>()) {
std::vector<uint32_t> 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::double_t>()) {
std::vector<double> 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::double_t>()) {
std::vector<double> specconstsvec((double*)specInfo.ptr,
((double*)specInfo.ptr) +
specInfo.size);
if (spec_consts.dtype() == py::dtype::of<std::float_t>()) {
std::vector<float> 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::int32_t>()) {
std::vector<float> 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::uint32_t>()) {
std::vector<float> 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::double_t>()) {
std::vector<float> 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<float>(),
py::arg("push_consts") = std::vector<float>())
.def(
"list_devices",
[](kp::Manager& self) {
const std::vector<vk::PhysicalDevice> devices = self.listDevices(); const std::vector<vk::PhysicalDevice> devices = self.listDevices();
py::list list; py::list list;
for (const vk::PhysicalDevice& device : devices) { for (const vk::PhysicalDevice& device : devices) {
list.append(kp::py::vkPropertiesToDict(device.getProperties())); list.append(kp::py::vkPropertiesToDict(device.getProperties()));
} }
return list; return list;
}, "Return a dict containing information about the device") },
.def("get_device_properties", [](kp::Manager& self){ "Return a dict containing information about the device")
const vk::PhysicalDeviceProperties properties = self.getDeviceProperties(); .def(
"get_device_properties",
[](kp::Manager& self) {
const vk::PhysicalDeviceProperties properties =
self.getDeviceProperties();
return kp::py::vkPropertiesToDict(properties); 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"); auto atexit = py::module_::import("atexit");
atexit.attr("register")(py::cpp_function([](){ atexit.attr("register")(py::cpp_function([]() {
kp_debug = py::none(); kp_debug = py::none();
kp_info = py::none(); kp_info = py::none();
kp_warning = py::none(); kp_warning = py::none();
@ -340,4 +562,3 @@ PYBIND11_MODULE(kp, m) {
m.attr("__version__") = "dev"; m.attr("__version__") = "dev";
#endif #endif
} }

View file

@ -80,24 +80,23 @@ endif()
##################################################### #####################################################
if(KOMPUTE_OPT_ANDROID_BUILD) if(KOMPUTE_OPT_ANDROID_BUILD)
target_link_libraries(kompute PUBLIC fmt::fmt target_link_libraries(kompute PUBLIC kompute_vk_ndk_wrapper
kompute_vk_ndk_wrapper fmt::fmt
log log
android) android
logger)
else() else()
target_link_libraries(kompute PUBLIC Vulkan::Vulkan target_link_libraries(kompute PUBLIC Vulkan::Vulkan
fmt::fmt) fmt::fmt
logger)
endif() endif()
if(KOMPUTE_OPT_USE_BUILD_IN_VULKAN_HEADER) if(KOMPUTE_OPT_USE_BUILD_IN_VULKAN_HEADER)
target_link_libraries(kompute PUBLIC Vulkan-Headers) target_link_libraries(kompute PUBLIC Vulkan-Headers)
endif() endif()
if(KOMPUTE_OPT_ENABLE_LOGGING)
target_link_libraries(kompute PUBLIC spdlog::spdlog)
endif()
##################################################### #####################################################
# Misc # Misc
##################################################### #####################################################
add_subdirectory(logger)
add_subdirectory(include) add_subdirectory(include)

View file

@ -6,8 +6,8 @@
#include <string> #include <string>
#include "kompute/Manager.hpp" #include "kompute/Manager.hpp"
#include "kompute/logger/Logger.hpp"
#include "fmt/ranges.h" #include "spdlog/common.h"
namespace kp { namespace kp {
@ -40,6 +40,9 @@ Manager::Manager(uint32_t physicalDeviceIndex,
{ {
this->mManageResources = true; this->mManageResources = true;
// Make sure the logger is setup
logger::setupLogger();
this->createInstance(); this->createInstance();
this->createDevice( this->createDevice(
familyQueueIndices, physicalDeviceIndex, desiredExtensions); familyQueueIndices, physicalDeviceIndex, desiredExtensions);
@ -54,6 +57,9 @@ Manager::Manager(std::shared_ptr<vk::Instance> instance,
this->mInstance = instance; this->mInstance = instance;
this->mPhysicalDevice = physicalDevice; this->mPhysicalDevice = physicalDevice;
this->mDevice = device; this->mDevice = device;
// Make sure the logger is setup
logger::setupLogger();
} }
Manager::~Manager() Manager::~Manager()
@ -311,8 +317,10 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices,
this->mPhysicalDevice = this->mPhysicalDevice =
std::make_shared<vk::PhysicalDevice>(physicalDevice); std::make_shared<vk::PhysicalDevice>(physicalDevice);
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
vk::PhysicalDeviceProperties physicalDeviceProperties = vk::PhysicalDeviceProperties physicalDeviceProperties =
physicalDevice.getProperties(); physicalDevice.getProperties();
#endif
KP_LOG_INFO("Using physical device index {} found {}", KP_LOG_INFO("Using physical device index {} found {}",
physicalDeviceIndex, physicalDeviceIndex,
@ -369,7 +377,7 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices,
} }
KP_LOG_DEBUG("Kompute Manager desired extension layers {}", KP_LOG_DEBUG("Kompute Manager desired extension layers {}",
desiredExtensions); logger::vecToString(desiredExtensions));
std::vector<vk::ExtensionProperties> deviceExtensions = std::vector<vk::ExtensionProperties> deviceExtensions =
this->mPhysicalDevice->enumerateDeviceExtensionProperties(); this->mPhysicalDevice->enumerateDeviceExtensionProperties();
@ -379,7 +387,7 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices,
uniqueExtensionNames.insert(ext.extensionName); uniqueExtensionNames.insert(ext.extensionName);
} }
KP_LOG_DEBUG("Kompute Manager available extensions {}", KP_LOG_DEBUG("Kompute Manager available extensions {}",
uniqueExtensionNames); logger::setToString(uniqueExtensionNames));
std::vector<const char*> validExtensions; std::vector<const char*> validExtensions;
for (const std::string& ext : desiredExtensions) { for (const std::string& ext : desiredExtensions) {
if (uniqueExtensionNames.count(ext) != 0) { if (uniqueExtensionNames.count(ext) != 0) {
@ -388,7 +396,7 @@ Manager::createDevice(const std::vector<uint32_t>& familyQueueIndices,
} }
if (desiredExtensions.size() != validExtensions.size()) { if (desiredExtensions.size() != validExtensions.size()) {
KP_LOG_ERROR("Kompute Manager not all extensions were added: {}", KP_LOG_ERROR("Kompute Manager not all extensions were added: {}",
validExtensions); logger::vecToString(validExtensions));
} }
vk::DeviceCreateInfo deviceCreateInfo(vk::DeviceCreateFlags(), vk::DeviceCreateInfo deviceCreateInfo(vk::DeviceCreateFlags(),

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#include "kompute/operations/OpTensorCopy.hpp" #include "kompute/operations/OpTensorCopy.hpp"
#include "kompute/Tensor.hpp"
namespace kp { namespace kp {
@ -21,8 +22,8 @@ OpTensorCopy::OpTensorCopy(const std::vector<std::shared_ptr<Tensor>>& tensors)
if (tensor->dataType() != dataType) { if (tensor->dataType() != dataType) {
throw std::runtime_error(fmt::format( throw std::runtime_error(fmt::format(
"Attempting to copy tensors of different types from {} to {}", "Attempting to copy tensors of different types from {} to {}",
dataType, Tensor::toString(dataType),
tensor->dataType())); Tensor::toString(tensor->dataType())));
} }
if (tensor->size() != size) { if (tensor->size() != size) {
throw std::runtime_error(fmt::format( throw std::runtime_error(fmt::format(

View file

@ -4,6 +4,40 @@
namespace kp { 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<vk::PhysicalDevice> physicalDevice, Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
std::shared_ptr<vk::Device> device, std::shared_ptr<vk::Device> device,
void* data, void* data,
@ -14,7 +48,7 @@ Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
{ {
KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}", KP_LOG_DEBUG("Kompute Tensor constructor data length: {}, and type: {}",
elementTotalCount, elementTotalCount,
tensorType); Tensor::toString(tensorType));
this->mPhysicalDevice = physicalDevice; this->mPhysicalDevice = physicalDevice;
this->mDevice = device; this->mDevice = device;
@ -27,7 +61,7 @@ Tensor::Tensor(std::shared_ptr<vk::PhysicalDevice> physicalDevice,
Tensor::~Tensor() Tensor::~Tensor()
{ {
KP_LOG_DEBUG("Kompute Tensor destructor started. Type: {}", KP_LOG_DEBUG("Kompute Tensor destructor started. Type: {}",
this->tensorType()); Tensor::toString(this->tensorType()));
if (this->mDevice) { if (this->mDevice) {
this->destroy(); this->destroy();

View file

@ -1,5 +1,9 @@
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.15)
#####################################################
# Kompute
#####################################################
target_include_directories(kompute PUBLIC $<INSTALL_INTERFACE:include> target_include_directories(kompute PUBLIC $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>) $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
@ -22,6 +26,22 @@ target_sources(kompute PRIVATE
kompute/shaders/shaderlogisticregression.hpp kompute/shaders/shaderlogisticregression.hpp
kompute/shaders/shaderopmult.hpp kompute/shaders/shaderopmult.hpp
kompute/logger/Logger.hpp
) )
install(DIRECTORY kompute DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY kompute DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
#####################################################
# Logger
#####################################################
target_include_directories(logger PUBLIC $<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
target_sources(logger PRIVATE
# Header files (useful in IDEs)
kompute/logger/Logger.hpp
)
install(DIRECTORY logger DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View file

@ -4,6 +4,7 @@
#include "kompute/Core.hpp" #include "kompute/Core.hpp"
#include "kompute/Tensor.hpp" #include "kompute/Tensor.hpp"
#include "logger/Logger.hpp"
namespace kp { namespace kp {

View file

@ -2,15 +2,11 @@
#pragma once #pragma once
#if VK_USE_PLATFORM_ANDROID_KHR #if VK_USE_PLATFORM_ANDROID_KHR
#include <android/log.h>
#include <kompute_vk_ndk_wrapper.hpp> #include <kompute_vk_ndk_wrapper.hpp>
// VK_NO_PROTOTYPES required before vulkan import but after wrapper.hpp // VK_NO_PROTOTYPES required before vulkan import but after wrapper.hpp
#undef VK_NO_PROTOTYPES #undef VK_NO_PROTOTYPES
static const char* KOMPUTE_LOG_TAG = "KomputeLog";
#endif #endif
#include <fmt/core.h>
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
// Typedefs to simplify interaction with core types // Typedefs to simplify interaction with core types
@ -32,124 +28,9 @@ typedef std::vector<float> Constants;
KOMPUTE_VK_API_MAJOR_VERSION, KOMPUTE_VK_API_MINOR_VERSION, 0) KOMPUTE_VK_API_MAJOR_VERSION, KOMPUTE_VK_API_MINOR_VERSION, 0)
#endif // KOMPUTE_VK_API_VERSION #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) #if defined(KOMPUTE_BUILD_PYTHON)
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
namespace py = pybind11; namespace py = pybind11;
// from python/src/main.cpp // from python/src/main.cpp
extern py::object kp_debug, kp_info, kp_warning, kp_error; extern py::object kp_debug, kp_info, kp_warning, kp_error;
#endif #endif
#ifndef KOMPUTE_LOG_OVERRIDE
#if KOMPUTE_ENABLE_SPDLOG
#include <spdlog/spdlog.h>
#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 <iostream>
#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

View file

@ -7,6 +7,7 @@
#include "kompute/Core.hpp" #include "kompute/Core.hpp"
#include "kompute/Sequence.hpp" #include "kompute/Sequence.hpp"
#include "logger/Logger.hpp"
#define KP_DEFAULT_SESSION "DEFAULT" #define KP_DEFAULT_SESSION "DEFAULT"

View file

@ -1,10 +1,12 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#pragma once #pragma once
#include "kompute/Core.hpp"
#include <fmt/format.h>
#include <string> #include <string>
#include "kompute/Core.hpp"
#include "logger/Logger.hpp"
namespace kp { namespace kp {
/** /**
@ -39,6 +41,9 @@ class Tensor
eDouble = 4, 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 * Constructor with data provided which would be used to create the
* respective vulkan buffer and memory. * respective vulkan buffer and memory.
@ -341,59 +346,3 @@ class TensorT : public Tensor
}; };
} // End namespace kp } // End namespace kp
/**
* fmt fromater for kp::Tensor::TensorDataTypes.
*/
template<>
struct fmt::formatter<kp::Tensor::TensorDataTypes> : formatter<std::string>
{
template<typename FormatContext>
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<std::string>::format(name, ctx);
}
};
/**
* fmt fromater for kp::Tensor::TensorTypes.
*/
template<>
struct fmt::formatter<kp::Tensor::TensorTypes> : formatter<std::string>
{
template<typename FormatContext>
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<std::string>::format(name, ctx);
}
};

View file

@ -0,0 +1,36 @@
#pragma once
#include <set>
#include <spdlog/spdlog.h>
#include <string>
#include <vector>
#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<std::string>& set);
std::string
vecToString(const std::vector<const char*>& vec);
std::string
vecToString(const std::vector<std::string>& vec);
} // namespace logger

37
src/logger/CMakeLists.txt Normal file
View file

@ -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 $<IF:$<CONFIG:Debug>,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})

192
src/logger/Logger.cpp Normal file
View file

@ -0,0 +1,192 @@
#include "kompute/logger/Logger.hpp"
#include <cassert>
#include <iostream>
#include <memory>
#include <mutex>
#include <spdlog/async.h>
#include <spdlog/common.h>
#include <spdlog/logger.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _WIN32
#include <iso646.h>
#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<spdlog::sinks::stdout_color_sink_mt>();
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<spdlog::sinks::rotating_file_sink_mt>(
s, FILE_ROTATION_TIME, 3);
#else // _WIN32
spdlog::sink_ptr file_sink =
std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
logger::logFolder + "/kompute.log", FILE_ROTATION_TIME, 3);
#endif
file_sink->set_pattern("[%H:%M:%S %z] [%=8l] [thread %t] [%@]\t%v");
std::vector<spdlog::sink_ptr> sinks{ file_sink, console_sink };
std::shared_ptr<spdlog::logger> logger =
std::make_shared<spdlog::async_logger>(
"",
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<std::string>& 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<const char*>& 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<std::string>& 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

View file

@ -6,8 +6,6 @@
#include "shaders/Utils.hpp" #include "shaders/Utils.hpp"
#include "fmt/ranges.h"
TEST(TestPushConstants, TestConstantsAlgoDispatchOverride) TEST(TestPushConstants, TestConstantsAlgoDispatchOverride)
{ {
{ {