Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions library/src/solve_board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ auto solve_all_boards_n(
dds::internal::worker_solver_context(),
bds.deals[bno], bds.target[bno], bds.solutions[bno],
bds.mode[bno], &fut);
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(
auto dur = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - t0).count();
if (dur < 0) dur = 0;
scheduler.SetBoardTime(bno, static_cast<int>(dur));
Expand Down Expand Up @@ -280,7 +280,7 @@ auto solve_all_boards_n_seq(
dds::internal::worker_solver_context(),
bds.deals[bno], bds.target[bno], bds.solutions[bno],
bds.mode[bno], &fut);
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(
auto dur = std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - t0).count();
if (dur < 0) dur = 0;
scheduler.SetBoardTime(bno, static_cast<int>(dur));
Expand Down
4 changes: 2 additions & 2 deletions library/src/system/scheduler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,13 +990,13 @@ void Scheduler::GetBoardTimes(std::vector<std::pair<int,int>>& outVec) const
}


void Scheduler::SetBoardTime(int boardIndex, int timeMs)
void Scheduler::SetBoardTime(int boardIndex, int time_us)
{
if (boardIndex < 0 || boardIndex >= MAXNOOFBOARDS) return;
// store in the hand time field; this is a lightweight fallback
// for when DDS_SCHEDULER isn't enabled. No locking required for
// single-writer per-board usage pattern from the solver threads.
hands[boardIndex].time = timeMs;
hands[boardIndex].time = time_us;
}


Expand Down
9 changes: 5 additions & 4 deletions library/src/system/scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,15 @@ class Scheduler
/**
* @brief Retrieve per-board raw times collected by the scheduler.
*
* Fills outVec with pairs (boardIndex, userTimeMs) for each board in
* the current run. This is intended for post-run reporting.
* Fills outVec with pairs (boardIndex, userTimeUs) for each board in
* the current run. Times are wall-clock microseconds. This is intended
* for post-run reporting.
*/
void GetBoardTimes(std::vector<std::pair<int,int>>& outVec) const;

// Lightweight API to set a board's time in ms for reporting when
// Lightweight API to set a board's time in microseconds for reporting when
// full DDS_SCHEDULER timing is not enabled. Thread-safe for single-writer per-board.
void SetBoardTime(int boardIndex, int timeMs);
void SetBoardTime(int boardIndex, int time_us);

// Release timing storage early to avoid heavy destructor work at exit.
void ClearTiming();
Expand Down
17 changes: 17 additions & 0 deletions library/tests/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ filegroup(
"calc_par_test.cpp", # Uses GoogleTest, compiled separately
"test_timer_test.cpp", # Uses GoogleTest, compiled separately
"args_test.cpp", # Uses GoogleTest, compiled separately
"report_board_timings_test.cpp", # Uses GoogleTest, compiled separately
],
),
)
Expand Down Expand Up @@ -105,4 +106,20 @@ cc_test(
],
)

cc_test(
name = "report_board_timings_test",
srcs = [
"report_board_timings_test.cpp",
"report_board_timings.cpp",
"report_board_timings.hpp",
],
size = "small",
copts = DDS_CPPOPTS,
linkopts = DDS_LINKOPTS,
local_defines = DDS_LOCAL_DEFINES,
deps = [
"@googletest//:gtest_main",
],
)


3 changes: 2 additions & 1 deletion library/tests/args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ void usage(
" the modern SolverContext API, prefer configuring\n" <<
" memory via SolverConfig instead of this option.)\n" <<
"\n" <<
"-r, --report Print per-board timings sorted by longest first.\n" <<
"-r, --report Print per-deal timings in ms (one decimal) for every\n" <<
" hand in the input (solve mode), longest first.\n" <<
"\n" <<
endl;
}
Expand Down
14 changes: 13 additions & 1 deletion library/tests/loop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
#include "compare.hpp"
#include "print.hpp"
#include <vector>
#include <utility>

#include "cst.hpp"
#include "dtest_parallel.hpp"
#include "report_board_timings.hpp"
#include <solve_board.hpp>
#include "system/scheduler.hpp"

using std::cout;
using std::endl;
Expand All @@ -32,6 +35,7 @@ using std::right;

extern TestTimer timer;
extern OptionsType options;
extern Scheduler scheduler;


