Browse Source

refactor: remove exposed group extend interface

master
Dnomd343 2 weeks ago
parent
commit
470d7415e7
  1. 1
      src/core/CMakeLists.txt
  2. 21
      src/core/benchmark/group.cc
  3. 3
      src/core/group/group.h
  4. 42
      src/core/group/internal/extend.cc
  5. 66
      src/core/group/internal/group.cc
  6. 8
      src/core/group/internal/group.inl
  7. 34
      src/core/group/internal/group_cases.cc

1
src/core/CMakeLists.txt

@ -23,7 +23,6 @@ set(KLOTSKI_CORE_SRC
fast_cal/internal/fast_cal.cc fast_cal/internal/fast_cal.cc
group/internal/group_union.cc group/internal/group_union.cc
group/internal/extend.cc
group/internal/group.cc group/internal/group.cc
group/internal/group_cases.cc group/internal/group_cases.cc

21
src/core/benchmark/group.cc

@ -16,6 +16,9 @@ using klotski::cases::AllCases;
using klotski::group::Group; using klotski::group::Group;
using klotski::group::GroupUnion; using klotski::group::GroupUnion;
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
/// Build all valid CommonCodes. /// Build all valid CommonCodes.
static std::vector<uint64_t> all_common_codes() { static std::vector<uint64_t> all_common_codes() {
std::vector<uint64_t> codes; std::vector<uint64_t> codes;
@ -110,7 +113,7 @@ static void GroupExtend(benchmark::State &state) {
for (auto _ : state) { for (auto _ : state) {
volatile auto ret = klotski::group::Group_extend(src, 0); // volatile auto ret = klotski::group::Group_extend(src, 0);
// std::cout << ret.size() << std::endl; // std::cout << ret.size() << std::endl;
} }
@ -263,6 +266,18 @@ static void SpawnGroups(benchmark::State &state) {
} }
static void GroupFromRawCode(benchmark::State &state) {
auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
for (auto _ : state) {
volatile auto g = Group::from_raw_code(code);
}
}
// BENCHMARK(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256); // BENCHMARK(CommonCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
// BENCHMARK(RawCodeToTypeId)->Arg(8)->Arg(64)->Arg(256); // BENCHMARK(RawCodeToTypeId)->Arg(8)->Arg(64)->Arg(256);
@ -278,6 +293,8 @@ static void SpawnGroups(benchmark::State &state) {
// BENCHMARK(RangesDerive)->Unit(benchmark::kMillisecond); // BENCHMARK(RangesDerive)->Unit(benchmark::kMillisecond);
BENCHMARK(SpawnGroups); // BENCHMARK(SpawnGroups);
BENCHMARK(GroupFromRawCode)->Unit(benchmark::kMillisecond);
BENCHMARK_MAIN(); BENCHMARK_MAIN();

3
src/core/group/group.h

@ -390,9 +390,6 @@ private:
// ------------------------------------------------------------------------------------- // // ------------------------------------------------------------------------------------- //
}; };
/// Spawn all the unsorted codes of the current group.
std::vector<codec::RawCode> Group_extend(codec::RawCode raw_code, uint32_t reserve = 0);
} // namespace klotski::group } // namespace klotski::group
#include "internal/type_id.inl" #include "internal/type_id.inl"

42
src/core/group/internal/extend.cc

@ -1,42 +0,0 @@
#include <parallel_hashmap/phmap.h>
#include "mover/mover.h"
#include "group/group.h"
using klotski::codec::RawCode;
using klotski::codec::CommonCode;
using klotski::cases::RangesUnion;
using klotski::mover::MaskMover;
using klotski::group::GroupUnion;
// TODO: maybe we can perf with mirror cases
std::vector<RawCode> klotski::group::Group_extend(RawCode raw_code, uint32_t reserve) {
std::vector<RawCode> codes;
phmap::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
// reserve = reserve ? reserve : GroupUnion::from_raw_code(raw_code).max_group_size();
// reserve = 25955;
codes.reserve(GroupUnion::from_raw_code(raw_code).max_group_size());
cases.reserve(25955 * 1.56);
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
codes.emplace_back(raw_code);
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
// std::cout << cases.size() << std::endl;
// std::cout << cases.load_factor() << std::endl;
return codes;
}

66
src/core/group/internal/group.cc

@ -2,15 +2,50 @@
#include "group/group.h" #include "group/group.h"
#include <mover/mover.h>
#include <parallel_hashmap/phmap.h>
using klotski::codec::RawCode; using klotski::codec::RawCode;
using klotski::codec::CommonCode; using klotski::codec::CommonCode;
using klotski::group::Group; using klotski::group::Group;
using klotski::group::GroupUnion;
using klotski::cases::RangesUnion; using klotski::cases::RangesUnion;
using klotski::mover::MaskMover;
using klotski::group::GROUP_DATA; using klotski::group::GROUP_DATA;
using klotski::group::PATTERN_DATA; using klotski::group::PATTERN_DATA;
// TODO: maybe we can perf with mirror cases
/// Spawn all the unsorted codes of the current group.
static std::vector<RawCode> Group_extend_for_cases(RawCode raw_code, uint32_t reserve) {
std::vector<RawCode> codes;
phmap::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
codes.reserve(reserve);
cases.reserve(reserve * 1.56);
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
codes.emplace_back(raw_code);
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
return codes;
}
RangesUnion Group::cases() const { RangesUnion Group::cases() const {
// TODO: add white list for single-group unions // TODO: add white list for single-group unions
@ -28,7 +63,7 @@ RangesUnion Group::cases() const {
seed = seed.to_vertical_mirror().to_horizontal_mirror(); seed = seed.to_vertical_mirror().to_horizontal_mirror();
} }
auto codes = Group_extend(seed.to_raw_code(), size()); auto codes = Group_extend_for_cases(seed.to_raw_code(), size());
RangesUnion data; RangesUnion data;
for (auto raw_code : codes) { for (auto raw_code : codes) {
@ -57,10 +92,35 @@ static std::unordered_map<uint64_t, Group> build_map_data() {
return data; return data;
} }
Group Group::from_raw_code(codec::RawCode raw_code) { static std::vector<RawCode> Group_extend_for_from_raw_code(RawCode raw_code) {
std::vector<RawCode> codes;
phmap::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
codes.reserve(GroupUnion::from_raw_code(raw_code).max_group_size());
cases.reserve(GroupUnion::from_raw_code(raw_code).max_group_size() * 1.56);
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
codes.emplace_back(raw_code);
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
return codes;
}
Group Group::from_raw_code(const RawCode raw_code) {
static auto map_data = build_map_data(); static auto map_data = build_map_data();
auto raw_codes = Group_extend(raw_code); auto raw_codes = Group_extend_for_from_raw_code(raw_code);
auto common_codes = raw_codes | std::views::transform([](const RawCode r) { auto common_codes = raw_codes | std::views::transform([](const RawCode r) {
return r.to_common_code(); return r.to_common_code();
}) | std::ranges::to<std::vector>(); // TODO: search min_element directly }) | std::ranges::to<std::vector>(); // TODO: search min_element directly

8
src/core/group/internal/group.inl

@ -6,6 +6,10 @@ namespace klotski::group {
// ----------------------------------------------------------------------------------------- // // ----------------------------------------------------------------------------------------- //
constexpr auto Group::toward() const -> Toward {
return toward_;
}
constexpr uint_fast8_t Group::type_id() const { constexpr uint_fast8_t Group::type_id() const {
return type_id_; return type_id_;
} }
@ -14,10 +18,6 @@ constexpr uint_fast16_t Group::pattern_id() const {
return pattern_id_; return pattern_id_;
} }
constexpr auto Group::toward() const -> Toward {
return toward_;
}
constexpr char Group::toward_char() const { constexpr char Group::toward_char() const {
// TODO: select chars from pre-build std::array // TODO: select chars from pre-build std::array
switch (mirror_type()) { switch (mirror_type()) {

34
src/core/group/internal/group_cases.cc

@ -2,8 +2,12 @@
#include <algorithm> #include <algorithm>
#include <parallel_hashmap/phmap.h>
#include "group/group.h" #include "group/group.h"
#include "mover/mover.h"
using klotski::codec::RawCode;
using klotski::codec::ShortCode; using klotski::codec::ShortCode;
using klotski::codec::CommonCode; using klotski::codec::CommonCode;
@ -14,6 +18,8 @@ using klotski::cases::RangesUnion;
using klotski::group::CaseInfo; using klotski::group::CaseInfo;
using klotski::mover::MaskMover;
using klotski::group::ALL_GROUP_NUM; using klotski::group::ALL_GROUP_NUM;
using klotski::group::TYPE_ID_LIMIT; using klotski::group::TYPE_ID_LIMIT;
using klotski::cases::ALL_CASES_NUM_; using klotski::cases::ALL_CASES_NUM_;
@ -195,8 +201,34 @@ static std::unordered_map<uint64_t, Group> build_map_data() {
return data; return data;
} }
static std::vector<RawCode> Group_extend_for_obtain_info(RawCode raw_code) {
std::vector<RawCode> codes;
phmap::flat_hash_map<uint64_t, uint64_t> cases; // <code, mask>
codes.reserve(GroupUnion::from_raw_code(raw_code).max_group_size());
cases.reserve(GroupUnion::from_raw_code(raw_code).max_group_size() * 1.56);
auto core = MaskMover([&codes, &cases](RawCode code, uint64_t mask) {
if (const auto match = cases.find(code.unwrap()); match != cases.end()) {
match->second |= mask; // update mask
return;
}
cases.emplace(code, mask);
codes.emplace_back(code); // new case
});
uint64_t offset = 0;
codes.emplace_back(raw_code);
cases.emplace(raw_code, 0); // without mask
while (offset != codes.size()) {
auto curr = codes[offset++].unwrap();
core.next_cases(RawCode::unsafe_create(curr), cases.find(curr)->second);
}
return codes;
}
CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) { CaseInfo GroupCases::tiny_obtain_info(CommonCode common_code) {
auto raw_codes = Group_extend(common_code.to_raw_code()); auto raw_codes = Group_extend_for_obtain_info(common_code.to_raw_code());
std::vector<CommonCode> common_codes; std::vector<CommonCode> common_codes;
common_codes.reserve(raw_codes.size()); common_codes.reserve(raw_codes.size());
for (auto raw_code : raw_codes) { for (auto raw_code : raw_codes) {

Loading…
Cancel
Save