├── requirements.txt ├── .gitignore ├── examples ├── data │ ├── lena.png │ └── parrot.mp4 ├── example_save_file.cpp ├── python │ └── example_wandb.py ├── example_get_mode.cpp ├── example_print_pyobject.cpp ├── CMakeLists.txt ├── example_table2.cpp ├── example_table3.cpp ├── example_image.cpp ├── example_table.cpp ├── example_log_dict.cpp ├── example_log_basic.cpp ├── example_video.cpp ├── example_object3d.cpp ├── example_log_time_measurement.cpp └── example_object3d_lidar.cpp ├── assets ├── example_image.png ├── example_video.gif ├── example_log_basic.png ├── example_save_file.png ├── example_table_add_column.png ├── example_table_add_data.png ├── example_table_constructor.png └── example_object3d_pointcloud.png ├── src ├── py_util.hpp ├── utils.hpp ├── np_object.cpp ├── np_object.hpp ├── py_util.cpp ├── async_logging.hpp ├── wandb_object.hpp ├── wandb_object.cpp ├── py_object.cpp ├── py_object.hpp ├── async_logging.cpp └── wandbcpp.cpp ├── LICENSE ├── CMakeLists.txt ├── wandbcpp.hpp └── README.md /requirements.txt: -------------------------------------------------------------------------------- 1 | wandb 2 | numpy -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | wandb/ 3 | .vscode/ 4 | tmp/ 5 | Taskfile.yml -------------------------------------------------------------------------------- /examples/data/lena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/examples/data/lena.png -------------------------------------------------------------------------------- /assets/example_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_image.png -------------------------------------------------------------------------------- /assets/example_video.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_video.gif -------------------------------------------------------------------------------- /examples/data/parrot.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/examples/data/parrot.mp4 -------------------------------------------------------------------------------- /assets/example_log_basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_log_basic.png -------------------------------------------------------------------------------- /assets/example_save_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_save_file.png -------------------------------------------------------------------------------- /assets/example_table_add_column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_table_add_column.png -------------------------------------------------------------------------------- /assets/example_table_add_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_table_add_data.png -------------------------------------------------------------------------------- /assets/example_table_constructor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_table_constructor.png -------------------------------------------------------------------------------- /assets/example_object3d_pointcloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yhisaki/wandb-cpp/HEAD/assets/example_object3d_pointcloud.png -------------------------------------------------------------------------------- /examples/example_save_file.cpp: -------------------------------------------------------------------------------- 1 | #include "wandbcpp.hpp" 2 | 3 | int main() { 4 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"save file"}}); 5 | wandbcpp::save("examples/data/lena.png"); // save this source code 6 | wandbcpp::finish(); 7 | } 8 | -------------------------------------------------------------------------------- /examples/python/example_wandb.py: -------------------------------------------------------------------------------- 1 | import wandb 2 | 3 | wandb.init(project="test_wandb_cpp", name="") 4 | 5 | for i in range(100): 6 | wandb.log({"x": 1.0, "mode": "abc"}, step=i) 7 | 8 | wandb.summary.a = 1 9 | 10 | wandb.config.update({"a": 1, "b": 2}) -------------------------------------------------------------------------------- /examples/example_get_mode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "wandbcpp.hpp" 6 | 7 | namespace chrono = std::chrono; 8 | using namespace std::literals; 9 | 10 | int main() { std::cout << (int)wandbcpp::wandb::get_mode() << std::endl; } 11 | -------------------------------------------------------------------------------- /examples/example_print_pyobject.cpp: -------------------------------------------------------------------------------- 1 | #include "src/wandb_object.hpp" 2 | 3 | int main(int argc, char const *argv[]) { 4 | using namespace wandbcpp::internal::object; 5 | Py_Initialize(); 6 | PyBasicType i(1); 7 | std::cout << i << std::endl; 8 | Py_Finalize(); 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | file(GLOB example_files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) 2 | 3 | foreach(file ${example_files}) 4 | string(REPLACE ".cpp" "" name ${file}) 5 | message(${name}) 6 | add_executable(${name} ${file}) 7 | target_link_libraries(${name} 8 | wandbcpp 9 | ) 10 | endforeach(file ${example_files}) -------------------------------------------------------------------------------- /examples/example_table2.cpp: -------------------------------------------------------------------------------- 1 | #include "wandbcpp.hpp" 2 | 3 | int main() { 4 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"table"}}); 5 | int I = 10; 6 | for (int i = 0; i < I; i++) { 7 | wandbcpp::Table table({"x", "y"}, {{"poyo", i}, {"hoge", i + 1}}); 8 | wandbcpp::log({{"table", table}}); 9 | } 10 | wandbcpp::finish(); 11 | } 12 | -------------------------------------------------------------------------------- /examples/example_table3.cpp: -------------------------------------------------------------------------------- 1 | #include "wandbcpp.hpp" 2 | 3 | int main() { 4 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"table"}}); 5 | wandbcpp::Table table; 6 | std::vector x = {1.0, 2.0, 3.0}; 7 | std::vector y = {4, 5, 6}; 8 | table.add_column("x", {x.begin(), x.end()}); 9 | table.add_column("y", {y.begin(), y.end()}); 10 | wandbcpp::log({{"table", table}}); 11 | wandbcpp::finish(); 12 | } 13 | -------------------------------------------------------------------------------- /examples/example_image.cpp: -------------------------------------------------------------------------------- 1 | #ifdef USE_OPENCV 2 | #include 3 | #endif 4 | #include "wandbcpp.hpp" 5 | 6 | int main() 7 | { 8 | #ifdef USE_OPENCV 9 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"image"}}); 10 | cv::Mat img = cv::imread("examples/data/lena.png"); 11 | wandbcpp::log({{"image_from_array", wandbcpp::Image(img)}}); 12 | wandbcpp::log( 13 | {{"image_from_path", wandbcpp::Image("examples/data/lena.png")}}); 14 | wandbcpp::finish(); 15 | #endif 16 | } 17 | -------------------------------------------------------------------------------- /examples/example_table.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "wandbcpp.hpp" 4 | 5 | int main() { 6 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"table"}}); 7 | int I = 10; 8 | int J = 100; 9 | 10 | for (int i = 0; i < I; i++) { 11 | wandbcpp::Table table({"x", "y"}); 12 | for (int j = 0; j < J; j++) { 13 | double x = (i + 1) * std::sin(M_PI * j / J); 14 | double y = (i + 1) * std::cos(M_PI * j / J); 15 | table.add_data({x, y}); 16 | } 17 | wandbcpp::log({{"mytable", table}}); 18 | } 19 | wandbcpp::finish(); 20 | } 21 | -------------------------------------------------------------------------------- /examples/example_log_dict.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "wandbcpp.hpp" 5 | 6 | int main() { 7 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"log_dict"}}); 8 | 9 | int N = 100; 10 | 11 | for (int i = 0; i < N; i++) { 12 | wandbcpp::log_dict logs; 13 | double t = M_PI * i / N; 14 | double x = std::sin(M_PI * i / N); 15 | double y = std::cos(M_PI * i / N); 16 | logs.update({{"t", t}}); 17 | logs.update({{"x", x}}); 18 | logs.update({{"y", y}}); 19 | wandbcpp::log(logs); 20 | } 21 | 22 | wandbcpp::save(__FILE__); 23 | wandbcpp::finish(); 24 | } 25 | -------------------------------------------------------------------------------- /src/py_util.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDBCPP_PY_UTIL_HPP_ 2 | #define WANDBCPP_PY_UTIL_HPP_ 3 | 4 | #include "src/py_object.hpp" 5 | 6 | namespace wandbcpp::internal::util { 7 | 8 | object::SharedPyObjectPtr PyCall(const object::SharedPyObjectPtr& func); 9 | object::SharedPyObjectPtr PyCall(const object::SharedPyObjectPtr& func, 10 | const object::PyDict& kwargs); 11 | object::SharedPyObjectPtr PyCall(const object::SharedPyObjectPtr& func, 12 | const object::PyTuple& args); 13 | void print_pyobject(PyObject* obj, int idx = 0); 14 | 15 | } // namespace wandbcpp::internal::util 16 | 17 | #endif -------------------------------------------------------------------------------- /examples/example_log_basic.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "wandbcpp.hpp" 5 | 6 | int main() { 7 | wandbcpp::init( 8 | {.project = "example_wandb_cpp", .tags = {"basic"}, .group = "abc"}); 9 | 10 | int N = 100; 11 | 12 | wandbcpp::update_config({{"N", N}, {"mode", "abc"}}); 13 | 14 | for (int i = 0; i < N; i++) { 15 | double t = M_PI * i / N; 16 | double x = std::sin(M_PI * i / N); 17 | double y = std::cos(M_PI * i / N); 18 | wandbcpp::log({{"t", t}, {"x", x}, {"y", y}}); 19 | std::cout << "i : " << i << std::endl; 20 | } 21 | 22 | wandbcpp::update_summary({{"success", true}}); 23 | 24 | wandbcpp::finish(); 25 | } 26 | -------------------------------------------------------------------------------- /src/utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDBCPP_UTILS_HPP_ 2 | #define WANDBCPP_UTILS_HPP_ 3 | 4 | #include 5 | #include 6 | 7 | #include "src/py_object.hpp" 8 | namespace wandbcpp { 9 | 10 | inline namespace utils { 11 | 12 | template 13 | internal::object::PyList topylist(I begin, I end) { 14 | if constexpr (std::is_arithmetic_v< 15 | typename std::iterator_traits::value_type>) { 16 | return {begin, end}; 17 | } else { 18 | std::vector data; 19 | for (auto i = begin; i != end; i++) { 20 | data.emplace_back(topylist(i->begin(), i->end())); 21 | } 22 | return {data.begin(), data.end()}; 23 | } 24 | } 25 | 26 | } // namespace utils 27 | 28 | } // namespace wandbcpp 29 | 30 | #endif -------------------------------------------------------------------------------- /examples/example_video.cpp: -------------------------------------------------------------------------------- 1 | #ifdef USE_OPENCV 2 | #include 3 | #endif 4 | #include "wandbcpp.hpp" 5 | 6 | int main() { 7 | #ifdef USE_OPENCV 8 | 9 | cv::VideoCapture cap("examples/data/parrot.mp4"); 10 | 11 | if (!cap.isOpened()) { 12 | std::cerr << "Error: Video file not opened." << std::endl; 13 | return 1; 14 | } 15 | 16 | std::vector frames; 17 | 18 | while (true) { 19 | cv::Mat frame; 20 | cap >> frame; 21 | if (frame.empty()) break; 22 | 23 | frames.push_back(frame); 24 | } 25 | std::cout << "Number of frames: " << frames.size() << std::endl; 26 | 27 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"video"}}); 28 | 29 | wandbcpp::log({{"video", wandbcpp::Video(frames.begin(), frames.end())}}); 30 | 31 | wandbcpp::finish(); 32 | 33 | #endif 34 | } 35 | -------------------------------------------------------------------------------- /src/np_object.cpp: -------------------------------------------------------------------------------- 1 | #include "src/np_object.hpp" 2 | 3 | #include 4 | #include 5 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 6 | #define NO_IMPORT_ARRAY 7 | #define PY_ARRAY_UNIQUE_SYMBOL cool_ARRAY_API 8 | #include "numpy/arrayobject.h" 9 | namespace wandbcpp::numpy { 10 | using namespace std::literals; 11 | ndarray::ndarray(const internal::object::PyList& data) 12 | : data_(data), dtype_(dtype::np_notype) {} 13 | 14 | ndarray::ndarray(const internal::object::PyList& data, dtype dtype) 15 | : data_(data), dtype_(dtype) {} 16 | 17 | // ndarray::ndarray(const internal::object::PyList& data) : data_(data) {} 18 | 19 | PyObject* ndarray::get_pyobject() const { 20 | return PyArray_FromObject(data_.get_pyobject(), 21 | static_cast(dtype_), 0, 0); 22 | } 23 | 24 | } // namespace wandbcpp::numpy 25 | -------------------------------------------------------------------------------- /examples/example_object3d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "wandbcpp.hpp" 5 | 6 | std::array gen_random_point() { 7 | static std::random_device seed_gen; 8 | static std::mt19937 engine(seed_gen()); 9 | static std::uniform_real_distribution<> dist(-1.0, 1.0); 10 | return {dist(engine), dist(engine), dist(engine)}; 11 | } 12 | 13 | int main(int argc, char const* argv[]) { 14 | namespace np = wandbcpp::numpy; 15 | 16 | wandbcpp::init({.project = "example_wandb_cpp", .tags = {"object3d"}}); 17 | 18 | int num_points = 300; 19 | 20 | std::vector> point_cloud(num_points); 21 | 22 | std::generate(point_cloud.begin(), point_cloud.end(), &gen_random_point); 23 | 24 | auto lst = wandbcpp::topylist(point_cloud.begin(), point_cloud.end()); 25 | 26 | wandbcpp::log({{"obj3d", wandbcpp::Object3D{np::ndarray{lst}}}}); 27 | 28 | wandbcpp::finish(); 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /src/np_object.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDBCPP_NP_OBJECT_HPP_ 2 | #define WANDBCPP_NP_OBJECT_HPP_ 3 | #include 4 | #include 5 | #include 6 | #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION 7 | #include "numpy/ndarraytypes.h" 8 | #include "src/py_object.hpp" 9 | namespace wandbcpp { 10 | 11 | namespace numpy { 12 | 13 | enum class dtype : std::underlying_type_t { 14 | np_notype = NPY_NOTYPE, 15 | np_short = NPY_SHORT, 16 | np_int = NPY_INT, 17 | np_double = NPY_DOUBLE, 18 | np_float = NPY_FLOAT, 19 | np_object = NPY_OBJECT 20 | }; 21 | class ndarray : public internal::object::PyObjectBaseClonable { 22 | internal::object::PyList data_; 23 | dtype dtype_; 24 | 25 | public: 26 | explicit ndarray(const internal::object::PyList& data); 27 | 28 | explicit ndarray(const internal::object::PyList& data, dtype dtype); 29 | 30 | ~ndarray() {} 31 | 32 | PyObject* get_pyobject() const override; 33 | }; 34 | 35 | } // namespace numpy 36 | 37 | } // namespace wandbcpp 38 | #endif -------------------------------------------------------------------------------- /examples/example_log_time_measurement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "wandbcpp.hpp" 6 | 7 | namespace chrono = std::chrono; 8 | using namespace std::literals; 9 | 10 | int main() { 11 | wandbcpp::init( 12 | {.project = "example_wandb_cpp", .tags = {"time measurement"}}); 13 | 14 | int N = 100; 15 | 16 | wandbcpp::update_config({{"N", N}}); 17 | 18 | auto begin = chrono::high_resolution_clock::now(); 19 | 20 | for (int i = 0; i < N; i++) { 21 | double t = M_PI * i / N; 22 | double x = std::sin(M_PI * i / N); 23 | double y = std::cos(M_PI * i / N); 24 | wandbcpp::log({{"t", t}, {"x", x}, {"y", y}}); 25 | std::cout << "i : " << i << std::endl; 26 | } 27 | 28 | auto end = chrono::high_resolution_clock::now(); 29 | const auto elapsed_time_us_per_step = 30 | chrono::duration_cast(end - begin).count() / 31 | static_cast(N); 32 | 33 | wandbcpp::update_summary( 34 | {{"elapsed_time_us per step", elapsed_time_us_per_step}}); 35 | wandbcpp::finish(); 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yukinari Hisaki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | enable_language(CXX) 3 | set(CMAKE_CXX_STANDARD 20) # C++20... 4 | set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required... 5 | set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11 6 | 7 | option(BUILD_WANDBCPP_EXE OFF) 8 | option(USE_OPENCV OFF) 9 | 10 | project(wandb-cpp) 11 | 12 | include(FetchContent) 13 | 14 | find_library(PTHREAD_LIBRARY pthread) 15 | find_package(Python3 COMPONENTS Interpreter Development NumPy) 16 | 17 | # find OpenCV 18 | if (USE_OPENCV) 19 | find_package(OpenCV REQUIRED) 20 | # add definitions for OpenCV 21 | add_definitions(-DUSE_OPENCV) 22 | endif (USE_OPENCV) 23 | 24 | 25 | file(GLOB src_files src/*.cpp) 26 | 27 | add_library(wandbcpp ${src_files}) 28 | add_library(wandbcpp::wandbcpp ALIAS wandbcpp) 29 | 30 | target_compile_options(wandbcpp PRIVATE -O3 -Wall -Wextra -Wno-long-long -pedantic) 31 | 32 | target_include_directories(wandbcpp PUBLIC 33 | ${CMAKE_CURRENT_SOURCE_DIR} 34 | ) 35 | 36 | target_link_libraries(wandbcpp PUBLIC 37 | Python3::NumPy 38 | Python3::Python 39 | ${PTHREAD_LIBRARY} 40 | ) 41 | 42 | if (USE_OPENCV) 43 | target_include_directories(wandbcpp PUBLIC 44 | ${OpenCV_INCLUDE_DIRS}) 45 | target_link_libraries(wandbcpp PUBLIC 46 | ${OpenCV_LIBS} 47 | ) 48 | endif (USE_OPENCV) 49 | 50 | if(BUILD_WANDBCPP_EXE) 51 | add_subdirectory(examples) 52 | endif(BUILD_WANDBCPP_EXE) 53 | -------------------------------------------------------------------------------- /src/py_util.cpp: -------------------------------------------------------------------------------- 1 | #include "src/py_util.hpp" 2 | 3 | #include 4 | #include 5 | 6 | namespace wandbcpp::internal::util { 7 | 8 | using namespace object; 9 | 10 | SharedPyObjectPtr PyCall(const SharedPyObjectPtr& func) { 11 | SharedPyObjectPtr args_ptr(PyTuple().get_pyobject()); 12 | SharedPyObjectPtr kwargs_ptr(PyDict().get_pyobject()); 13 | return SharedPyObjectPtr( 14 | PyObject_Call(func.get(), args_ptr.get(), kwargs_ptr.get())); 15 | } 16 | 17 | SharedPyObjectPtr PyCall(const SharedPyObjectPtr& func, const PyDict& kwargs) { 18 | SharedPyObjectPtr args_ptr(PyTuple().get_pyobject()); 19 | SharedPyObjectPtr kwargs_ptr(kwargs.get_pyobject()); 20 | return SharedPyObjectPtr( 21 | PyObject_Call(func.get(), args_ptr.get(), kwargs_ptr.get())); 22 | } 23 | 24 | SharedPyObjectPtr PyCall(const SharedPyObjectPtr& func, const PyTuple& args) { 25 | SharedPyObjectPtr args_ptr(args.get_pyobject()); 26 | SharedPyObjectPtr kwargs_ptr(PyDict().get_pyobject()); 27 | return SharedPyObjectPtr( 28 | PyObject_Call(func.get(), args_ptr.get(), kwargs_ptr.get())); 29 | } 30 | 31 | SharedPyObjectPtr PyCall(const SharedPyObjectPtr& func, const PyTuple& args, 32 | const PyDict& kwargs) { 33 | SharedPyObjectPtr args_ptr(args.get_pyobject()); 34 | SharedPyObjectPtr kwargs_ptr(kwargs.get_pyobject()); 35 | return SharedPyObjectPtr( 36 | PyObject_Call(func.get(), args_ptr.get(), kwargs_ptr.get())); 37 | } 38 | 39 | void print_pyobject(PyObject* obj, int idx) { 40 | PyObject_Print(obj, stdout, idx); 41 | printf("\n"); 42 | } 43 | 44 | } // namespace wandbcpp::internal::util 45 | -------------------------------------------------------------------------------- /examples/example_object3d_lidar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "src/utils.hpp" 5 | #include "wandbcpp.hpp" 6 | 7 | std::array gen_random_point() { 8 | static std::random_device seed_gen; 9 | static std::mt19937 engine(seed_gen()); 10 | static std::uniform_real_distribution<> dist(-1.0, 1.0); 11 | return {dist(engine), dist(engine), dist(engine)}; 12 | } 13 | 14 | int main(int argc, char const* argv[]) { 15 | namespace np = wandbcpp::numpy; 16 | 17 | wandbcpp::init( 18 | {.project = "example_wandb_cpp", .tags = {"object3d", "lidar"}}); 19 | 20 | int num_points = 300; 21 | 22 | std::vector> point_cloud(num_points); 23 | 24 | std::generate(point_cloud.begin(), point_cloud.end(), &gen_random_point); 25 | 26 | auto point_cloud_lst = 27 | wandbcpp::topylist(point_cloud.begin(), point_cloud.end()); 28 | 29 | std::vector> box_corners = { 30 | {0, 0, 0}, {0, 1, 0}, {0, 0, 1}, {1, 0, 0}, 31 | {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 1, 1}, 32 | }; 33 | 34 | auto box_corners_lst = 35 | wandbcpp::topylist(box_corners.begin(), box_corners.end()); 36 | 37 | auto box = np::ndarray(wandbcpp::py_list( 38 | wandbcpp::py_dict({{"corners", box_corners_lst}, 39 | {"color", wandbcpp::py_list(123, 321, 111)}}))); 40 | 41 | wandbcpp::Object3D obj{ 42 | wandbcpp::py_dict({{"type", "lidar/beta"}, // 43 | {"points", np::ndarray{point_cloud_lst}}, // 44 | {"boxes", box}})}; 45 | 46 | wandbcpp::log({{"obj3d", obj}}); 47 | 48 | wandbcpp::finish(); 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /src/async_logging.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDBCPP_ASYNC_LOGGING_HPP_ 2 | #define WANDBCPP_ASYNC_LOGGING_HPP_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "wandbcpp.hpp" 11 | 12 | namespace wandbcpp::internal::async { 13 | class AsyncLoggingWorker { 14 | /** 15 | * @brief A worker class to handle asynchronous logging. 16 | * 17 | * This class is used to handle asynchronous logging. 18 | * 19 | */ 20 | private: 21 | std::mutex init_mtx_; 22 | std::optional init_args_; 23 | std::condition_variable cv_do_init_; 24 | bool is_initialized_; 25 | std::mutex is_initialized_mtx_; 26 | std::condition_variable cv_is_initialized_; 27 | 28 | bool terminal_ = false; 29 | 30 | std::mutex buffers_mtx_; 31 | std::condition_variable cv_buffers_not_empty_; 32 | 33 | // log 34 | std::queue log_buffer_; 35 | 36 | // config 37 | std::queue config_buffer_; 38 | 39 | // summary 40 | std::queue summary_buffer_; 41 | 42 | // save 43 | std::vector file_path_buffer_; 44 | 45 | std::thread logging_worker_thread; 46 | 47 | wandb* wandb_; 48 | 49 | public: 50 | AsyncLoggingWorker(); 51 | ~AsyncLoggingWorker(); 52 | AsyncLoggingWorker(const AsyncLoggingWorker& other) = delete; 53 | AsyncLoggingWorker& operator=(const AsyncLoggingWorker& other) = delete; 54 | void initialize_wandb(const wandb::init_args& ia); 55 | void wait_initialized(); 56 | void worker(); 57 | 58 | bool is_buffers_empty(); 59 | 60 | bool is_log_buffer_empty(); 61 | void append_log(const object::PyDict& log); 62 | void append_log(object::PyDict&& log); 63 | 64 | bool is_config_buffer_empty(); 65 | void append_config(const object::PyDict& config); 66 | void append_config(object::PyDict&& config); 67 | 68 | bool is_summary_buffer_empty(); 69 | void append_summary(const object::PyDict& summary); 70 | void append_summary(object::PyDict&& summary); 71 | 72 | bool is_file_path_buffer_empty(); 73 | void append_file_path(const std::string& file_path); 74 | 75 | void finish(); 76 | }; 77 | 78 | } // namespace wandbcpp::internal::async 79 | 80 | #endif -------------------------------------------------------------------------------- /wandbcpp.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDBCPP_HPP_ 2 | #define WANDBCPP_HPP_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include "src/py_object.hpp" 10 | #include "src/py_util.hpp" 11 | #include "src/utils.hpp" 12 | #include "src/wandb_object.hpp" 13 | 14 | namespace wandbcpp { 15 | 16 | class wandb { 17 | internal::object::SharedPyObjectPtr wandb_module_; // wandb module 18 | internal::object::SharedPyObjectPtr run_; // run object 19 | internal::object::SharedPyObjectPtr init_; // init function 20 | internal::object::SharedPyObjectPtr log_; // log function 21 | internal::object::SharedPyObjectPtr config_; // config object 22 | internal::object::SharedPyObjectPtr config_update_; // config.update function 23 | internal::object::SharedPyObjectPtr summary_; // summary object 24 | internal::object::SharedPyObjectPtr 25 | summary_update_; // summary.update function 26 | internal::object::SharedPyObjectPtr save_; // save function 27 | internal::object::SharedPyObjectPtr finish_; // finish function 28 | 29 | public: 30 | wandb(); 31 | ~wandb() {} 32 | 33 | struct init_args { 34 | std::string project; 35 | std::string entity = ""; 36 | std::string name = ""; 37 | std::vector tags = {}; 38 | std::string group = ""; 39 | }; 40 | 41 | void init(const init_args& ia); 42 | 43 | void log(const internal::object::PyDict& logs); 44 | 45 | // void log(internal::object::PyDict&& logs); 46 | 47 | void save(const std::string& file_path); 48 | 49 | void update_config(const internal::object::PyDict& conf); 50 | 51 | void update_summary(const internal::object::PyDict& summ); 52 | 53 | void finish(); 54 | 55 | enum class wandb_mode { online, offline, disabled }; 56 | static wandb_mode get_mode(); 57 | }; 58 | 59 | using log_dict = internal::object::PyDict; 60 | using py_list = internal::object::PyList; 61 | using py_dict = internal::object::PyDict; 62 | 63 | void init(const wandb::init_args& ia, bool wait_initialized = true); 64 | 65 | void log(const internal::object::PyDict& logs); 66 | 67 | void log(internal::object::PyDict&& logs); 68 | 69 | void save(const std::string& file_path); 70 | 71 | void update_config(const internal::object::PyDict& confs); 72 | 73 | void update_config(internal::object::PyDict&& confs); 74 | 75 | void update_summary(const internal::object::PyDict& summs); 76 | 77 | void update_summary(internal::object::PyDict&& summs); 78 | 79 | void finish(); 80 | 81 | } // namespace wandbcpp 82 | 83 | #endif -------------------------------------------------------------------------------- /src/wandb_object.hpp: -------------------------------------------------------------------------------- 1 | #ifndef WANDB_OBJECT_HPP_ 2 | #define WANDB_OBJECT_HPP_ 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "src/np_object.hpp" 9 | #include "src/py_object.hpp" 10 | #include "wandbcpp.hpp" 11 | 12 | #ifdef USE_OPENCV 13 | #include 14 | #endif 15 | 16 | namespace wandbcpp { 17 | 18 | class Table : public internal::object::PyObjectBaseClonable { 19 | friend class wandb; 20 | internal::object::PyList columns_; 21 | std::vector data_; 22 | static internal::object::SharedPyObjectPtr& TablePointer(); 23 | 24 | public: 25 | Table() = default; 26 | ~Table() {} 27 | explicit Table(const std::vector& columns); 28 | Table(const std::vector& columns, 29 | const std::vector& data); 30 | void add_data(const internal::object::PyList& l); 31 | void add_data(internal::object::PyList&& l); 32 | void add_column(std::string name, const internal::object::PyList& l); 33 | PyObject* get_pyobject() const override; 34 | }; 35 | 36 | class Object3D : public internal::object::PyObjectBaseClonable { 37 | friend class wandb; 38 | static internal::object::SharedPyObjectPtr& Object3DPointer(); 39 | 40 | private: 41 | std::optional dict_; 42 | std::optional arr_; 43 | 44 | public: 45 | Object3D() = default; 46 | ~Object3D() {} 47 | explicit Object3D(const internal::object::PyDict& dict); 48 | explicit Object3D(const numpy::ndarray& arr); 49 | 50 | PyObject* get_pyobject() const override; 51 | }; 52 | 53 | #ifdef USE_OPENCV 54 | 55 | class Image : public internal::object::PyObjectBaseClonable { 56 | friend class wandb; 57 | static internal::object::SharedPyObjectPtr& ImagePointer(); 58 | 59 | private: 60 | std::optional cv_mat_; 61 | std::optional path_to_image_; 62 | 63 | public: 64 | Image() = default; 65 | explicit Image(const cv::Mat& cv_mat) : cv_mat_(cv_mat) {} 66 | explicit Image(cv::Mat&& cv_mat) : cv_mat_(std::move(cv_mat)) {} 67 | explicit Image(const std::string& path_to_image) 68 | : path_to_image_(path_to_image) {} 69 | ~Image() {} 70 | PyObject* get_pyobject() const override; 71 | }; 72 | 73 | class Video : public internal::object::PyObjectBaseClonable