void loop_solve(
Expand All @@ -40,7 +44,8 @@ void loop_solve(
DealPBN * deal_list,
FutureTricks * fut_list,
const int number,
const int stepsize)
const int stepsize,
std::vector<std::pair<int, int>>* board_times)
{
#ifdef BATCHTIMES
cout << setw(8) << left << "Hand no." <<
Expand Down Expand Up @@ -79,6 +84,13 @@ void loop_solve(
}
timer.end();

if (board_times != nullptr)
{
std::vector<std::pair<int, int>> batch_times;
scheduler.GetBoardTimes(batch_times);
append_batch_board_times(*board_times, batch_times, i);
}

#ifdef BATCHTIMES
timer.print_running(i+count, number);
#endif
Expand Down
10 changes: 8 additions & 2 deletions library/tests/loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

#pragma once

#include <utility>
#include <vector>

#include <api/dll.h>

/// @file loop.hpp
Expand All @@ -23,14 +26,17 @@
/// @param deal_list Input deals in PBN format
/// @param fut_list Expected future tricks results
/// @param number Number of deals in test set
/// @param stepsize Reporting frequency
/// @param stepsize Boards per solve batch (typically `MAXNOOFBOARDS`)
/// @param board_times When non-null, appends per-deal timings for every batch
/// with file-relative board indices (for `dtest -r`)
void loop_solve(
BoardsPBN * bop,
SolvedBoards * solvedbdp,
DealPBN * deal_list,
FutureTricks * fut_list,
const int number,
const int stepsize);
const int stepsize,
std::vector<std::pair<int, int>>* board_times = nullptr);

/// Calculate loop: CalcAllTablesPBNX for the full deal list in one parallel job.
/// Allocates its own flat deal/result buffers (unbounded X API); no legacy
Expand Down
92 changes: 92 additions & 0 deletions library/tests/report_board_timings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/// @file report_board_timings.cpp
/// @brief Format dtest `-r` / `--report` per-board timing output.

#include "report_board_timings.hpp"

#include <algorithm>
#include <cstdlib>
#include <iomanip>
#include <sstream>

namespace
{

int decimal_digits(int value)
{
const int n = std::abs(value);
int digits = 1;
int x = n;
while (x >= 10)
{
x /= 10;
++digits;
}
if (value < 0)
++digits;
return digits;
}

int board_column_width(const std::vector<std::pair<int, int>>& times)
{
constexpr int kHeaderWidth = 5; // "board"
int width = kHeaderWidth;
for (const auto& p : times)
width = std::max(width, decimal_digits(p.first));
return width;
}

int ms_column_width(const std::vector<std::pair<int, int>>& times)
{
constexpr int kHeaderWidth = 2; // "ms"
int width = kHeaderWidth;
for (const auto& p : times)
{
std::ostringstream formatted;
formatted << std::fixed << std::setprecision(1)
<< (static_cast<double>(p.second) / 1000.0);
width = std::max(width, static_cast<int>(formatted.str().size()));
}
return width;
}

} // namespace

void print_per_board_timings(
std::ostream& out,
std::vector<std::pair<int, int>> times)
{
std::sort(times.begin(), times.end(), [](const auto& a, const auto& b) {
return a.second > b.second;
});

const int ms_width = ms_column_width(times);
const int board_width = board_column_width(times);

// Preserve caller formatting; setw is one-shot but fixed/precision/align persist.
const auto saved_flags = out.flags();
const auto saved_precision = out.precision();

out << "\nPer-board timings (ms) sorted by longest first:\n\n";
out << std::right << std::setw(ms_width) << "ms" << " "
<< std::setw(board_width) << "board" << "\n";
out << std::fixed << std::setprecision(1);
for (const auto& p : times)
{
out << std::right << std::setw(ms_width)
<< (static_cast<double>(p.second) / 1000.0) << " "
<< std::setw(board_width) << p.first << "\n";
}

out.flags(saved_flags);
out.precision(saved_precision);
}
Comment thread
tameware marked this conversation as resolved.

void append_batch_board_times(
std::vector<std::pair<int, int>>& accumulated,
const std::vector<std::pair<int, int>>& batch_times,
int file_offset)
{
accumulated.reserve(accumulated.size() + batch_times.size());
for (const auto& p : batch_times)
accumulated.emplace_back(p.first + file_offset, p.second);
}
29 changes: 29 additions & 0 deletions library/tests/report_board_timings.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// @file report_board_timings.hpp
/// @brief Format dtest `-r` / `--report` per-board timing output.

#pragma once

#include <ostream>
#include <utility>
#include <vector>

/// Print per-board timings sorted by longest first.
///
/// Each element of @p times is `(board_index, time_us)`, where `board_index`
/// is the 0-based deal index in the input file and `time_us` is wall time in
/// microseconds. Printed times are milliseconds with one decimal place.
/// Both the `ms` and `board` columns are right-aligned with spaces (no tabs).
/// Output includes a title line, a heading line, then one row per board.
void print_per_board_timings(
std::ostream& out,
std::vector<std::pair<int, int>> times);

/// Append one solve-batch's scheduler timings into a file-wide report.
///
/// @p batch_times entries use batch-local indices `(0 .. batch_size-1)`.
/// Each is remapped to `board_index + file_offset` so multi-batch runs
/// (chunks of `MAXNOOFBOARDS`) report every deal in the input file.
void append_batch_board_times(
std::vector<std::pair<int, int>>& accumulated,
const std::vector<std::pair<int, int>>& batch_times,
int file_offset);
Loading