Skip to content

Commit

Permalink
refactor(Log): Clear file write logic
Browse files Browse the repository at this point in the history
  • Loading branch information
HarukiMoriarty committed Apr 10, 2024
1 parent 879a7b3 commit b2050e5
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 171 deletions.
2 changes: 1 addition & 1 deletion calmapf/include/instance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct Instance {
// Assign agent group
void assign_agent_group();
// Simple feasibility check of instance
bool is_valid(const int verbose = 0) const;
void _is_valid(int verbose = 0);
// Check if reached port
bool is_port(Vertex* port) const;

Expand Down
13 changes: 11 additions & 2 deletions calmapf/include/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,22 @@
#pragma once
#include "dist_table.hpp"
#include "instance.hpp"
#include "parser.hpp"
#include "utils.hpp"

struct Log {
// File output handler
std::ofstream throughput_output_handler;
std::ofstream csv_output_handler;
std::ofstream step_output_handler;
std::ofstream visual_output_handler;

Solution step_solution;
Solution life_long_solution;
std::vector<std::vector<uint>> bit_status_log;
std::shared_ptr<spdlog::logger> logger;
std::shared_ptr<spdlog::logger> log_console;

Log(std::shared_ptr<spdlog::logger> _logger);
Log(Parser* parser);
~Log();

bool update_solution(Solution& solution, std::vector<uint> bit_status);
Expand All @@ -26,4 +33,6 @@ struct Log {
void print_stats(const int verbose, const Instance& ins, const double comp_time_ms);
void make_step_log(const Instance& ins, const std::string& output_name, const double comp_time_ms, const std::string& map_name, const int seed, const bool log_short = false);
void make_life_long_log(const Instance& ins, std::string visual_name);
void make_throughput_log(uint index, uint start_cnt, uint make_span);
void make_csv_log(double cache_hit_rate, uint make_span, std::vector<uint>* step_percentiles, bool failure);
};
14 changes: 0 additions & 14 deletions calmapf/include/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,6 @@

using Time = std::chrono::steady_clock;

// Lacam info struct, keep it here for now
template <typename Head, typename... Tail>
void info(const int level, const int verbose, Head&& head, Tail&&... tail);

void info(const int level, const int verbose);

template <typename Head, typename... Tail>
void info(const int level, const int verbose, Head&& head, Tail&&... tail)
{
if (verbose < level) return;
std::cout << head;
info(level, verbose, std::forward<Tail>(tail)...);
}

// Time manager
struct Deadline {
Time::time_point t_s;
Expand Down
8 changes: 5 additions & 3 deletions calmapf/src/instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@ Instance::Instance(Parser* _parser) : graph(Graph(_parser)), parser(_parser)
if (goals.size() == parser->num_agents) break;
++j;
}

// check instance
_is_valid(parser->verbose_level);
}

bool Instance::is_valid(const int verbose) const
void Instance::_is_valid(int verbose)
{
if (parser->num_agents != starts.size() || parser->num_agents != goals.size()) {
instance_console->error("invalid N, check instance nagents {} starts {} goals {}", parser->num_agents, starts.size(), goals.size());
return false;
exit(1);
}
return true;
}

uint Instance::update_on_reaching_goals_with_cache(
Expand Down
161 changes: 108 additions & 53 deletions calmapf/src/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,50 @@

#include "../include/dist_table.hpp"

Log::Log(std::shared_ptr<spdlog::logger> _logger) : logger(std::move(_logger))
Log::Log(Parser* parser)
{
log_console = spdlog::stderr_color_mt("log");
if (parser->debug_log) log_console->set_level(spdlog::level::debug);
else log_console->set_level(spdlog::level::info);

// Open throughput file
throughput_output_handler.open(parser->output_throughput_file, std::ios::app);
if (!throughput_output_handler.is_open()) {
log_console->error("Failed to open file: {}", parser->output_throughput_file);
exit(1);
}
throughput_output_handler << parser->map_file << "," << parser->cache_type_input << "," << parser->goals_gen_strategy_input << "," << parser->num_goals << "," << parser->num_agents << "," << parser->random_seed << "," << parser->verbose_level << "," << parser->time_limit_sec << "," << parser->goals_max_m << "," << parser->goals_max_k << ",";

// Open csv file
csv_output_handler.open(parser->output_csv_file, std::ios::app);
if (!csv_output_handler.is_open()) {
log_console->error("Failed to open file: {}", parser->output_csv_file);
exit(1);
}
csv_output_handler << parser->map_file << "," << parser->cache_type_input << "," << parser->look_ahead_num << "," << parser->delay_deadline_limit << "," << parser->goals_gen_strategy_input << "," << parser->num_goals << "," << parser->num_agents << "," << parser->random_seed << "," << parser->verbose_level << "," << parser->time_limit_sec << "," << parser->goals_max_m << "," << parser->goals_max_k << ",";

// Open step file
step_output_handler.open(parser->output_step_file, std::ios::app);
if (!step_output_handler.is_open()) {
log_console->error("Failed to open file: {}", parser->output_step_file);
exit(1);
}

// Open visual file
visual_output_handler.open(parser->output_step_file, std::ios::app);
if (!visual_output_handler.is_open()) {
log_console->error("Failed to open file: {}", parser->output_visual_file);
exit(1);
}
}

Log::~Log() {
// Close file
throughput_output_handler.close();
csv_output_handler.close();
step_output_handler.close();
visual_output_handler.close();
}
Log::~Log() {}

bool Log::update_solution(Solution& solution, std::vector<uint> bit_status)
{
Expand Down Expand Up @@ -39,42 +79,42 @@ bool Log::update_solution(Solution& solution, std::vector<uint> bit_status)
bool Log::is_feasible_solution(const Instance& ins, const int verbose)
{
if (step_solution.empty()) return true;
// check start locations

// Check start locations
if (!is_same_config(step_solution.front(), ins.starts)) {
info(1, verbose, "invalid starts");
log_console->error("invalid starts");
return false;
}

// check goal locations
// Check goal locations
if (!is_reach_at_least_one(step_solution.back(), ins.goals)) {
info(1, verbose, "invalid goals");
log_console->error("invalid goals");
return false;
}

for (size_t t = 1; t < step_solution.size(); ++t) {
for (size_t i = 0; i < ins.parser->num_agents; ++i) {
auto v_i_from = step_solution[t - 1][i];
auto v_i_to = step_solution[t][i];
// check connectivity
// Check connectivity
if (v_i_from != v_i_to &&
std::find(v_i_to->neighbor.begin(), v_i_to->neighbor.end(),
v_i_from) == v_i_to->neighbor.end()) {
info(1, verbose, "invalid move");
std::find(v_i_to->neighbor.begin(), v_i_to->neighbor.end(), v_i_from) == v_i_to->neighbor.end()) {
log_console->error("invalid move");
return false;
}

// check conflicts
// Check conflicts
for (size_t j = i + 1; j < ins.parser->num_agents; ++j) {
auto v_j_from = step_solution[t - 1][j];
auto v_j_to = step_solution[t][j];
// vertex conflicts
// Vertex conflicts
if (v_j_to == v_i_to) {
info(1, verbose, "vertex conflict");
log_console->error("vertex conflict");
return false;
}
// swap conflicts
// Swap conflicts
if (v_j_to == v_i_from && v_j_from == v_i_to) {
info(1, verbose, "edge conflict");
log_console->error("edge conflict");
return false;
}
}
Expand Down Expand Up @@ -146,14 +186,15 @@ void Log::print_stats(const int verbose, const Instance& ins,
const double comp_time_ms)
{
auto ceil = [](float x) { return std::ceil(x * 100) / 100; };

auto dist_table = DistTable(ins);
const auto makespan = get_makespan();
const auto makespan_lb = get_makespan_lower_bound(ins, dist_table);
const auto sum_of_costs = get_sum_of_costs();
const auto sum_of_costs_lb = get_sum_of_costs_lower_bound(ins, dist_table);
const auto sum_of_loss = get_sum_of_loss();

logger->debug(
log_console->debug(
"solved: {} ms\tmakespan: {} (lb={}, ub={})\tsum_of_costs: {} (lb={}, "
"ub={})\tsum_of_loss: {} (lb={}, ub={})",
comp_time_ms, makespan, makespan_lb,
Expand Down Expand Up @@ -182,58 +223,55 @@ void Log::make_step_log(const Instance& ins, const std::string& output_name,
// log for visualizer
auto get_x = [&](int k) { return k % ins.graph.width; };
auto get_y = [&](int k) { return k / ins.graph.width; };
std::ofstream log;
log.open(output_name, std::ios::out);
log << "agents=" << ins.parser->num_agents << "\n";
log << "map_file=" << map_recorded_name << "\n";
log << "solver=planner\n";
log << "solved=" << !step_solution.empty() << "\n";
log << "soc=" << get_sum_of_costs() << "\n";
log << "soc_lb=" << get_sum_of_costs_lower_bound(ins, dist_table) << "\n";
log << "makespan=" << get_makespan() << "\n";
log << "makespan_lb=" << get_makespan_lower_bound(ins, dist_table) << "\n";
log << "sum_of_loss=" << get_sum_of_loss() << "\n";
log << "sum_of_loss_lb=" << get_sum_of_costs_lower_bound(ins, dist_table)
<< "\n";
log << "comp_time=" << comp_time_ms << "\n";
log << "seed=" << seed << "\n";

step_output_handler << "agents=" << ins.parser->num_agents << std::endl
<< "map_file=" << map_recorded_name << std::endl
<< "solver=planner" << std::endl
<< "solved=" << !step_solution.empty() << std::endl
<< "soc=" << get_sum_of_costs() << std::endl
<< "soc_lb=" << get_sum_of_costs_lower_bound(ins, dist_table) << std::endl
<< "makespan=" << get_makespan() << std::endl
<< "makespan_lb=" << get_makespan_lower_bound(ins, dist_table) << std::endl
<< "sum_of_loss=" << get_sum_of_loss() << std::endl
<< "sum_of_loss_lb=" << get_sum_of_costs_lower_bound(ins, dist_table) << std::endl
<< "comp_time=" << comp_time_ms << std::endl
<< "seed=" << seed << std::endl;

if (log_short) return;
log << "starts=";
step_output_handler << "starts=";
for (size_t i = 0; i < ins.parser->num_agents; ++i) {
auto k = ins.starts[i]->index;
log << "(" << get_x(k) << "," << get_y(k) << "),";
step_output_handler << "(" << get_x(k) << "," << get_y(k) << "),";
}
log << "\ngoals=";
step_output_handler << std::endl << "goals=";
for (size_t i = 0; i < ins.parser->num_agents; ++i) {
auto k = ins.goals[i]->index;
log << "(" << get_x(k) << "," << get_y(k) << "),";
step_output_handler << "(" << get_x(k) << "," << get_y(k) << "),";
}
log << "\nsolution=\n";
std::vector<std::vector<int> > new_sol(
ins.parser->num_agents, std::vector<int>(step_solution.size(), 0));
step_output_handler << std::endl << "solution=" << std::endl;

std::vector<std::vector<int> > new_sol(ins.parser->num_agents, std::vector<int>(step_solution.size(), 0));
for (size_t t = 0; t < step_solution.size(); ++t) {
log << t << ":";
step_output_handler << t << ":";
auto C = step_solution[t];
int idx = 0;
for (auto v : C) {
log << "(" << get_x(v->index) << "," << get_y(v->index) << "),";
step_output_handler << "(" << get_x(v->index) << "," << get_y(v->index) << "),";
new_sol[idx][t] = v->index;
idx++;
}
log << "\n";
step_output_handler << std::endl;
}
log.close();
}

void Log::make_life_long_log(const Instance& ins, std::string visual_name)
{
logger->info("life long solution size: {}, bit status size: {}", life_long_solution.size(), bit_status_log.size());
std::cout << visual_name << std::endl;
log_console->info("life long solution size: {}, bit status size: {}", life_long_solution.size(), bit_status_log.size());

auto dist_table = DistTable(ins);
auto get_x = [&](int k) { return k % ins.graph.width; };
auto get_y = [&](int k) { return k / ins.graph.width; };
std::vector<std::vector<int> > new_sol(
ins.parser->num_agents, std::vector<int>(life_long_solution.size(), 0));
std::vector<std::vector<int> > new_sol(ins.parser->num_agents, std::vector<int>(life_long_solution.size(), 0));

for (size_t t = 0; t < life_long_solution.size(); ++t) {
auto C = life_long_solution[t];
Expand All @@ -244,18 +282,35 @@ void Log::make_life_long_log(const Instance& ins, std::string visual_name)
}
}

std::ofstream out2(visual_name);
out2 << "width: " << ins.graph.width << std::endl;
out2 << "height: " << ins.graph.height << std::endl;
out2 << "schedule: " << std::endl;
visual_output_handler << "width: " << ins.graph.width << std::endl
<< "height: " << ins.graph.height << std::endl
<< "schedule: " << std::endl;

for (size_t a = 0; a < new_sol.size(); ++a) {
out2 << " agent" << a << ":" << std::endl;
visual_output_handler << " agent" << a << ":" << std::endl;
for (size_t t = 0; t < new_sol[a].size(); ++t) {
out2 << " - x: " << get_y(new_sol[a][t]) << std::endl
visual_output_handler << " - x: " << get_y(new_sol[a][t]) << std::endl
<< " y: " << get_x(new_sol[a][t]) << std::endl
<< " t: " << t << std::endl
<< " s: " << bit_status_log[t][a] << std::endl;
}
}
out2.close();
}

void Log::make_throughput_log(uint index, uint start_cnt, uint make_span)
{
double throughput = double(index) / double(make_span);
for (; start_cnt < make_span; start_cnt += 200) {
throughput_output_handler << throughput << ",";
}
}

void Log::make_csv_log(double cache_hit_rate, uint make_span, std::vector<uint>* step_percentiles, bool failure)
{
if (!failure) {
csv_output_handler << cache_hit_rate << "," << make_span << "," << (*step_percentiles)[0] << "," << (*step_percentiles)[2] << "," << (*step_percentiles)[6] << std::endl;
}
else {
csv_output_handler << "fail to solve" << std::endl;
}
}
14 changes: 7 additions & 7 deletions calmapf/src/planner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Planner::Planner(const Instance* _ins, const Deadline* _deadline,

Solution Planner::solve()
{
info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\tstart search");
// info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\tstart search");

// setup agents
for (auto i = 0; i < N; ++i) A[i] = new Agent(i);
Expand Down Expand Up @@ -147,11 +147,11 @@ Solution Planner::solve()
CLOSED[S_new->C] = S_new;
}

info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\t",
solution.empty() ? (OPEN.empty() ? "no solution" : "failed")
: "solution found",
"\tloop_itr:", loop_cnt, "\texplored:", CLOSED.size());
// memory management
// info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\t",
// solution.empty() ? (OPEN.empty() ? "no solution" : "failed")
// : "solution found",
// "\tloop_itr:", loop_cnt, "\texplored:", CLOSED.size());
// // memory management
for (auto a : A) delete a;
for (auto M : GC) delete M;
for (auto p : CLOSED) delete p.second;
Expand Down Expand Up @@ -258,7 +258,7 @@ bool Planner::funcPIBT(Agent* ai)
Solution solve(const Instance& ins, const int verbose, const Deadline* deadline,
std::mt19937* MT)
{
info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\tpre-processing");
// info(1, verbose, "elapsed:", elapsed_ms(deadline), "ms\tpre-processing");
auto planner = Planner(&ins, deadline, MT, verbose);
return planner.solve();
}
Loading

0 comments on commit b2050e5

Please sign in to comment.