Better handling of printing results board
This commit is contained in:
parent
f65c58d95c
commit
211dcad893
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
namespace fs = std::filesystem;
|
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "toolbox.hpp"
|
#include "toolbox.hpp"
|
||||||
//#include "config.hpp"
|
//#include "config.hpp"
|
||||||
@ -53,62 +52,64 @@ bool unit_test_argsort_2d(const np::Array<T>& a, const np::Array<uint16_t>& indi
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename F, typename... Args>
|
template <typename T, typename F, typename... Args>
|
||||||
T benchmark_function(const char* step_name, const F& fnc, Args &&...args) noexcept {
|
T benchmark_function(const char* const step_name, const int32_t& column_width, const F& fnc, Args &&...args) noexcept {
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("%s...\r", step_name);
|
fprintf(stderr, "%s...\r", step_name);
|
||||||
fflush(stdout); // manual flush is mandatory, otherwise it will not be shown immediately because the output is buffered
|
fflush(stderr); // manual flush is mandatory, otherwise it will not be shown immediately because the output is buffered
|
||||||
#endif
|
#endif
|
||||||
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
||||||
const T res = fnc(std::forward<Args>(args)...);
|
const T res = fnc(std::forward<Args>(args)...);
|
||||||
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
||||||
printf("| %-49s | %18s | %-29s |\n", step_name, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str());
|
formatted_row<3>({ column_width, -18, 29 }, { step_name, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename... Args>
|
template <typename F, typename... Args>
|
||||||
void benchmark_function_void(const char* step_name, const F& fnc, Args &&...args) noexcept {
|
void benchmark_function_void(const char* const step_name, const int32_t& column_width, const F& fnc, Args &&...args) noexcept {
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("%s...\r", step_name);
|
fprintf(stderr, "%s...\r", step_name);
|
||||||
fflush(stdout); // manual flush is mandatory, otherwise it will not be shown immediately because the output is buffered
|
fflush(stderr); // manual flush is mandatory, otherwise it will not be shown immediately because the output is buffered
|
||||||
#endif
|
#endif
|
||||||
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
||||||
fnc(std::forward<Args>(args)...);
|
fnc(std::forward<Args>(args)...);
|
||||||
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
||||||
printf("| %-49s | %18s | %-29s |\n", step_name, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str());
|
formatted_row<3>({ column_width, -18, 29 }, { step_name, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename F, typename... Args>
|
template <typename T, typename F, typename... Args>
|
||||||
np::Array<T> state_saver(const char* step_name, const char* filename, const bool& force_redo, const bool& save_state, const char* out_dir, const F& fnc, Args &&...args) noexcept {
|
np::Array<T> state_saver(const char* const step_name, const int32_t& column_width, const char* const filename, const bool& force_redo, const bool& save_state, const char* const out_dir, const F& fnc, Args &&...args) noexcept {
|
||||||
char filepath[BUFFER_SIZE] = { 0 };
|
char filepath[BUFFER_SIZE] = { 0 };
|
||||||
sprintf(filepath, "%s/%s.bin", out_dir, filename);
|
snprintf(filepath, BUFFER_SIZE, "%s/%s.bin", out_dir, filename);
|
||||||
|
|
||||||
np::Array<T> bin;
|
np::Array<T> bin;
|
||||||
if (!fs::exists(filepath) || force_redo) {
|
if (!std::filesystem::exists(filepath) || force_redo) {
|
||||||
bin = std::move(benchmark_function<np::Array<T>>(step_name, fnc, std::forward<Args>(args)...));
|
//bin = std::move(benchmark_function<np::Array<T>>(step_name, column_width, fnc, std::forward<Args>(args)...));
|
||||||
|
bin = benchmark_function<np::Array<T>>(step_name, column_width, fnc, std::forward<Args>(args)...);
|
||||||
if(save_state){
|
if(save_state){
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("Saving results of %s\r", step_name);
|
fprintf(stderr, "Saving results of %s\r", step_name);
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
save<T>(bin, filepath);
|
save<T>(bin, filepath);
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("%*c\r", 100, ' ');
|
fprintf(stderr, "%*c\r", 100, ' '); // Clear previous clear
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("Loading results of %s\r", step_name);
|
fprintf(stderr, "Loading results of %s\r", step_name);
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
bin = std::move(load<T>(filepath));
|
//bin = std::move(load<T>(filepath));
|
||||||
printf("| %-49s | %18s | %-29s |\n", step_name, "None", "loaded saved state");
|
bin = load<T>(filepath);
|
||||||
|
formatted_row<3>({ column_width, -18, 29 }, { step_name, "None", "loaded saved state" });
|
||||||
}
|
}
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, size_t N, typename F, typename... Args>
|
template <typename T, size_t N, typename F, typename... Args>
|
||||||
std::array<np::Array<T>, N> state_saver(const char* step_name, const std::vector<const char*>& filenames, const bool& force_redo, const bool& save_state, const char* out_dir, const F& fnc, Args &&...args) noexcept {
|
std::array<np::Array<T>, N> state_saver(const char* const step_name, const int32_t& column_width, const std::vector<const char*>& filenames, const bool& force_redo, const bool& save_state, const char* const out_dir, const F& fnc, Args &&...args) noexcept {
|
||||||
char filepath[BUFFER_SIZE] = { 0 };
|
char filepath[BUFFER_SIZE] = { 0 };
|
||||||
bool abs = false;
|
bool abs = false;
|
||||||
for (const char* filename : filenames){
|
for (const char* filename : filenames){
|
||||||
@ -121,11 +122,12 @@ std::array<np::Array<T>, N> state_saver(const char* step_name, const std::vector
|
|||||||
|
|
||||||
std::array<np::Array<T>, N> bin;
|
std::array<np::Array<T>, N> bin;
|
||||||
if (abs || force_redo) {
|
if (abs || force_redo) {
|
||||||
bin = std::move(benchmark_function<std::array<np::Array<T>, N>>(step_name, fnc, std::forward<Args>(args)...));
|
//bin = std::move(benchmark_function<std::array<np::Array<T>, N>>(step_name, column_width, fnc, std::forward<Args>(args)...));
|
||||||
|
bin = benchmark_function<std::array<np::Array<T>, N>>(step_name, column_width, fnc, std::forward<Args>(args)...);
|
||||||
if (save_state){
|
if (save_state){
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("Saving results of %s\r", step_name);
|
fprintf(stderr, "Saving results of %s\r", step_name);
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const char* filename : filenames){
|
for (const char* filename : filenames){
|
||||||
@ -133,21 +135,21 @@ std::array<np::Array<T>, N> state_saver(const char* step_name, const std::vector
|
|||||||
save<T>(bin[i++], filepath);
|
save<T>(bin[i++], filepath);
|
||||||
}
|
}
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("%*c\r", 100, ' ');
|
fprintf(stderr, "%*c\r", 100, ' '); // Clear previous print
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if __DEBUG == false
|
#if __DEBUG == false
|
||||||
printf("Loading results of %s\r", step_name);
|
fprintf(stderr, "Loading results of %s\r", step_name);
|
||||||
fflush(stdout);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const char* filename : filenames){
|
for (const char* filename : filenames){
|
||||||
sprintf(filepath, "%s/%s.bin", out_dir, filename);
|
|
||||||
bin[i++] = std::move(load<T>(filepath));
|
bin[i++] = std::move(load<T>(filepath));
|
||||||
|
snprintf(filepath, BUFFER_SIZE, "%s/%s.bin", out_dir, filename);
|
||||||
}
|
}
|
||||||
printf("| %-49s | %18s | %-29s |\n", step_name, "None", "loaded saved state");
|
formatted_row<3>({ column_width, -18, 29 }, { step_name, "None", "loaded saved state" });
|
||||||
}
|
}
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#define DATA_DIR "../data"
|
#define DATA_DIR "../data"
|
||||||
#define OUT_DIR "./out"
|
#define OUT_DIR "./out"
|
||||||
@ -11,7 +12,7 @@
|
|||||||
#define NB_THREADS_3D_X 16
|
#define NB_THREADS_3D_X 16
|
||||||
#define NB_THREADS_3D_Y 16
|
#define NB_THREADS_3D_Y 16
|
||||||
#define NB_THREADS_3D_Z 4
|
#define NB_THREADS_3D_Z 4
|
||||||
__device__ constexpr const size_t M = 5; //log2(NB_THREADS_2D_Y));
|
#define M static_cast<size_t>(log2f(NB_THREADS_2D_Y))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Save state to avoid recalculation on restart
|
// Save state to avoid recalculation on restart
|
||||||
@ -22,17 +23,19 @@ __device__ constexpr const size_t M = 5; //log2(NB_THREADS_2D_Y));
|
|||||||
// Use GPU to greatly accelerate runtime
|
// Use GPU to greatly accelerate runtime
|
||||||
#define GPU_BOOSTED true
|
#define GPU_BOOSTED true
|
||||||
// Depending on what you set, the output label will be as follow :
|
// Depending on what you set, the output label will be as follow :
|
||||||
// | GPU_BOOSTED | LABEL |
|
// ┌─────────────┬───────┐
|
||||||
// |-------------|-------|
|
// │ GPU_BOOSTED │ LABEL │
|
||||||
// | true | GPU |
|
// ├─────────────┼───────┤
|
||||||
// | false | CPU |
|
// │ true │ GPU │
|
||||||
|
// │ false │ CPU │
|
||||||
|
// └─────────────┴───────┘
|
||||||
|
|
||||||
// Number of weak classifiers
|
// Number of weak classifiers
|
||||||
// const size_t TS[] = { 1 };
|
// [[maybe_unused]] constexpr const std::array TS{ 1 };
|
||||||
// const size_t TS[] = { 1, 5, 10 };
|
// [[maybe_unused]] constexpr const std::array TS{ 1, 5, 10 };
|
||||||
const size_t TS[] = { 1, 5, 10, 25, 50 };
|
[[maybe_unused]] constexpr const std::array TS{ 1, 5, 10, 25, 50 };
|
||||||
// const size_t TS[] = { 1, 5, 10, 25, 50, 100, 200, 300 };
|
// [[maybe_unused]] constexpr const std::array TS{ 1, 5, 10, 25, 50, 100, 200, 300 };
|
||||||
// const size_t TS[] = { 1, 5, 10, 25, 50, 100, 200, 300, 400, 500, 1000 };
|
// [[maybe_unused]] constexpr const std::array TS{ 1, 5, 10, 25, 50, 100, 200, 300, 400, 500, 1000 };
|
||||||
|
|
||||||
// Enable verbose output (for debugging purposes)
|
// Enable verbose output (for debugging purposes)
|
||||||
#define __DEBUG false
|
#define __DEBUG false
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#define BUFFER_SIZE 256
|
#define BUFFER_SIZE 256
|
||||||
#define STRING_INT_SIZE 8 // Length of a number in log10 (including '-')
|
#define STRING_INT_SIZE 8 // Length of a number in log10 (including '-')
|
||||||
#define S(N) std::string(N, '-').c_str()
|
|
||||||
|
|
||||||
#ifndef __CUDACC__
|
#ifndef __CUDACC__
|
||||||
#define __host__
|
#define __host__
|
||||||
|
152
cpp/projet.cpp
152
cpp/projet.cpp
@ -27,10 +27,11 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
for (const char* const folder_name : { "models", "out" })
|
for (const char* const folder_name : { "models", "out" })
|
||||||
fs::create_directory(folder_name);
|
fs::create_directory(folder_name);
|
||||||
|
|
||||||
printf("| %-49s | %-18s | %-29s |\n", "Preprocessing", "Time spent (ns)", "Formatted time spent");
|
const std::chrono::system_clock::time_point preproc_timestamp = perf_counter_ns();
|
||||||
printf("|%s|%s|%s|\n", S(51), S(20), S(31));
|
const std::array<int32_t, 3> preproc_gaps = { 49, -18, 29 };
|
||||||
|
header({ "Preprocessing", "Time spent (ns)", "Formatted time spent" }, preproc_gaps);
|
||||||
|
|
||||||
const auto [ X_train, y_train, X_test, y_test ] = state_saver<uint8_t, 4>("Loading sets", {"X_train", "y_train", "X_test", "y_test"},
|
const auto [ X_train, y_train, X_test, y_test ] = state_saver<uint8_t, 4>("Loading sets", preproc_gaps[0], {"X_train", "y_train", "X_test", "y_test"},
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, load_datasets);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, load_datasets);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
@ -48,7 +49,7 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
print(y_test, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
print(y_test, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const np::Array<uint8_t> feats = state_saver<uint8_t>("Building features", "feats",
|
const np::Array<uint8_t> feats = state_saver<uint8_t>("Building features", preproc_gaps[0], "feats",
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, build_features, X_train.shape[1], X_train.shape[2]);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, build_features, X_train.shape[1], X_train.shape[2]);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
@ -57,9 +58,9 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
print_feat(feats, { IDX_INSPECT });
|
print_feat(feats, { IDX_INSPECT });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const np::Array<uint32_t> X_train_ii = state_saver<uint32_t>("Converting training set to integral images (" LABEL ")", "X_train_ii_" LABEL,
|
const np::Array<uint32_t> X_train_ii = state_saver<uint32_t>("Converting training set to integral images (" LABEL ")", preproc_gaps[0], "X_train_ii_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, set_integral_image, X_train);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, set_integral_image, X_train);
|
||||||
const np::Array<uint32_t> X_test_ii = state_saver<uint32_t>("Converting testing set to integral images (" LABEL ")", "X_test_ii_" LABEL,
|
const np::Array<uint32_t> X_test_ii = state_saver<uint32_t>("Converting testing set to integral images (" LABEL ")", preproc_gaps[0], "X_test_ii_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, set_integral_image, X_test);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, set_integral_image, X_test);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
@ -71,9 +72,9 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
print(X_test_ii, { IDX_INSPECT });
|
print(X_test_ii, { IDX_INSPECT });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const np::Array<int32_t> X_train_feat = state_saver<int32_t>("Applying features to training set (" LABEL ")", "X_train_feat_" LABEL,
|
const np::Array<int32_t> X_train_feat = state_saver<int32_t>("Applying features to training set (" LABEL ")", preproc_gaps[0], "X_train_feat_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, apply_features, feats, X_train_ii);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, apply_features, feats, X_train_ii);
|
||||||
const np::Array<int32_t> X_test_feat = state_saver<int32_t>("Applying features to testing set (" LABEL ")", "X_test_feat_" LABEL,
|
const np::Array<int32_t> X_test_feat = state_saver<int32_t>("Applying features to testing set (" LABEL ")", preproc_gaps[0], "X_test_feat_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, apply_features, feats, X_test_ii);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, apply_features, feats, X_test_ii);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
@ -92,7 +93,7 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
// print_feature(indices);
|
// print_feature(indices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const np::Array<uint16_t> X_train_feat_argsort = state_saver<uint16_t>("Precalculating training set argsort (" LABEL ")", "X_train_feat_argsort_" LABEL,
|
const np::Array<uint16_t> X_train_feat_argsort = state_saver<uint16_t>("Precalculating training set argsort (" LABEL ")", preproc_gaps[0], "X_train_feat_argsort_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, argsort_2d, X_train_feat);
|
FORCE_REDO, SAVE_STATE, OUT_DIR, argsort_2d, X_train_feat);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
@ -101,35 +102,38 @@ std::tuple<np::Array<int32_t>, np::Array<uint16_t>, np::Array<uint8_t>, np::Arra
|
|||||||
print(X_train_feat_argsort, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
print(X_train_feat_argsort, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const np::Array<uint16_t> X_test_feat_argsort = state_saver<uint16_t>("Precalculating testing set argsort (" LABEL ")", "X_test_feat_argsort_" LABEL,
|
// const np::Array<uint16_t> X_test_feat_argsort = state_saver<uint16_t>("Precalculating testing set argsort (" LABEL ")", preproc_gaps[0], "X_test_feat_argsort_" LABEL,
|
||||||
FORCE_REDO, SAVE_STATE, OUT_DIR, argsort_2d, X_test_feat);
|
// FORCE_REDO, SAVE_STATE, OUT_DIR, argsort_2d, X_test_feat);
|
||||||
|
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
print("X_test_feat_argsort");
|
// printf("X_test_feat_argsort\n");
|
||||||
print(X_test_feat_argsort.shape);
|
// print(X_test_feat_argsort.shape);
|
||||||
print(X_test_feat_argsort, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
// print(X_test_feat_argsort, { IDX_INSPECT, IDX_INSPECT + IDX_INSPECT_OFFSET });
|
||||||
#endif
|
#endif
|
||||||
|
const long long time_spent = duration_ns(perf_counter_ns() - preproc_timestamp);
|
||||||
|
formatted_line(preproc_gaps, "├", "┼", "─", "┤");
|
||||||
|
formatted_row(preproc_gaps, { "Preprocessing summary", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
|
footer(preproc_gaps);
|
||||||
return { X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test };
|
return { X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test };
|
||||||
}
|
}
|
||||||
|
|
||||||
void train(const np::Array<int32_t>& X_train_feat, const np::Array<uint16_t>& X_train_feat_argsort, const np::Array<uint8_t>& y_train) {
|
std::array<std::array<np::Array<float64_t>, 2>, TS.size()> train(const np::Array<int32_t>& X_train_feat, const np::Array<uint16_t>& X_train_feat_argsort, const np::Array<uint8_t>& y_train) noexcept {
|
||||||
printf("\n| %-49s | %-18s | %-29s |\n", "Training", "Time spent (ns)", "Formatted time spent");
|
const std::chrono::system_clock::time_point training_timestamp = perf_counter_ns();
|
||||||
printf("|%s|%s|%s|\n", S(51), S(20), S(31));
|
const std::array<int32_t, 3> training_gaps = { 26, -18, 29 };
|
||||||
|
header({ "Training", "Time spent (ns)", "Formatted time spent" }, training_gaps);
|
||||||
|
|
||||||
|
std::array<std::array<np::Array<float64_t>, 2>, TS.size()> models;
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
for (const size_t T : TS) {
|
for (const size_t T : TS) {
|
||||||
char title[BUFFER_SIZE] = { 0 };
|
char title[BUFFER_SIZE] = { 0 };
|
||||||
char alphas_title[BUFFER_SIZE] = { 0 };
|
char alphas_title[BUFFER_SIZE] = { 0 };
|
||||||
char final_classifiers_title[BUFFER_SIZE] = { 0 };
|
char final_classifiers_title[BUFFER_SIZE] = { 0 };
|
||||||
sprintf(title, "ViolaJones T = %-4lu (%s)", T, LABEL);
|
snprintf(title, BUFFER_SIZE, "ViolaJones T = %-4lu (%s)", T, LABEL);
|
||||||
sprintf(alphas_title, "alphas_%lu_%s", T, LABEL);
|
snprintf(alphas_title, BUFFER_SIZE, "alphas_%lu_%s", T, LABEL);
|
||||||
sprintf(final_classifiers_title, "final_classifiers_%lu_%s", T, LABEL);
|
snprintf(final_classifiers_title, BUFFER_SIZE, "final_classifiers_%lu_%s", T, LABEL);
|
||||||
|
|
||||||
#if __DEBUG
|
const auto [ alphas, final_classifiers ] = state_saver<float64_t, 2>(title, training_gaps[0], { alphas_title, final_classifiers_title },
|
||||||
const auto [ alphas, final_classifiers ] = state_saver<float64_t, 2>(title, { alphas_title, final_classifiers_title },
|
|
||||||
#else
|
|
||||||
state_saver<float64_t, 2>(title, { alphas_title, final_classifiers_title },
|
|
||||||
#endif
|
|
||||||
FORCE_REDO, SAVE_STATE, MODEL_DIR, train_viola_jones, T, X_train_feat, X_train_feat_argsort, y_train);
|
FORCE_REDO, SAVE_STATE, MODEL_DIR, train_viola_jones, T, X_train_feat, X_train_feat_argsort, y_train);
|
||||||
#if __DEBUG
|
#if __DEBUG
|
||||||
print("alphas");
|
print("alphas");
|
||||||
@ -137,31 +141,32 @@ void train(const np::Array<int32_t>& X_train_feat, const np::Array<uint16_t>& X_
|
|||||||
print("final_classifiers");
|
print("final_classifiers");
|
||||||
print(final_classifiers);
|
print(final_classifiers);
|
||||||
#endif
|
#endif
|
||||||
|
models[i++] = { alphas, final_classifiers };
|
||||||
}
|
}
|
||||||
|
const long long time_spent = duration_ns(perf_counter_ns() - training_timestamp);
|
||||||
|
formatted_line(training_gaps, "├", "┼", "─", "┤");
|
||||||
|
formatted_row(training_gaps, { "Training summary", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
|
footer(training_gaps);
|
||||||
|
|
||||||
|
return models;
|
||||||
}
|
}
|
||||||
|
|
||||||
void testing_and_evaluating(const np::Array<int32_t>& X_train_feat, const np::Array<uint8_t>& y_train, const np::Array<int32_t>& X_test_feat, const np::Array<uint8_t>& y_test) {
|
void testing_and_evaluating(const std::array<std::array<np::Array<float64_t>, 2>, TS.size()>& models, const np::Array<int32_t>& X_train_feat, const np::Array<uint8_t>& y_train, const np::Array<int32_t>& X_test_feat, const np::Array<uint8_t>& y_test) {
|
||||||
printf("\n| %-26s | Time spent (ns) (E) | %-29s | Time spent (ns) (T) | %-29s |\n", "Testing", "Formatted time spent (E)", "Formatted time spent (T)");
|
const std::array<int32_t, 5> testing_gaps = { 26, -19, 24, -19, 24 };
|
||||||
printf("|%s|%s|%s|%s|%s|\n", S(28), S(21), S(31), S(21), S(31));
|
header({ "Testing", "Time spent (ns) (E)", "Formatted time spent (E)", "Time spent (ns) (T)", "Formatted time spent (T)" }, testing_gaps);
|
||||||
|
std::array<std::array<float64_t, 8>, TS.size()> results;
|
||||||
constexpr const size_t NT = sizeof(TS) / sizeof(size_t);
|
|
||||||
std::array<std::array<float64_t, 8>, NT> results;
|
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
for (const size_t T : TS) {
|
long long total_train_timestamp = 0;
|
||||||
|
long long total_test_timestamp = 0;
|
||||||
|
for (const auto& [ alphas, final_classifiers ] : models) {
|
||||||
char title[BUFFER_SIZE] = { 0 };
|
char title[BUFFER_SIZE] = { 0 };
|
||||||
char alphas_title[BUFFER_SIZE] = { 0 };
|
snprintf(title, BUFFER_SIZE, "ViolaJones T = %-4i (%s)", TS[i], LABEL);
|
||||||
char final_classifiers_title[BUFFER_SIZE] = { 0 };
|
|
||||||
sprintf(title, "ViolaJones T = %-4lu (%s)", T, LABEL);
|
|
||||||
sprintf(alphas_title, MODEL_DIR "/alphas_%lu_%s.bin", T, LABEL);
|
|
||||||
sprintf(final_classifiers_title, MODEL_DIR "/final_classifiers_%lu_%s.bin", T, LABEL);
|
|
||||||
|
|
||||||
const np::Array<float64_t> alphas = load<float64_t>(alphas_title);
|
|
||||||
const np::Array<float64_t> final_classifiers = load<float64_t>(final_classifiers_title);
|
|
||||||
|
|
||||||
std::chrono::system_clock::time_point start = perf_counter_ns();
|
std::chrono::system_clock::time_point start = perf_counter_ns();
|
||||||
const np::Array<uint8_t> y_pred_train = classify_viola_jones(alphas, final_classifiers, X_train_feat);
|
const np::Array<uint8_t> y_pred_train = classify_viola_jones(alphas, final_classifiers, X_train_feat);
|
||||||
const long long t_pred_train = duration_ns(perf_counter_ns() - start);
|
const long long t_pred_train = duration_ns(perf_counter_ns() - start);
|
||||||
|
total_train_timestamp += t_pred_train;
|
||||||
const float64_t e_acc = accuracy_score(y_train, y_pred_train);
|
const float64_t e_acc = accuracy_score(y_train, y_pred_train);
|
||||||
const float64_t e_f1 = f1_score(y_train, y_pred_train);
|
const float64_t e_f1 = f1_score(y_train, y_pred_train);
|
||||||
float64_t e_FN, e_FP;
|
float64_t e_FN, e_FP;
|
||||||
@ -170,48 +175,53 @@ void testing_and_evaluating(const np::Array<int32_t>& X_train_feat, const np::Ar
|
|||||||
start = perf_counter_ns();
|
start = perf_counter_ns();
|
||||||
const np::Array<uint8_t> y_pred_test = classify_viola_jones(alphas, final_classifiers, X_test_feat);
|
const np::Array<uint8_t> y_pred_test = classify_viola_jones(alphas, final_classifiers, X_test_feat);
|
||||||
const long long t_pred_test = duration_ns(perf_counter_ns() - start);
|
const long long t_pred_test = duration_ns(perf_counter_ns() - start);
|
||||||
|
total_test_timestamp += t_pred_test;
|
||||||
const float64_t t_acc = accuracy_score(y_test, y_pred_test);
|
const float64_t t_acc = accuracy_score(y_test, y_pred_test);
|
||||||
const float64_t t_f1 = f1_score(y_test, y_pred_test);
|
const float64_t t_f1 = f1_score(y_test, y_pred_test);
|
||||||
float64_t t_FN, t_FP;
|
float64_t t_FN, t_FP;
|
||||||
std::tie(std::ignore, t_FN, t_FP, std::ignore) = confusion_matrix(y_test, y_pred_test);
|
std::tie(std::ignore, t_FN, t_FP, std::ignore) = confusion_matrix(y_test, y_pred_test);
|
||||||
results[i++] = { e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP };
|
results[i++] = { e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP };
|
||||||
|
|
||||||
printf("| %-26s | %'19lld | %-29s | %'19lld | %-29s |\n", title, t_pred_train, format_time_ns(t_pred_train).c_str(), t_pred_test, format_time_ns(t_pred_test).c_str());
|
formatted_row(testing_gaps, { title, thousand_sep(t_pred_train).c_str(), format_time_ns(t_pred_train).c_str(), thousand_sep(t_pred_test).c_str(), format_time_ns(t_pred_test).c_str() });
|
||||||
}
|
}
|
||||||
|
formatted_line(testing_gaps, "├", "┼", "─", "┤");
|
||||||
|
formatted_row(testing_gaps, { "Testing summary", thousand_sep(total_train_timestamp).c_str(), format_time_ns(total_train_timestamp).c_str(), thousand_sep(total_test_timestamp).c_str(), format_time_ns(total_test_timestamp).c_str() });
|
||||||
|
footer(testing_gaps);
|
||||||
|
|
||||||
printf("\n| %-19s | ACC (E) | F1 (E) | FN (E) | FP (E) | ACC (T) | F1 (T) | FN (T) | FP (T) |\n", "Evaluating");
|
const std::array<int32_t, 9> evaluating_gaps = { 19, -7, -6, -6, -6, -7, -6, -6, -6 };
|
||||||
printf("|%s|%s|%s|%s|%s|%s|%s|%s|%s|\n", S(21), S(9), S(8), S(8), S(8), S(9), S(8), S(8), S(8));
|
header({ "Evaluating", "ACC (E)", "F1 (E)", "FN (E)", "FP (E)", "ACC (T)", "F1 (T)", "FN (T)", "FP (T)"}, evaluating_gaps);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (const size_t T : TS) {
|
for (const size_t T : TS) {
|
||||||
char title[BUFFER_SIZE] = { 0 };
|
char title[BUFFER_SIZE] = { 0 };
|
||||||
sprintf(title, "ViolaJones T = %-4lu", T);
|
snprintf(title, BUFFER_SIZE, "ViolaJones T = %-4lu", T);
|
||||||
const auto [e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP] = results[i++];
|
const auto [e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP] = results[i++];
|
||||||
printf("| %-19s | %'6.2f%% | %'6.2f | %'6.0f | %'6.0f | %6.2f%% | %'6.2f | %'6.0f | %'6.0f |\n", title, e_acc * 100, e_f1, e_FN, e_FP, t_acc * 100, t_f1, t_FN, t_FP);
|
printf("│ %-19s │ %'6.2f%% │ %'6.2f │ %'6.0f │ %'6.0f │ %6.2f%% │ %'6.2f │ %'6.0f │ %'6.0f │\n", title, e_acc * 100, e_f1, e_FN, e_FP, t_acc * 100, t_f1, t_FN, t_FP);
|
||||||
}
|
}
|
||||||
|
footer(evaluating_gaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void unit_test(void) {
|
void unit_test(void) {
|
||||||
printf("\n| %-37s | %-10s | %-18s | %-29s |\n", "Unit testing", "Test state", "Time spent (ns)", "Formatted time spent");
|
const std::chrono::system_clock::time_point unit_timestamp = perf_counter_ns();
|
||||||
printf("|%s|%s|%s|%s|\n", S(39), S(12), S(20), S(31));
|
const std::array<int32_t, 4> unit_gaps = { 37, -10, -18, 29};
|
||||||
|
header({ "Unit testing", "Test state", "Time spent (ns)", "Formatted time spent" }, unit_gaps);
|
||||||
|
|
||||||
char title[BUFFER_SIZE] = { 0 };
|
char title[BUFFER_SIZE] = { 0 };
|
||||||
char tmp_title[BUFFER_SIZE / 2] = { 0 };
|
char tmp_title[BUFFER_SIZE / 2] = { 0 };
|
||||||
char file_cpu[BUFFER_SIZE] = { 0 };
|
char file_cpu[BUFFER_SIZE] = { 0 };
|
||||||
char file_gpu[BUFFER_SIZE] = { 0 };
|
char file_gpu[BUFFER_SIZE] = { 0 };
|
||||||
const std::chrono::system_clock::time_point fnc_s = perf_counter_ns();
|
|
||||||
uint64_t n_total = 0, n_success = 0;
|
uint64_t n_total = 0, n_success = 0;
|
||||||
|
|
||||||
auto test_fnc = [&n_total, &n_success](const char* title, const auto& fnc) {
|
const auto test_fnc = [&unit_gaps, &n_total, &n_success](const char* const title, const auto& fnc) noexcept {
|
||||||
++n_total;
|
++n_total;
|
||||||
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
const std::chrono::system_clock::time_point start = perf_counter_ns();
|
||||||
const bool state = fnc();
|
const bool state = fnc();
|
||||||
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
const long long time_spent = duration_ns(perf_counter_ns() - start);
|
||||||
if(state){
|
if(state){
|
||||||
printf("| %-37s | %10s | %18s | %-29s |\n", title, "Passed", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str());
|
formatted_row(unit_gaps, { title, "Passed", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
++n_success;
|
++n_success;
|
||||||
} else
|
} else
|
||||||
printf("| %-37s | %10s | %18s | %-29s |\n", title, "Failed", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str());
|
formatted_row(unit_gaps, { title, "Failed", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const char* label : { "train", "test" }) {
|
for (const char* label : { "train", "test" }) {
|
||||||
@ -275,32 +285,38 @@ void unit_test(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const long long time_spent = duration_ns(perf_counter_ns() - fnc_s);
|
const long long time_spent = duration_ns(perf_counter_ns() - unit_timestamp);
|
||||||
sprintf(title, "%ld/%ld", n_success, n_total);
|
snprintf(title, BUFFER_SIZE, "%ld/%ld", n_success, n_total);
|
||||||
|
|
||||||
printf("|%s|%s|%s|%s|\n", S(39), S(12), S(20), S(31));
|
formatted_line(unit_gaps, "├", "┼", "─", "┤");
|
||||||
printf("| %-37s | %10s | %18s | %-29s |\n", "Unit testing summary", title, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str());
|
formatted_row(unit_gaps, { "Unit testing summary", title, thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
|
footer(unit_gaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
setlocale(LC_NUMERIC, ""); // Allow proper number display
|
setlocale(LC_NUMERIC, ""); // Allow proper number display
|
||||||
|
|
||||||
printf("| %-49s | %-18s | %-29s |\n", "Unit testing", "Time spent (ns)", "Formatted time spent");
|
const std::chrono::system_clock::time_point unit_timestamp = perf_counter_ns();
|
||||||
printf("|%s|%s|%s|\n", S(51), S(20), S(31));
|
const std::array<int32_t, 3> unit_gaps = { 27, -18, 29 };
|
||||||
|
header({ "Unit testing", "Time spent (ns)", "Formatted time spent" }, unit_gaps);
|
||||||
#if GPU_BOOSTED
|
#if GPU_BOOSTED
|
||||||
benchmark_function_void("Testing GPU capabilities 1D", test_working, 3 + (1<<29));
|
benchmark_function_void("Testing GPU capabilities 1D", unit_gaps[0], test_working, 50000);
|
||||||
benchmark_function_void("Testing GPU capabilities 2D", test_working_2d, 3 + (1<<15), 2 + (1<<14));
|
benchmark_function_void("Testing GPU capabilities 2D", unit_gaps[0], test_working_2d, 200, 500);
|
||||||
benchmark_function_void("Testing GPU capabilities 3D", test_working_3d, 9 + (1<<10), 5 + (1<<10), 7 + (1<<9));
|
benchmark_function_void("Testing GPU capabilities 3D", unit_gaps[0], test_working_3d, 30, 40, 500);
|
||||||
#endif
|
#endif
|
||||||
benchmark_function_void("Testing format_time", format_time_test);
|
benchmark_function_void("Testing format_time", unit_gaps[0], format_time_test);
|
||||||
benchmark_function_void("Testing format_time_ns", format_time_ns_test);
|
benchmark_function_void("Testing format_time_ns", unit_gaps[0], format_time_ns_test);
|
||||||
benchmark_function_void("Testing format_byte_size", format_byte_size_test);
|
benchmark_function_void("Testing format_byte_size", unit_gaps[0], format_byte_size_test);
|
||||||
benchmark_function_void("Testing thousand_sep", thousand_sep_test);
|
benchmark_function_void("Testing thousand_sep", unit_gaps[0], thousand_sep_test);
|
||||||
printf("\n");
|
const long long time_spent = duration_ns(perf_counter_ns() - unit_timestamp);
|
||||||
|
formatted_line(unit_gaps, "├", "┼", "─", "┤");
|
||||||
|
formatted_row(unit_gaps, { "Unit testing summary", thousand_sep(time_spent).c_str(), format_time_ns(time_spent).c_str() });
|
||||||
|
footer(unit_gaps);
|
||||||
|
|
||||||
const auto [ X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test ] = preprocessing();
|
const auto [ X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test ] = preprocessing();
|
||||||
train(X_train_feat, X_train_feat_argsort, y_train);
|
const std::array<std::array<np::Array<float64_t>, 2>, TS.size()> models = train(X_train_feat, X_train_feat_argsort, y_train);
|
||||||
testing_and_evaluating(X_train_feat, y_train, X_test_feat, y_test);
|
testing_and_evaluating(models, X_train_feat, y_train, X_test_feat, y_test);
|
||||||
unit_test();
|
unit_test();
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,41 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <chrono>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
constexpr void formatted_row(const std::array<int32_t, N>& gaps, const std::array<const char* const, N>& titles,
|
||||||
|
const char* const separator = "│") noexcept {
|
||||||
|
for(size_t i = 0; i < N; ++i)
|
||||||
|
printf("%s %*s ", separator, -gaps[i], titles[i]);
|
||||||
|
printf("%s\n", separator);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
constexpr void formatted_line(const std::array<int32_t, N>& gaps, const char* const right, const char* const middle,
|
||||||
|
const char* const separator, const char* const left) noexcept {
|
||||||
|
printf("%s", right);
|
||||||
|
for(size_t i = 0; i < N; ++i){
|
||||||
|
for(int32_t j = std::abs(gaps[i]) + 2; j > 0; --j)
|
||||||
|
printf("%s", separator);
|
||||||
|
if(i != N - 1)
|
||||||
|
printf("%s", middle);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", left);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
constexpr void header(const std::array<const char* const, N>& titles, const std::array<int32_t, N>& gaps) noexcept {
|
||||||
|
formatted_line(gaps, "┌", "┬", "─", "┐");
|
||||||
|
formatted_row(gaps, titles);
|
||||||
|
formatted_line(gaps, "├", "┼", "─", "┤");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
constexpr inline void footer(const std::array<int32_t, N>& gaps) noexcept {
|
||||||
|
formatted_line(gaps, "└", "┴", "─", "┘");
|
||||||
|
}
|
||||||
|
|
||||||
#define duration_ns(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
|
#define duration_ns(a) std::chrono::duration_cast<std::chrono::nanoseconds>(a).count()
|
||||||
#define perf_counter_ns() std::chrono::high_resolution_clock::now()
|
#define perf_counter_ns() std::chrono::high_resolution_clock::now()
|
||||||
|
@ -1,44 +1,47 @@
|
|||||||
|
from typing import Final
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
DATA_DIR = "../data"
|
DATA_DIR: Final = '../data'
|
||||||
OUT_DIR = "./out"
|
OUT_DIR: Final = './out'
|
||||||
MODEL_DIR = "./models"
|
MODEL_DIR: Final = './models'
|
||||||
|
|
||||||
NB_THREADS = 1024
|
NB_THREADS: Final = 1024
|
||||||
NB_THREADS_2D = (32, 32)
|
NB_THREADS_2D: Final = (32, 32)
|
||||||
NB_THREADS_3D = (16, 16, 4)
|
NB_THREADS_3D: Final = (16, 16, 4)
|
||||||
M = int(np.log2(NB_THREADS_2D[1]))
|
M: Final = int(np.log2(NB_THREADS_2D[1]))
|
||||||
|
|
||||||
# Save state to avoid recalculation on restart
|
# Save state to avoid recalculation on restart
|
||||||
SAVE_STATE = True
|
SAVE_STATE: Final = True
|
||||||
# Redo the state even if it's already saved
|
# Redo the state even if it's already saved
|
||||||
FORCE_REDO = False
|
FORCE_REDO: Final = False
|
||||||
# Use NJIT to greatly accelerate runtime
|
# Use NJIT to greatly accelerate runtime
|
||||||
COMPILE_WITH_C = True
|
COMPILE_WITH_C: Final = True
|
||||||
# Use GPU to greatly accelerate runtime (as priority over NJIT)
|
# Use GPU to greatly accelerate runtime (as priority over NJIT)
|
||||||
GPU_BOOSTED = True
|
GPU_BOOSTED: Final = True
|
||||||
# Depending on what you set, the output label will be as follow :
|
# Depending on what you set, the output label will be as follow :
|
||||||
# | COMPILE_WITH_C | GPU_BOOSTED | LABEL |
|
# ┌────────────────┬─────────────┬───────┐
|
||||||
# |----------------|-------------|-------|
|
# │ COMPILE_WITH_C │ GPU_BOOSTED │ LABEL │
|
||||||
# | True | True | GPU |
|
# ├────────────────┼─────────────┼───────┤
|
||||||
# | True | False | CPU |
|
# │ True │ True │ GPU │
|
||||||
# | False | True | PGPU |
|
# │ True │ False │ CPU │
|
||||||
# | False | False | PY |
|
# │ False │ True │ PGPU │
|
||||||
|
# │ False │ False │ PY │
|
||||||
|
# └────────────────┴─────────────┴───────┘
|
||||||
|
|
||||||
# Number of weak classifiers
|
# Number of weak classifiers
|
||||||
# TS = [1]
|
# TS: Final = [1]
|
||||||
# TS = [1, 5, 10]
|
# TS: Final = [1, 5, 10]
|
||||||
TS = [1, 5, 10, 25, 50]
|
TS: Final = [1, 5, 10, 25, 50]
|
||||||
# TS = [1, 5, 10, 25, 50, 100, 200]
|
# TS: Final = [1, 5, 10, 25, 50, 100, 200]
|
||||||
# TS = [1, 5, 10, 25, 50, 100, 200, 300]
|
# TS: Final = [1, 5, 10, 25, 50, 100, 200, 300]
|
||||||
# TS = [1, 5, 10, 25, 50, 100, 200, 300, 400, 500, 1000]
|
# TS: Final = [1, 5, 10, 25, 50, 100, 200, 300, 400, 500, 1000]
|
||||||
|
|
||||||
# Enable verbose output (for debugging purposes)
|
# Enable verbose output (for debugging purposes)
|
||||||
__DEBUG = False
|
__DEBUG: Final = False
|
||||||
# Debugging options
|
# Debugging options
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
IDX_INSPECT = 4548
|
IDX_INSPECT: Final = 4548
|
||||||
IDX_INSPECT_OFFSET = 100
|
IDX_INSPECT_OFFSET: Final = 100
|
||||||
np.seterr(all = 'raise')
|
np.seterr(all = 'raise')
|
||||||
# Debug option (image width * log_10(length) + extra characters)
|
# Debug option (image width * log_10(length) + extra characters)
|
||||||
np.set_printoptions(linewidth = 19 * 6 + 3)
|
np.set_printoptions(linewidth = 19 * 6 + 3)
|
||||||
|
110
python/projet.py
110
python/projet.py
@ -4,6 +4,7 @@
|
|||||||
from ViolaJones import train_viola_jones, classify_viola_jones
|
from ViolaJones import train_viola_jones, classify_viola_jones
|
||||||
from toolbox import state_saver, picke_multi_loader, format_time_ns, benchmark_function, unit_test_argsort_2d
|
from toolbox import state_saver, picke_multi_loader, format_time_ns, benchmark_function, unit_test_argsort_2d
|
||||||
from toolbox_unit_test import format_time_ns_test
|
from toolbox_unit_test import format_time_ns_test
|
||||||
|
from toolbox import header, footer, formatted_row, formatted_line
|
||||||
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix
|
from sklearn.metrics import accuracy_score, f1_score, confusion_matrix
|
||||||
from sklearn.feature_selection import SelectPercentile, f_classif
|
from sklearn.feature_selection import SelectPercentile, f_classif
|
||||||
from common import load_datasets, unit_test
|
from common import load_datasets, unit_test
|
||||||
@ -38,9 +39,11 @@ def preprocessing() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|||||||
for folder_name in ["models", "out"]:
|
for folder_name in ["models", "out"]:
|
||||||
makedirs(folder_name, exist_ok = True)
|
makedirs(folder_name, exist_ok = True)
|
||||||
|
|
||||||
print(f"| {'Preprocessing':<49} | {'Time spent (ns)':<18} | {'Formatted time spent':<29} |\n|{'-'*51}|{'-'*20}|{'-'*31}|")
|
preproc_timestamp = perf_counter_ns()
|
||||||
|
preproc_gaps = [49, -18, 29]
|
||||||
|
header(['Preprocessing', 'Time spent (ns)', 'Formatted time spent'], preproc_gaps)
|
||||||
|
|
||||||
X_train, y_train, X_test, y_test = state_saver("Loading sets", ["X_train", "y_train", "X_test", "y_test"],
|
X_train, y_train, X_test, y_test = state_saver('Loading sets', preproc_gaps[0], ['X_train', 'y_train', 'X_test', 'y_test'],
|
||||||
load_datasets, FORCE_REDO, SAVE_STATE)
|
load_datasets, FORCE_REDO, SAVE_STATE)
|
||||||
|
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
@ -57,16 +60,17 @@ def preprocessing() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|||||||
print(y_test.shape)
|
print(y_test.shape)
|
||||||
print(y_test[IDX_INSPECT: IDX_INSPECT + IDX_INSPECT_OFFSET])
|
print(y_test[IDX_INSPECT: IDX_INSPECT + IDX_INSPECT_OFFSET])
|
||||||
|
|
||||||
feats = state_saver("Building features", "feats", lambda: build_features(X_train.shape[1], X_train.shape[2]), FORCE_REDO, SAVE_STATE)
|
feats = state_saver('Building features', preproc_gaps[0], 'feats', lambda: build_features(X_train.shape[1], X_train.shape[2]),
|
||||||
|
FORCE_REDO, SAVE_STATE)
|
||||||
|
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
print("feats")
|
print("feats")
|
||||||
print(feats.shape)
|
print(feats.shape)
|
||||||
print(feats[IDX_INSPECT].ravel())
|
print(feats[IDX_INSPECT].ravel())
|
||||||
|
|
||||||
X_train_ii = state_saver(f"Converting training set to integral images ({label})", f"X_train_ii_{label}",
|
X_train_ii = state_saver(f'Converting training set to integral images ({label})', preproc_gaps[0], f'X_train_ii_{label}',
|
||||||
lambda: set_integral_image(X_train), FORCE_REDO, SAVE_STATE)
|
lambda: set_integral_image(X_train), FORCE_REDO, SAVE_STATE)
|
||||||
X_test_ii = state_saver(f"Converting testing set to integral images ({label})", f"X_test_ii_{label}",
|
X_test_ii = state_saver(f'Converting testing set to integral images ({label})', preproc_gaps[0], f'X_test_ii_{label}',
|
||||||
lambda: set_integral_image(X_test), FORCE_REDO, SAVE_STATE)
|
lambda: set_integral_image(X_test), FORCE_REDO, SAVE_STATE)
|
||||||
|
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
@ -77,9 +81,9 @@ def preprocessing() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|||||||
print(X_test_ii.shape)
|
print(X_test_ii.shape)
|
||||||
print(X_test_ii[IDX_INSPECT])
|
print(X_test_ii[IDX_INSPECT])
|
||||||
|
|
||||||
X_train_feat = state_saver(f"Applying features to training set ({label})", f"X_train_feat_{label}",
|
X_train_feat = state_saver(f'Applying features to training set ({label})', preproc_gaps[0], f'X_train_feat_{label}',
|
||||||
lambda: apply_features(feats, X_train_ii), FORCE_REDO, SAVE_STATE)
|
lambda: apply_features(feats, X_train_ii), FORCE_REDO, SAVE_STATE)
|
||||||
X_test_feat = state_saver(f"Applying features to testing set ({label})", f"X_test_feat_{label}",
|
X_test_feat = state_saver(f'Applying features to testing set ({label})', preproc_gaps[0], f'X_test_feat_{label}',
|
||||||
lambda: apply_features(feats, X_test_ii), FORCE_REDO, SAVE_STATE)
|
lambda: apply_features(feats, X_test_ii), FORCE_REDO, SAVE_STATE)
|
||||||
del X_train_ii, X_test_ii, feats
|
del X_train_ii, X_test_ii, feats
|
||||||
|
|
||||||
@ -106,14 +110,14 @@ def preprocessing() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|||||||
|
|
||||||
# X_train_feat, X_test_feat = X_train_feat[indices], X_test_feat[indices]
|
# X_train_feat, X_test_feat = X_train_feat[indices], X_test_feat[indices]
|
||||||
|
|
||||||
X_train_feat_argsort = state_saver(f"Precalculating training set argsort ({label})", f"X_train_feat_argsort_{label}",
|
X_train_feat_argsort = state_saver(f'Precalculating training set argsort ({label})', preproc_gaps[0], f'X_train_feat_argsort_{label}',
|
||||||
lambda: argsort(X_train_feat), FORCE_REDO, SAVE_STATE)
|
lambda: argsort(X_train_feat), FORCE_REDO, SAVE_STATE)
|
||||||
|
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
print("X_train_feat_argsort")
|
print("X_train_feat_argsort")
|
||||||
print(X_train_feat_argsort.shape)
|
print(X_train_feat_argsort.shape)
|
||||||
print(X_train_feat_argsort[IDX_INSPECT, : IDX_INSPECT_OFFSET])
|
print(X_train_feat_argsort[IDX_INSPECT, : IDX_INSPECT_OFFSET])
|
||||||
benchmark_function("Arg unit test", lambda: unit_test_argsort_2d(X_train_feat, X_train_feat_argsort))
|
benchmark_function('Arg unit test', preproc_gaps[0], lambda: unit_test_argsort_2d(X_train_feat, X_train_feat_argsort))
|
||||||
|
|
||||||
X_test_feat_argsort = state_saver(f"Precalculating testing set argsort ({label})", f"X_test_feat_argsort_{label}",
|
X_test_feat_argsort = state_saver(f"Precalculating testing set argsort ({label})", f"X_test_feat_argsort_{label}",
|
||||||
lambda: argsort(X_test_feat), FORCE_REDO, SAVE_STATE)
|
lambda: argsort(X_test_feat), FORCE_REDO, SAVE_STATE)
|
||||||
@ -123,48 +127,70 @@ def preprocessing() -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|||||||
print(X_test_feat_argsort.shape)
|
print(X_test_feat_argsort.shape)
|
||||||
print(X_test_feat_argsort[IDX_INSPECT, : IDX_INSPECT_OFFSET])
|
print(X_test_feat_argsort[IDX_INSPECT, : IDX_INSPECT_OFFSET])
|
||||||
benchmark_function("Arg unit test", lambda: unit_test_argsort_2d(X_test_feat, X_test_feat_argsort))
|
benchmark_function("Arg unit test", lambda: unit_test_argsort_2d(X_test_feat, X_test_feat_argsort))
|
||||||
|
time_spent = perf_counter_ns() - preproc_timestamp
|
||||||
|
formatted_line(preproc_gaps, '├', '┼', '─', '┤')
|
||||||
|
formatted_row(preproc_gaps, ['Preprocessing summary', f'{time_spent:,}', format_time_ns(time_spent)])
|
||||||
|
footer(preproc_gaps)
|
||||||
|
|
||||||
return X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test
|
return X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test
|
||||||
|
|
||||||
def train(X_train_feat: np.ndarray, X_train_feat_argsort: np.ndarray, y_train: np.ndarray) -> None:
|
def train(X_train_feat: np.ndarray, X_train_feat_argsort: np.ndarray, y_train: np.ndarray) -> List[np.ndarray]:
|
||||||
"""Train the weak classifiers.
|
"""Train the weak classifiers.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
X_train (np.ndarray): Training images.
|
X_train (np.ndarray): Training images.
|
||||||
X_test (np.ndarray): Testing Images.
|
X_train_feat_argsort (np.ndarray): Sorted indexes of the training images features.
|
||||||
y_train (np.ndarray): Training labels.
|
y_train (np.ndarray): Training labels.
|
||||||
|
|
||||||
|
Returns: List of trained models
|
||||||
"""
|
"""
|
||||||
print(f"\n| {'Training':<49} | {'Time spent (ns)':<18} | {'Formatted time spent':<29} |\n|{'-'*51}|{'-'*20}|{'-'*31}|")
|
|
||||||
|
training_timestamp = perf_counter_ns()
|
||||||
|
training_gaps = [26, -18, 29]
|
||||||
|
header(['Training', 'Time spent (ns)', 'Formatted time spent'], training_gaps)
|
||||||
|
models = []
|
||||||
|
|
||||||
for T in TS:
|
for T in TS:
|
||||||
alphas, final_classifiers = state_saver(f"ViolaJones T = {T:<3} ({label})", [f"alphas_{T}_{label}", f"final_classifiers_{T}_{label}"],
|
alphas, final_classifiers = state_saver(f'ViolaJones T = {T:<4} ({label})', training_gaps[0],
|
||||||
lambda: train_viola_jones(T, X_train_feat, X_train_feat_argsort, y_train), FORCE_REDO, SAVE_STATE, MODEL_DIR)
|
[f'alphas_{T}_{label}', f'final_classifiers_{T}_{label}'],
|
||||||
|
lambda: train_viola_jones(T, X_train_feat, X_train_feat_argsort, y_train), FORCE_REDO, SAVE_STATE, MODEL_DIR)
|
||||||
|
models.append([alphas, final_classifiers])
|
||||||
|
|
||||||
if __DEBUG:
|
if __DEBUG:
|
||||||
print("alphas")
|
print("alphas")
|
||||||
print(alphas)
|
print(alphas)
|
||||||
print("final_classifiers")
|
print("final_classifiers")
|
||||||
print(final_classifiers)
|
print(final_classifiers)
|
||||||
|
|
||||||
def testing_and_evaluating(X_train_feat: np.ndarray, y_train: np.ndarray, X_test_feat: np.ndarray, y_test: np.ndarray) -> None:
|
time_spent = perf_counter_ns() - training_timestamp
|
||||||
|
formatted_line(training_gaps, '├', '┼', '─', '┤')
|
||||||
|
formatted_row(training_gaps, ['Training summary', f'{time_spent:,}', format_time_ns(time_spent)])
|
||||||
|
footer(training_gaps)
|
||||||
|
|
||||||
|
return models
|
||||||
|
|
||||||
|
def testing_and_evaluating(models: List[np.ndarray], X_train_feat: np.ndarray, y_train: np.ndarray, X_test_feat: np.ndarray, y_test: np.ndarray) -> None:
|
||||||
"""Benchmark the trained classifiers on the training and testing sets.
|
"""Benchmark the trained classifiers on the training and testing sets.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
models (List[np.ndarray]): List of trained models.
|
||||||
X_train_feat (np.ndarray): Training features.
|
X_train_feat (np.ndarray): Training features.
|
||||||
y_train (np.ndarray): Training labels.
|
y_train (np.ndarray): Training labels.
|
||||||
X_test_feat (np.ndarray): Testing features.
|
X_test_feat (np.ndarray): Testing features.
|
||||||
y_test (np.ndarray): Testing labels.
|
y_test (np.ndarray): Testing labels.
|
||||||
"""
|
"""
|
||||||
print(f"\n| {'Testing':<26} | Time spent (ns) (E) | {'Formatted time spent (E)':<29}", end = " | ")
|
|
||||||
print(f"Time spent (ns) (T) | {'Formatted time spent (T)':<29} |")
|
|
||||||
print(f"|{'-'*28}|{'-'*21}|{'-'*31}|{'-'*21}|{'-'*31}|")
|
|
||||||
|
|
||||||
perfs = []
|
testing_gaps = [26, -19, 24, -19, 24]
|
||||||
for T in TS:
|
header(['Testing', 'Time spent (ns) (E)', 'Formatted time spent (E)', 'Time spent (ns) (T)', 'Formatted time spent (T)'], testing_gaps)
|
||||||
(alphas, final_classifiers) = picke_multi_loader([f"alphas_{T}_{label}", f"final_classifiers_{T}_{label}"])
|
|
||||||
|
|
||||||
|
performances = []
|
||||||
|
total_train_timestamp = 0
|
||||||
|
total_test_timestamp = 0
|
||||||
|
for T, (alphas, final_classifiers) in zip(TS, models):
|
||||||
s = perf_counter_ns()
|
s = perf_counter_ns()
|
||||||
y_pred_train = classify_viola_jones(alphas, final_classifiers, X_train_feat)
|
y_pred_train = classify_viola_jones(alphas, final_classifiers, X_train_feat)
|
||||||
t_pred_train = perf_counter_ns() - s
|
t_pred_train = perf_counter_ns() - s
|
||||||
|
total_train_timestamp += t_pred_train
|
||||||
e_acc = accuracy_score(y_train, y_pred_train)
|
e_acc = accuracy_score(y_train, y_pred_train)
|
||||||
e_f1 = f1_score(y_train, y_pred_train)
|
e_f1 = f1_score(y_train, y_pred_train)
|
||||||
(_, e_FP), (e_FN, _) = confusion_matrix(y_train, y_pred_train)
|
(_, e_FP), (e_FN, _) = confusion_matrix(y_train, y_pred_train)
|
||||||
@ -172,36 +198,48 @@ def testing_and_evaluating(X_train_feat: np.ndarray, y_train: np.ndarray, X_test
|
|||||||
s = perf_counter_ns()
|
s = perf_counter_ns()
|
||||||
y_pred_test = classify_viola_jones(alphas, final_classifiers, X_test_feat)
|
y_pred_test = classify_viola_jones(alphas, final_classifiers, X_test_feat)
|
||||||
t_pred_test = perf_counter_ns() - s
|
t_pred_test = perf_counter_ns() - s
|
||||||
|
total_test_timestamp += t_pred_test
|
||||||
t_acc = accuracy_score(y_test, y_pred_test)
|
t_acc = accuracy_score(y_test, y_pred_test)
|
||||||
t_f1 = f1_score(y_test, y_pred_test)
|
t_f1 = f1_score(y_test, y_pred_test)
|
||||||
(_, t_FP), (t_FN, _) = confusion_matrix(y_test, y_pred_test)
|
(_, t_FP), (t_FN, _) = confusion_matrix(y_test, y_pred_test)
|
||||||
perfs.append((e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP))
|
performances.append((e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP))
|
||||||
|
|
||||||
print(f"| {'ViolaJones T = ' + str(T):<19} {'(' + label + ')':<6}", end = " | ")
|
formatted_row(testing_gaps, [f"{'ViolaJones T = ' + str(T):<19} {'(' + label + ')':<6}", f'{t_pred_train:,}',
|
||||||
print(f"{t_pred_train:>19,} | {format_time_ns(t_pred_train):<29}", end = " | ")
|
format_time_ns(t_pred_train), f'{t_pred_test:,}', format_time_ns(t_pred_test)])
|
||||||
print(f"{t_pred_test:>19,} | {format_time_ns(t_pred_test):<29} |")
|
|
||||||
|
|
||||||
print(f"\n| {'Evaluating':<19} | ACC (E) | F1 (E) | FN (E) | FP (E) | ACC (T) | F1 (T) | FN (T) | FP (T) | ")
|
formatted_line(testing_gaps, '├', '┼', '─', '┤')
|
||||||
print(f"|{'-'*21}|{'-'*9}|{'-'*8}|{'-'*8}|{'-'*8}|{'-'*9}|{'-'*8}|{'-'*8}|{'-'*8}|")
|
formatted_row(testing_gaps, ['Testing summary', f'{total_train_timestamp:,}', format_time_ns(total_train_timestamp), f'{total_test_timestamp:,}',
|
||||||
|
format_time_ns(total_test_timestamp)])
|
||||||
|
footer(testing_gaps)
|
||||||
|
|
||||||
for T, (e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP) in zip(TS, perfs):
|
evaluating_gaps = [19, 7, 6, 6, 6, 7, 6, 6, 6]
|
||||||
print(f"| {'ViolaJones T = ' + str(T):<19} | {e_acc:>7.2%} | {e_f1:>6.2f} | {e_FN:>6,} | {e_FP:>6,}", end = " | ")
|
header(['Evaluating', 'ACC (E)', 'F1 (E)', 'FN (E)', 'FP (E)', 'ACC (T)', 'F1 (T)', 'FN (T)', 'FP (T)'], evaluating_gaps)
|
||||||
print(f"{t_acc:>7.2%} | {t_f1:>6.2f} | {t_FN:>6,} | {t_FP:>6,} |")
|
|
||||||
|
for T, (e_acc, e_f1, e_FN, e_FP, t_acc, t_f1, t_FN, t_FP) in zip(TS, performances):
|
||||||
|
print(f'│ ViolaJones T = {T:<4} │ {e_acc:>7.2%} │ {e_f1:>6.2f} │ {e_FN:>6,} │ {e_FP:>6,}', end = ' │ ')
|
||||||
|
print(f'{t_acc:>7.2%} │ {t_f1:>6.2f} │ {t_FN:>6,} │ {t_FP:>6,} │')
|
||||||
|
|
||||||
|
footer(evaluating_gaps)
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
print(f"| {'Unit testing':<49} | {'Time spent (ns)':<18} | {'Formatted time spent':<29} |")
|
unit_timestamp = perf_counter_ns()
|
||||||
print(f"|{'-'*51}|{'-'*20}|{'-'*31}|")
|
unit_gaps = [27, -18, 29]
|
||||||
benchmark_function("Testing format_time_ns", format_time_ns_test)
|
header(['Unit testing', 'Time spent (ns)', 'Formatted time spent'], unit_gaps)
|
||||||
print()
|
benchmark_function('testing format_time', unit_gaps[0], format_time_test)
|
||||||
|
benchmark_function('testing format_time_ns', unit_gaps[0], format_time_ns_test)
|
||||||
|
time_spent = perf_counter_ns() - unit_timestamp
|
||||||
|
formatted_line(unit_gaps, '├', '┼', '─', '┤')
|
||||||
|
formatted_row(unit_gaps, ['Unit testing summary', f'{time_spent:,}', format_time_ns(time_spent)])
|
||||||
|
footer(unit_gaps)
|
||||||
|
|
||||||
X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test = preprocessing()
|
X_train_feat, X_train_feat_argsort, y_train, X_test_feat, y_test = preprocessing()
|
||||||
train(X_train_feat, X_train_feat_argsort, y_train)
|
models = train(X_train_feat, X_train_feat_argsort, y_train)
|
||||||
|
|
||||||
# X_train_feat, X_test_feat = picke_multi_loader([f"X_train_feat_{label}", f"X_test_feat_{label}"], OUT_DIR)
|
# X_train_feat, X_test_feat = picke_multi_loader([f"X_train_feat_{label}", f"X_test_feat_{label}"], OUT_DIR)
|
||||||
# indices = picke_multi_loader(["indices"], OUT_DIR)[0]
|
# indices = picke_multi_loader(["indices"], OUT_DIR)[0]
|
||||||
# X_train_feat, X_test_feat = X_train_feat[indices], X_test_feat[indices]
|
# X_train_feat, X_test_feat = X_train_feat[indices], X_test_feat[indices]
|
||||||
|
|
||||||
testing_and_evaluating(X_train_feat, y_train, X_test_feat, y_test)
|
testing_and_evaluating(models, X_train_feat, y_train, X_test_feat, y_test)
|
||||||
unit_test(TS)
|
unit_test(TS)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -2,12 +2,35 @@ from typing import Any, Callable, List, Union, Final
|
|||||||
from time import perf_counter_ns
|
from time import perf_counter_ns
|
||||||
from numba import njit
|
from numba import njit
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from sys import stderr
|
||||||
import pickle
|
import pickle
|
||||||
import os
|
import os
|
||||||
from config import MODEL_DIR, OUT_DIR
|
from config import MODEL_DIR, OUT_DIR
|
||||||
from decorators import njit
|
from decorators import njit
|
||||||
|
|
||||||
time_formats: Final = ["ns", "µs", "ms", "s", "m", "h", "j", "w", "M", "y", "c"]
|
time_formats: Final = ["ns", "µs", "ms", "s", "m", "h", "j", "w", "M", "y", "c"]
|
||||||
|
def formatted_row(gaps: list[int], titles: list[str], separator: str = '│') -> None:
|
||||||
|
for gap, title in zip(gaps, titles):
|
||||||
|
print(f"{separator} {title:{'>' if gap < 0 else '<'}{abs(gap)}} ", end = '')
|
||||||
|
print(separator)
|
||||||
|
|
||||||
|
def formatted_line(gaps: list[int], right: str, middle: str, separator: str, left: str) -> None:
|
||||||
|
print(right, end = '')
|
||||||
|
last_gap = len(gaps) - 1
|
||||||
|
for i, gap in enumerate(gaps):
|
||||||
|
print(f'{separator * (abs(gap) + 2)}', end = '')
|
||||||
|
if i != last_gap:
|
||||||
|
print(middle, end = '')
|
||||||
|
print(left)
|
||||||
|
|
||||||
|
def header(titles: list[str], gaps: list[int]) -> None:
|
||||||
|
formatted_line(gaps, '┌', '┬', '─', '┐')
|
||||||
|
formatted_row(gaps, titles)
|
||||||
|
formatted_line(gaps, '├', '┼', '─', '┤')
|
||||||
|
|
||||||
|
def footer(gaps: list[int]) -> None:
|
||||||
|
formatted_line(gaps, '└', '┴', '─', '┘')
|
||||||
|
|
||||||
time_numbers: Final = np.array([1, 1e3, 1e6, 1e9, 6e10, 36e11, 864e11, 6048e11, 26784e11, 31536e12, 31536e14], dtype = np.uint64)
|
time_numbers: Final = np.array([1, 1e3, 1e6, 1e9, 6e10, 36e11, 864e11, 6048e11, 26784e11, 31536e12, 31536e14], dtype = np.uint64)
|
||||||
@njit('str(uint64)')
|
@njit('str(uint64)')
|
||||||
def format_time_ns(time: int) -> str:
|
def format_time_ns(time: int) -> str:
|
||||||
@ -53,7 +76,7 @@ def picke_multi_loader(filenames: List[str], save_dir: str = MODEL_DIR) -> List[
|
|||||||
b.append(None)
|
b.append(None)
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def benchmark_function(step_name: str, fnc: Callable) -> Any:
|
def benchmark_function(step_name: str, column_width: int, fnc: Callable) -> Any:
|
||||||
"""Benchmark a function and display the result of stdout.
|
"""Benchmark a function and display the result of stdout.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -63,14 +86,15 @@ def benchmark_function(step_name: str, fnc: Callable) -> Any:
|
|||||||
Returns:
|
Returns:
|
||||||
Any: Result of the function.
|
Any: Result of the function.
|
||||||
"""
|
"""
|
||||||
print(f"{step_name}...", end = "\r")
|
print(f'{step_name}...', file = stderr, end = '\r')
|
||||||
s = perf_counter_ns()
|
s = perf_counter_ns()
|
||||||
b = fnc()
|
b = fnc()
|
||||||
e = perf_counter_ns() - s
|
e = perf_counter_ns() - s
|
||||||
print(f"| {step_name:<49} | {e:>18,} | {format_time_ns(e):<29} |")
|
print(f'│ {step_name:<{column_width}} │ {e:>18,} │ {format_time_ns(e):<29} │')
|
||||||
return b
|
return b
|
||||||
|
|
||||||
def state_saver(step_name: str, filename: Union[str, List[str]], fnc, force_redo: bool = False, save_state: bool = True, save_dir: str = OUT_DIR) -> Any:
|
def state_saver(step_name: str, column_width: int, filename: Union[str, List[str]], fnc, force_redo: bool = False,
|
||||||
|
save_state: bool = True, save_dir: str = OUT_DIR) -> Any:
|
||||||
"""Either execute a function then saves the result or load the already existing result.
|
"""Either execute a function then saves the result or load the already existing result.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -85,18 +109,18 @@ def state_saver(step_name: str, filename: Union[str, List[str]], fnc, force_redo
|
|||||||
"""
|
"""
|
||||||
if isinstance(filename, str):
|
if isinstance(filename, str):
|
||||||
if not os.path.exists(f"{save_dir}/{filename}.pkl") or force_redo:
|
if not os.path.exists(f"{save_dir}/{filename}.pkl") or force_redo:
|
||||||
b = benchmark_function(step_name, fnc)
|
b = benchmark_function(step_name, column_width, fnc)
|
||||||
if save_state:
|
if save_state:
|
||||||
print(f"Saving results of {step_name}", end = '\r')
|
|
||||||
with open(f"{save_dir}/{filename}.pkl", 'wb') as f:
|
with open(f"{save_dir}/{filename}.pkl", 'wb') as f:
|
||||||
|
print(f'Saving results of {step_name}', file = stderr, end = '\r')
|
||||||
pickle.dump(b, f)
|
pickle.dump(b, f)
|
||||||
print(' ' * 100, end = '\r')
|
print(' ' * 100, file = stderr, end = '\r')
|
||||||
return b
|
return b
|
||||||
else:
|
else:
|
||||||
print(f"Loading results of {step_name}", end = '\r')
|
|
||||||
with open(f"{save_dir}/{filename}.pkl", "rb") as f:
|
with open(f"{save_dir}/{filename}.pkl", "rb") as f:
|
||||||
|
print(f'Loading results of {step_name}', file = stderr, end = '\r')
|
||||||
res = pickle.load(f)
|
res = pickle.load(f)
|
||||||
print(f"| {step_name:<49} | {'None':>18} | {'loaded saved state':<29} |")
|
print(f"│ {step_name:<{column_width}} │ {'None':>18} │ {'loaded saved state':<29} │")
|
||||||
return res
|
return res
|
||||||
elif isinstance(filename, list):
|
elif isinstance(filename, list):
|
||||||
abs = False
|
abs = False
|
||||||
@ -105,22 +129,22 @@ def state_saver(step_name: str, filename: Union[str, List[str]], fnc, force_redo
|
|||||||
abs = True
|
abs = True
|
||||||
break
|
break
|
||||||
if abs or force_redo:
|
if abs or force_redo:
|
||||||
b = benchmark_function(step_name, fnc)
|
b = benchmark_function(step_name, column_width, fnc)
|
||||||
if save_state:
|
if save_state:
|
||||||
print(f"Saving results of {step_name}", end = '\r')
|
print(f'Saving results of {step_name}', file = stderr, end = '\r')
|
||||||
for bi, fnI in zip(b, filename):
|
for bi, fnI in zip(b, filename):
|
||||||
with open(f"{save_dir}/{fnI}.pkl", 'wb') as f:
|
with open(f"{save_dir}/{fnI}.pkl", 'wb') as f:
|
||||||
pickle.dump(bi, f)
|
pickle.dump(bi, f)
|
||||||
print(' ' * 100, end = '\r')
|
print(' ' * 100, file = stderr, end = '\r')
|
||||||
return b
|
return b
|
||||||
|
|
||||||
print(f"| {step_name:<49} | {'None':>18} | {'loaded saved state':<29} |")
|
print(f"│ {step_name:<{column_width}} │ {'None':>18} │ {'loaded saved state':<29} │")
|
||||||
b = []
|
b = []
|
||||||
print(f"Loading results of {step_name}", end = '\r')
|
print(f'Loading results of {step_name}', file = stderr, end = '\r')
|
||||||
for fn in filename:
|
for fn in filename:
|
||||||
with open(f"{save_dir}/{fn}.pkl", "rb") as f:
|
with open(f"{save_dir}/{fn}.pkl", "rb") as f:
|
||||||
b.append(pickle.load(f))
|
b.append(pickle.load(f))
|
||||||
print(' ' * 100, end = '\r')
|
print(' ' * 100, file = stderr, end = '\r')
|
||||||
return b
|
return b
|
||||||
else:
|
else:
|
||||||
assert False, f"Incompatible filename type = {type(filename)}"
|
assert False, f"Incompatible filename type = {type(filename)}"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user