From 02900e6067855f71e6d0370ae5b33831a7074f46 Mon Sep 17 00:00:00 2001 From: Zhenghong Yu Date: Wed, 19 Jun 2024 18:03:18 +0800 Subject: [PATCH] test([instance]): add state machine simple test --- CMakeLists.txt | 2 +- assets/test/test_instance.map | 14 ++++ calmapf/include/instance.hpp | 2 +- calmapf/include/parser.hpp | 2 +- calmapf/include/utils.hpp | 5 +- calmapf/src/cache.cpp | 10 ++- calmapf/src/instance.cpp | 16 ++-- calmapf/src/parser.cpp | 10 +-- tests/test_instance.cpp | 140 +++++++++++++++++++++++++++++++--- 9 files changed, 172 insertions(+), 29 deletions(-) create mode 100644 assets/test/test_instance.map diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fa3d80..1d184fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ endmacro(add_test) add_test(test_graph ./tests/test_graph.cpp) add_test(test_cache ./tests/test_cache.cpp) -# add_test(test_instance ./tests/test_instance.cpp) +add_test(test_instance ./tests/test_instance.cpp) # add_test(test_dist_table ./tests/test_dist_table.cpp) # add_test(test_planner ./tests/test_planner.cpp) # add_test(test_post_processing ./tests/test_post_processing.cpp) diff --git a/assets/test/test_instance.map b/assets/test/test_instance.map new file mode 100644 index 0000000..c3a59f7 --- /dev/null +++ b/assets/test/test_instance.map @@ -0,0 +1,14 @@ +type single_port +group 1 +height 8 +width 8 +map +TTTTTTTT +T......T +T....H.T +TU.C.H.T +T....H.T +T......T +T......T +TTTTTTTT + diff --git a/calmapf/include/instance.hpp b/calmapf/include/instance.hpp index a2fef64..2d6cd91 100644 --- a/calmapf/include/instance.hpp +++ b/calmapf/include/instance.hpp @@ -11,7 +11,7 @@ struct Instance { Graph graph; // graph Config starts; // initial configuration Config goals; // goal configuration, can be in warehouse block/cache block - Config old_goals; // old goal configuration, used for trash collection + Config garbages; // old goal configuration, used for trash collection Config cargo_goals; // cargo goal configuration std::vector cargo_cnts; // each cargo cnts, help variable for cargo_steps std::vector cargo_steps; // each cargo steps diff --git a/calmapf/include/parser.hpp b/calmapf/include/parser.hpp index c8e3ce4..0290dbb 100644 --- a/calmapf/include/parser.hpp +++ b/calmapf/include/parser.hpp @@ -55,5 +55,5 @@ struct Parser { void _print(); // Unit test only - Parser(std::string _map_file, CacheType _cache_type); + Parser(std::string _map_file, CacheType _cache_type, uint _num_agents = 4); }; \ No newline at end of file diff --git a/calmapf/include/utils.hpp b/calmapf/include/utils.hpp index c5016a6..8cbcc59 100644 --- a/calmapf/include/utils.hpp +++ b/calmapf/include/utils.hpp @@ -131,10 +131,11 @@ inline bool is_cache(CacheType cache_type) { struct CacheAccessResult { bool result; Vertex* goal; + Vertex* garbage; - inline CacheAccessResult(bool _result, Vertex* _goal) : result(_result), goal(_goal) {}; + inline CacheAccessResult(bool _result, Vertex* _goal, Vertex* _garbage = nullptr) : result(_result), goal(_goal), garbage(_garbage) {}; bool operator==(const CacheAccessResult& other) const { - return result == other.result && goal == other.goal; + return result == other.result && goal == other.goal && garbage == other.garbage; } }; diff --git a/calmapf/src/cache.cpp b/calmapf/src/cache.cpp index 94dc1b9..56197b3 100644 --- a/calmapf/src/cache.cpp +++ b/calmapf/src/cache.cpp @@ -125,8 +125,12 @@ bool Cache::_is_cargo_in_coming_cache(Vertex* cargo) { bool Cache::_is_garbage_collection(int group) { for (uint i = 0; i < is_empty[group].size(); i++) { - if (is_empty[group][i]) return false; + if (is_empty[group][i]) { + cache_console->debug("No need garbage collection"); + return false; + } } + cache_console->debug("Need garbage collection"); return true; } @@ -197,7 +201,7 @@ CacheAccessResult Cache::try_cache_garbage_collection(Vertex* cargo) { if (index != -1) { // We lock this position bit_cache_insert_or_clear_lock[group][index] += 1; - return CacheAccessResult(true, node_id[group][index]); + return CacheAccessResult(true, node_id[group][index], node_cargo[group][index]); } return CacheAccessResult(false, cargo); @@ -220,6 +224,8 @@ bool Cache::update_cargo_into_cache(Vertex* cargo, Vertex* cache_node) { node_cargo[cache_node->group][cache_index] = cargo; bit_cache_insert_or_clear_lock[cache_node->group][cache_index] -= 1; node_cargo_num[cache_node->group][cache_index] = parser->agent_capacity - 1; + // Set it as not empty + is_empty[cache_node->group][cache_index] = false; return true; } diff --git a/calmapf/src/instance.cpp b/calmapf/src/instance.cpp index 85afd7e..4867d76 100644 --- a/calmapf/src/instance.cpp +++ b/calmapf/src/instance.cpp @@ -28,8 +28,8 @@ Instance::Instance(Parser* _parser) : graph(Graph(_parser)), parser(_parser) Vertex* goal = graph.get_next_goal(agent_group[j]); goals.push_back(goal); cargo_goals.push_back(goal); - old_goals.push_back(goal); - bit_status.push_back(0); // At the begining, the cache is empty, all agents should at status 0 + garbages.push_back(goal); + bit_status.push_back(1); // At the begining, the cache is empty, all agents should at status 1 cargo_cnts.push_back(0); if (goals.size() == parser->num_agents) break; ++j; @@ -73,10 +73,10 @@ uint Instance::update_on_reaching_goals_with_cache( if (vertex_list[step][j] == goals[j]) { // Status 0 finished. ==> Status 3 if (bit_status[j] == 0) { - instance_console->debug("Agent {} status 0 -> status 3, reached cargo {} at cahe block {}, cleared", j, *cargo_goals[j], *goals[j]); + instance_console->debug("Agent {} status 0 -> status 3, reached cargo {} at cahe block {}, cleared", j, *garbages[j], *goals[j]); bit_status[j] = 3; - assert(graph.cache->clear_cargo_from_cache(cargo_goals[j], goals[j])); - goals[j] = old_goals[j]; + assert(graph.cache->clear_cargo_from_cache(garbages[j], goals[j])); + goals[j] = garbages[j]; } // Status 2 finished. ==> Status 6 // Agent has moved to cache cargo target. @@ -121,7 +121,7 @@ uint Instance::update_on_reaching_goals_with_cache( "Agent {} status 1 -> status 5, reach warehouse cargo {}, cache " "is full, go back to unloading port", j, *cargo_goals[j]); - bit_status[j] = 6; + bit_status[j] = 5; } // Find empty cache block, go and insert cargo into cache, -> Status 5 else { @@ -129,7 +129,7 @@ uint Instance::update_on_reaching_goals_with_cache( "Agent {} status 1 -> status 4, reach warehouse cargo {}, find " "cache block to insert, go to cache block {}", j, *cargo_goals[j], *result.goal); - bit_status[j] = 5; + bit_status[j] = 4; } // Update goals goals[j] = result.goal; @@ -205,6 +205,7 @@ uint Instance::update_on_reaching_goals_with_cache( "Agent {} assigned with new cargo {}, cache miss. Need to do trash collection. Go to " "clear cache {}, status 5 -> status 0", j, *cargo_goals[j], *trash_result.goal); + garbages[j] = trash_result.garbage; cache_access++; bit_status[j] = 0; } @@ -278,6 +279,7 @@ uint Instance::update_on_reaching_goals_with_cache( "Agent {} assigned with new cargo {}, cache miss. Need to do trash collection. Go to " "clear cache {}, status 6 -> status 0", j, *cargo_goals[j], *trash_result.goal); + garbages[j] = trash_result.garbage; cache_access++; bit_status[j] = 0; } diff --git a/calmapf/src/parser.cpp b/calmapf/src/parser.cpp index 0d32f1f..c30879e 100644 --- a/calmapf/src/parser.cpp +++ b/calmapf/src/parser.cpp @@ -160,16 +160,18 @@ void Parser::_print() { // Unit test only Parser::Parser( std::string _map_file, - CacheType _cache_type) : + CacheType _cache_type, + uint _num_agents) : map_file(_map_file), - cache_type(_cache_type) + cache_type(_cache_type), + num_agents(_num_agents) { // Set up logger if (auto existing_console = spdlog::get("parser"); existing_console != nullptr) parser_console = existing_console; else parser_console = spdlog::stderr_color_mt("parser"); parser_console->set_level(spdlog::level::debug); - look_ahead_num = 10; + look_ahead_num = 1; delay_deadline_limit = 10; num_goals = 100; @@ -179,8 +181,6 @@ Parser::Parser( goals_max_k = 20; goals_max_m = 100; - num_agents = 4; - MT = std::mt19937(0); time_limit_sec = 10; diff --git a/tests/test_instance.cpp b/tests/test_instance.cpp index efe175e..44208a9 100644 --- a/tests/test_instance.cpp +++ b/tests/test_instance.cpp @@ -1,15 +1,135 @@ -#include +#include #include "gtest/gtest.h" -TEST(Instance, initialize) +TEST(Instance, state_machine_test) { - const auto scen_filename = "./assets/random-32-32-10-random-1.scen"; - const auto map_filename = "./assets/random-32-32-10.map"; - const auto ins = Instance(scen_filename, map_filename, 3); - - ASSERT_EQ(size(ins.starts), 3); - ASSERT_EQ(size(ins.goals), 3); - ASSERT_EQ(ins.starts[0]->index, 203); - ASSERT_EQ(ins.goals[0]->index, 583); + Parser cache_state_machine_test_parser = Parser("./assets/test/test_instance.map", CacheType::LRU, 1); + Instance instance(&cache_state_machine_test_parser); + + /* Graph + TTTTTTTTT + T.......T + T.......T + T..C.HH.T + TU.C.HH.T + T..C.HH.T + T.......T + T.......T + TTTTTTTTT + */ + + // Initilization check + ASSERT_EQ(1, instance.bit_status[0]); + uint cache_access, cache_hit = 0; + std::vector vertex_list; + Config step; + Vertex* goal = instance.graph.cargo_vertices[0][0];; + + // Generate goal queue + instance.goals[0] = goal; + instance.cargo_goals[0] = goal; + instance.graph.goals_queue[0].clear(); + instance.graph.goals_queue[0].push_back(instance.graph.cargo_vertices[0][1]); + instance.graph.goals_queue[0].push_back(instance.graph.cargo_vertices[0][1]); + instance.graph.goals_delay[0].clear(); + instance.graph.goals_delay[0].push_back(0); + instance.graph.goals_delay[0].push_back(0); + instance.instance_console->info("Front goal {}", *(instance.graph.goals_queue[0].front())); + + + // Status 1 -> Status 4 + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(4, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 4 -> Status 6 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(6, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 6 -> Status 0 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(1, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(0, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 0 -> Status 3 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(3, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 3 -> Status 1 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(1, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 1 -> Status 4 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(4, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 4 -> Status 6 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(6, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 6 -> Status 2 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(1, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(2, instance.bit_status[0]); + + goal = instance.goals[0]; + + // Status 2 -> Status 6 + step.clear(); + vertex_list.clear(); + step.push_back(goal); + vertex_list.push_back(step); + + ASSERT_EQ(0, instance.update_on_reaching_goals_with_cache(vertex_list, 100, cache_access, cache_hit)); + ASSERT_EQ(6, instance.bit_status[0]); }