From 9447fc57f708a3d9c5e6cc6d25abd158525aa2fe Mon Sep 17 00:00:00 2001 From: JCRaymond Date: Fri, 27 Dec 2019 23:24:33 -0500 Subject: [PATCH] Restructure RelTables to support deleting useless information from RelTables. --- solver.cpp | 143 ++++++++++++++++++++++++++++++++++++++--------------- test.cpp | 2 +- 2 files changed, 105 insertions(+), 40 deletions(-) diff --git a/solver.cpp b/solver.cpp index cea6888..891d4a7 100644 --- a/solver.cpp +++ b/solver.cpp @@ -63,6 +63,66 @@ struct RelTable { } }; +struct RelTablesRow { + int* gnrs; + int** lst_ptrs; + RelTablesRow (int N, int* gnrs, int** lst_ptrs): gnrs(gnrs), lst_ptrs(lst_ptrs) { + for (int i = 0; i < N; i++) { + lst_ptrs[i] = nullptr; + } + } +}; + +struct TableInfo { + int gens[2]; + int mult; + TableInfo(Mult m) { + gens[0] = m.gen0; + gens[1] = m.gen1; + mult = m.mult; + } +}; + +struct RelTables { + static const int ROW_BLOCK_SIZE = 128; + std::vector table_info; + std::vector rows; + int start = 0; + int num_tables; + int buffer_rows = 0; + + RelTables (std::vector mults): num_tables(mults.size()) { + for (Mult m : mults) { + table_info.emplace_back(m); + } + } + + void add_row() { + if (buffer_rows == 0) { + int* gnrs_alloc = new int[num_tables*RelTables::ROW_BLOCK_SIZE]; + int** lst_ptrs_alloc = new int*[num_tables*RelTables::ROW_BLOCK_SIZE]; + for (int i = 0; i < RelTables::ROW_BLOCK_SIZE; i++) { + rows.push_back(new RelTablesRow(num_tables, &gnrs_alloc[i*num_tables], &lst_ptrs_alloc[i*num_tables])); + } + buffer_rows = RelTables::ROW_BLOCK_SIZE; + } + + buffer_rows--; + } + + void del_rows_to(int idx) { + const int del_to = (idx/RelTables::ROW_BLOCK_SIZE)*RelTables::ROW_BLOCK_SIZE; + for (int i = start; i < del_to; i += RelTables::ROW_BLOCK_SIZE) { + delete[] rows[i]->gnrs; + delete[] rows[i]->lst_ptrs; + for (int j = 0; j < RelTables::ROW_BLOCK_SIZE; j++) { + delete rows[i+j]; + } + start += RelTables::ROW_BLOCK_SIZE; + } + } +}; + struct Group { int ngens; std::vector> _mults; @@ -138,27 +198,28 @@ struct Group { } Cosets cosets(ngens, init_row); - std::vector rel_tables; + RelTables rel_tables(get_mults()); std::vector> gen_map(ngens); - int rel_idx; + int rel_idx = 0; for (Mult m : get_mults()) { - rel_idx = rel_tables.size(); gen_map[m.gen0].push_back(rel_idx); gen_map[m.gen1].push_back(rel_idx); - rel_tables.emplace_back(m); + rel_idx++; } int null_lst_ptr; - for (RelTable &rel : rel_tables) { - int idx = rel.add_row(); + rel_tables.add_row(); + RelTablesRow &row = *(rel_tables.rows[0]); + for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { + TableInfo &ti = rel_tables.table_info[table_idx]; - if (cosets.get(rel.gens[0]) + cosets.get(rel.gens[1]) == -2) { - rel.lst_ptr[idx] = new int; - rel.gen[idx] = 0; + if (cosets.get(ti.gens[0]) + cosets.get(ti.gens[1]) == -2) { + row.lst_ptrs[table_idx] = new int; + row.gnrs[table_idx] = 0; } else { - rel.lst_ptr[idx] = &null_lst_ptr; - rel.gen[idx] = -1; + row.lst_ptrs[table_idx] = &null_lst_ptr; + row.gnrs[table_idx] = -1; } } @@ -168,22 +229,24 @@ struct Group { while (idx < cosets.data.size() and cosets.get(idx) >= 0) idx++; - if (idx == cosets.data.size()) + if (idx == cosets.data.size()) { + rel_tables.del_rows_to(idx / ngens); break; + } target = cosets.len; cosets.add_row(); + rel_tables.add_row(); - for (RelTable &rel : rel_tables) { - rel.add_row(); - } - std::vector facts; facts.push_back(idx); coset = idx / ngens; gen = idx % ngens; + rel_tables.del_rows_to(coset); + + RelTablesRow &target_row = *(rel_tables.rows[target]); while (!facts.empty()) { fact_idx = facts.back(); facts.pop_back(); @@ -196,27 +259,28 @@ struct Group { coset = fact_idx / ngens; gen = fact_idx % ngens; - for (int rel_idx : gen_map[gen]) { - RelTable &rel = rel_tables[rel_idx]; - if ( rel.lst_ptr[target] == nullptr ) { - rel.lst_ptr[target] = rel.lst_ptr[coset]; - rel.gen[target] = rel.gen[coset] + 1; + RelTablesRow &coset_row = *(rel_tables.rows[coset]); + for (int table_idx : gen_map[gen]) { + if ( target_row.lst_ptrs[table_idx] == nullptr ) { + TableInfo &ti = rel_tables.table_info[table_idx]; + target_row.lst_ptrs[table_idx] = coset_row.lst_ptrs[table_idx]; + target_row.gnrs[table_idx] = coset_row.gnrs[table_idx] + 1; - if (rel.gen[coset] < 0) - rel.gen[target] -= 2; + if (coset_row.gnrs[table_idx] < 0) + target_row.gnrs[table_idx] -= 2; - if (rel.gen[target] == rel.mult) { - lst = *(rel.lst_ptr[target]); - delete rel.lst_ptr[target]; - gen_ = rel.gens[(int)(rel.gens[0] == gen)]; + if (target_row.gnrs[table_idx] == ti.mult) { + lst = *(target_row.lst_ptrs[table_idx]); + delete target_row.lst_ptrs[table_idx]; + gen_ = ti.gens[(int)(ti.gens[0] == gen)]; facts.push_back(lst*ngens + gen_); } - else if (rel.gen[target] == -rel.mult) { - gen_ = rel.gens[rel.gens[0] == gen]; + else if (target_row.gnrs[table_idx] == -ti.mult) { + gen_ = ti.gens[ti.gens[0] == gen]; facts.push_back(target*ngens + gen_); } - else if (rel.gen[target] == rel.mult - 1) { - *(rel.lst_ptr[target]) = target; + else if (target_row.gnrs[table_idx] == ti.mult - 1) { + *(target_row.lst_ptrs[table_idx]) = target; } } } @@ -224,16 +288,17 @@ struct Group { std::sort(facts.begin(), facts.end(), std::greater()); } - for (RelTable &rel : rel_tables) { - if (rel.lst_ptr[target] == nullptr) { - if ( (cosets.get(target, rel.gens[0]) != target) and - (cosets.get(target, rel.gens[1]) != target) ) { - rel.lst_ptr[target] = new int; - rel.gen[target] = 0; + for (int table_idx = 0; table_idx < rel_tables.num_tables; table_idx++) { + TableInfo &ti = rel_tables.table_info[table_idx]; + if (target_row.lst_ptrs[table_idx] == nullptr) { + if ( (cosets.get(target, ti.gens[0]) != target) and + (cosets.get(target, ti.gens[1]) != target) ) { + target_row.lst_ptrs[table_idx] = new int; + target_row.gnrs[table_idx] = 0; } else { - rel.lst_ptr[target] = &null_lst_ptr; - rel.gen[target] = -1; + target_row.lst_ptrs[table_idx] = &null_lst_ptr; + target_row.gnrs[table_idx] = -1; } } } diff --git a/test.cpp b/test.cpp index f77c448..114f7c5 100644 --- a/test.cpp +++ b/test.cpp @@ -3,7 +3,7 @@ #include int main() { - Group g = T(4500); + Group g = B(8); auto s = std::chrono::system_clock::now(); auto cosets = g.solve();