diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1e25605 --- /dev/null +++ b/.clang-format @@ -0,0 +1,68 @@ +# Generated from CLion C/C++ Code Style settings +BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: Consecutive +AlignConsecutiveDeclarations: Consecutive +AlignConsecutiveMacros: Consecutive +AlignOperands: Align +AllowAllArgumentsOnNextLine: false +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Always +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Always +AllowShortLambdasOnASingleLine: All +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: Yes +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: Never + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: true +BreakBeforeBinaryOperators: None +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: BeforeColon +BreakInheritanceList: BeforeColon +ColumnLimit: 0 +CompactNamespaces: false +ContinuationIndentWidth: 8 +IndentCaseLabels: true +IndentPPDirectives: BeforeHash +IndentWidth: 4 +KeepEmptyLinesAtTheStartOfBlocks: true +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: All +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PointerAlignment: Left +ReflowComments: false +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 0 +SpacesInAngles: false +SpacesInCStyleCastParentheses: false +SpacesInContainerLiterals: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +TabWidth: 4 +UseTab: Never \ No newline at end of file diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml new file mode 100644 index 0000000..0b1d703 --- /dev/null +++ b/.github/workflows/clang-format.yml @@ -0,0 +1,33 @@ +name: Clang Format + +on: + push: + branches: [ main ] + paths: + - '.github/**' + - 'src/**' + - 'include/**' + - 'tests/**' + - '.clang-format' + pull_request: + branches: [ main ] + +jobs: + formatting-check: + name: Formatting Check + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + path: + - 'src' + - 'include' + - 'tests' + steps: + - uses: actions/checkout@v4 + + - name: Run clang-format style check + uses: jidicula/clang-format-action@v4.15.0 + with: + clang-format-version: '20' + check-path: ${{ matrix.path }} diff --git a/include/regular_path_query.hpp b/include/regular_path_query.hpp index f870237..09b1eda 100644 --- a/include/regular_path_query.hpp +++ b/include/regular_path_query.hpp @@ -3,20 +3,20 @@ #include cuBool_Matrix regular_path_query_with_transposed( - // vector of sparse graph matrices for each label - const std::vector &graph, const std::vector &source_vertices, - // vector of sparse automaton matrices for each label - const std::vector &automaton, const std::vector &start_states, - // transposed matrices for graph and automaton - const std::vector &graph_transposed, - const std::vector &automaton_transposed, + // vector of sparse graph matrices for each label + const std::vector& graph, const std::vector& source_vertices, + // vector of sparse automaton matrices for each label + const std::vector& automaton, const std::vector& start_states, + // transposed matrices for graph and automaton + const std::vector& graph_transposed, + const std::vector& automaton_transposed, - const std::vector &inversed_labels = {}, bool all_labels_are_inversed = false); + const std::vector& inversed_labels = {}, bool all_labels_are_inversed = false); cuBool_Matrix regular_path_query( - // vector of sparse graph matrices for each label - const std::vector &graph, const std::vector &source_vertices, - // vector of sparse automaton matrices for each label - const std::vector &automaton, const std::vector &start_states, + // vector of sparse graph matrices for each label + const std::vector& graph, const std::vector& source_vertices, + // vector of sparse automaton matrices for each label + const std::vector& automaton, const std::vector& start_states, - const std::vector &inversed_labels = {}, bool all_labels_are_inversed = false); + const std::vector& inversed_labels = {}, bool all_labels_are_inversed = false); diff --git a/src/regular_path_query.cpp b/src/regular_path_query.cpp index f26a72c..5376c6d 100644 --- a/src/regular_path_query.cpp +++ b/src/regular_path_query.cpp @@ -7,187 +7,187 @@ #include "regular_path_query.hpp" cuBool_Matrix regular_path_query_with_transposed( - // vector of sparse graph matrices for each label - const std::vector &graph, const std::vector &source_vertices, - // vector of sparse automaton matrices for each label - const std::vector &automaton, const std::vector &start_states, - // transposed matrices for graph and automaton - const std::vector &graph_transposed, - const std::vector &automaton_transposed, - - const std::vector &inversed_labels_input, bool all_labels_are_inversed) { - cuBool_Status status; - - auto inversed_labels = inversed_labels_input; - inversed_labels.resize(std::max(graph.size(), automaton.size())); - - for (uint32_t i = 0; i < inversed_labels.size(); i++) { - bool is_inverse = inversed_labels[i]; - is_inverse ^= all_labels_are_inversed; - inversed_labels[i] = is_inverse; - } - - cuBool_Index graph_nodes_number = 0; - cuBool_Index automaton_nodes_number = 0; - - // get number of graph nodes - for (auto label_matrix : graph) { - if (label_matrix != nullptr) { - cuBool_Matrix_Nrows(label_matrix, &graph_nodes_number); - break; + // vector of sparse graph matrices for each label + const std::vector& graph, const std::vector& source_vertices, + // vector of sparse automaton matrices for each label + const std::vector& automaton, const std::vector& start_states, + // transposed matrices for graph and automaton + const std::vector& graph_transposed, + const std::vector& automaton_transposed, + + const std::vector& inversed_labels_input, bool all_labels_are_inversed) { + cuBool_Status status; + + auto inversed_labels = inversed_labels_input; + inversed_labels.resize(std::max(graph.size(), automaton.size())); + + for (uint32_t i = 0; i < inversed_labels.size(); i++) { + bool is_inverse = inversed_labels[i]; + is_inverse ^= all_labels_are_inversed; + inversed_labels[i] = is_inverse; } - } - // get number of automaton nodes - for (auto label_matrix : automaton) { - if (label_matrix != nullptr) { - cuBool_Matrix_Nrows(label_matrix, &automaton_nodes_number); - break; - } - } - - // this will be answer - cuBool_Matrix reacheble {}; - status = cuBool_Matrix_New(&reacheble, automaton_nodes_number, graph_nodes_number); - assert(status == CUBOOL_STATUS_SUCCESS); - - // allocate neccessary for algorithm matrices - cuBool_Matrix frontier {}, symbol_frontier {}, next_frontier {}; - status = cuBool_Matrix_New(&next_frontier, automaton_nodes_number, graph_nodes_number); - assert(status == CUBOOL_STATUS_SUCCESS); - status = cuBool_Matrix_New(&frontier, automaton_nodes_number, graph_nodes_number); - assert(status == CUBOOL_STATUS_SUCCESS); - status = cuBool_Matrix_New(&symbol_frontier, automaton_nodes_number, graph_nodes_number); - assert(status == CUBOOL_STATUS_SUCCESS); - - // init start values of algorithm matricies - for (const auto state : start_states) { - for (const auto vert : source_vertices) { - assert(state < automaton_nodes_number); - assert(vert < graph_nodes_number); - cuBool_Matrix_SetElement(next_frontier, state, vert); - cuBool_Matrix_SetElement(reacheble, state, vert); - } - } + cuBool_Index graph_nodes_number = 0; + cuBool_Index automaton_nodes_number = 0; - cuBool_Index states = source_vertices.size(); + // get number of graph nodes + for (auto label_matrix : graph) { + if (label_matrix != nullptr) { + cuBool_Matrix_Nrows(label_matrix, &graph_nodes_number); + break; + } + } - // temporary matrix for write result of cubool functions - cuBool_Matrix result; - status = cuBool_Matrix_New(&result, automaton_nodes_number, graph_nodes_number); - assert(status == CUBOOL_STATUS_SUCCESS); + // get number of automaton nodes + for (auto label_matrix : automaton) { + if (label_matrix != nullptr) { + cuBool_Matrix_Nrows(label_matrix, &automaton_nodes_number); + break; + } + } - const auto label_number = std::min(graph.size(), automaton.size()); - while (states > 0) { - std::swap(frontier, next_frontier); + // this will be answer + cuBool_Matrix reacheble{}; + status = cuBool_Matrix_New(&reacheble, automaton_nodes_number, graph_nodes_number); + assert(status == CUBOOL_STATUS_SUCCESS); - // clear next_frontier - status = cuBool_Matrix_Build(next_frontier, nullptr, nullptr, 0, CUBOOL_HINT_NO); + // allocate neccessary for algorithm matrices + cuBool_Matrix frontier{}, symbol_frontier{}, next_frontier{}; + status = cuBool_Matrix_New(&next_frontier, automaton_nodes_number, graph_nodes_number); + assert(status == CUBOOL_STATUS_SUCCESS); + status = cuBool_Matrix_New(&frontier, automaton_nodes_number, graph_nodes_number); + assert(status == CUBOOL_STATUS_SUCCESS); + status = cuBool_Matrix_New(&symbol_frontier, automaton_nodes_number, graph_nodes_number); assert(status == CUBOOL_STATUS_SUCCESS); - for (int i = 0; i < label_number; i++) { - if (graph[i] == nullptr || automaton[i] == nullptr) { - continue; - } - - cuBool_Matrix automaton_matrix = all_labels_are_inversed ? automaton[i] : automaton_transposed[i]; - status = cuBool_MxM(symbol_frontier, automaton_matrix, frontier, CUBOOL_HINT_NO); - assert(status == CUBOOL_STATUS_SUCCESS); - - // next_frontier += (symbol_frontier * graph[i]) & (!reachible) - // multiply 2 matrices - cuBool_Matrix graph_matrix = inversed_labels[i] ? graph_transposed[i] : graph[i]; - status = cuBool_MxM(next_frontier, symbol_frontier, graph_matrix, CUBOOL_HINT_ACCUMULATE); - assert(status == CUBOOL_STATUS_SUCCESS); - // apply invert mask - status = cuBool_Matrix_EWiseMulInverted(result, next_frontier, reacheble, CUBOOL_HINT_NO); - assert(status == CUBOOL_STATUS_SUCCESS); - std::swap(result, next_frontier); + // init start values of algorithm matricies + for (const auto state : start_states) { + for (const auto vert : source_vertices) { + assert(state < automaton_nodes_number); + assert(vert < graph_nodes_number); + cuBool_Matrix_SetElement(next_frontier, state, vert); + cuBool_Matrix_SetElement(reacheble, state, vert); + } } - // this must be accumulate with mask and save old value: reacheble += next_frontier & reacheble - status = cuBool_Matrix_EWiseAdd(result, reacheble, next_frontier, CUBOOL_HINT_NO); + cuBool_Index states = source_vertices.size(); + + // temporary matrix for write result of cubool functions + cuBool_Matrix result; + status = cuBool_Matrix_New(&result, automaton_nodes_number, graph_nodes_number); assert(status == CUBOOL_STATUS_SUCCESS); - std::swap(result, reacheble); - cuBool_Matrix_Nvals(next_frontier, &states); - } + const auto label_number = std::min(graph.size(), automaton.size()); + while (states > 0) { + std::swap(frontier, next_frontier); + + // clear next_frontier + status = cuBool_Matrix_Build(next_frontier, nullptr, nullptr, 0, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); + + for (int i = 0; i < label_number; i++) { + if (graph[i] == nullptr || automaton[i] == nullptr) { + continue; + } + + cuBool_Matrix automaton_matrix = all_labels_are_inversed ? automaton[i] : automaton_transposed[i]; + status = cuBool_MxM(symbol_frontier, automaton_matrix, frontier, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); + + // next_frontier += (symbol_frontier * graph[i]) & (!reachible) + // multiply 2 matrices + cuBool_Matrix graph_matrix = inversed_labels[i] ? graph_transposed[i] : graph[i]; + status = cuBool_MxM(next_frontier, symbol_frontier, graph_matrix, CUBOOL_HINT_ACCUMULATE); + assert(status == CUBOOL_STATUS_SUCCESS); + // apply invert mask + status = cuBool_Matrix_EWiseMulInverted(result, next_frontier, reacheble, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); + std::swap(result, next_frontier); + } + + // this must be accumulate with mask and save old value: reacheble += next_frontier & reacheble + status = cuBool_Matrix_EWiseAdd(result, reacheble, next_frontier, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); + std::swap(result, reacheble); + + cuBool_Matrix_Nvals(next_frontier, &states); + } - // free matrix necessary for algorithm - cuBool_Matrix_Free(next_frontier); - cuBool_Matrix_Free(frontier); - cuBool_Matrix_Free(symbol_frontier); - cuBool_Matrix_Free(result); + // free matrix necessary for algorithm + cuBool_Matrix_Free(next_frontier); + cuBool_Matrix_Free(frontier); + cuBool_Matrix_Free(symbol_frontier); + cuBool_Matrix_Free(result); - return reacheble; + return reacheble; } cuBool_Matrix regular_path_query( - // vector of sparse graph matrices for each label - const std::vector &graph, const std::vector &source_vertices, - // vector of sparse automaton matrices for each label - const std::vector &automaton, const std::vector &start_states, - // work with inverted labels - const std::vector &inversed_labels_input, bool all_labels_are_inversed) { - cuBool_Status status; - - // transpose graph matrices - std::vector graph_transposed; - graph_transposed.reserve(graph.size()); - for (uint32_t i = 0; i < graph.size(); i++) { - graph_transposed.emplace_back(); - - auto label_matrix = graph[i]; - if (label_matrix == nullptr) { - continue; + // vector of sparse graph matrices for each label + const std::vector& graph, const std::vector& source_vertices, + // vector of sparse automaton matrices for each label + const std::vector& automaton, const std::vector& start_states, + // work with inverted labels + const std::vector& inversed_labels_input, bool all_labels_are_inversed) { + cuBool_Status status; + + // transpose graph matrices + std::vector graph_transposed; + graph_transposed.reserve(graph.size()); + for (uint32_t i = 0; i < graph.size(); i++) { + graph_transposed.emplace_back(); + + auto label_matrix = graph[i]; + if (label_matrix == nullptr) { + continue; + } + + cuBool_Index nrows, ncols; + cuBool_Matrix_Nrows(label_matrix, &nrows); + cuBool_Matrix_Ncols(label_matrix, &ncols); + + status = cuBool_Matrix_New(&graph_transposed.back(), ncols, nrows); + assert(status == CUBOOL_STATUS_SUCCESS); + status = cuBool_Matrix_Transpose(graph_transposed.back(), label_matrix, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); } - cuBool_Index nrows, ncols; - cuBool_Matrix_Nrows(label_matrix, &nrows); - cuBool_Matrix_Ncols(label_matrix, &ncols); - - status = cuBool_Matrix_New(&graph_transposed.back(), ncols, nrows); - assert(status == CUBOOL_STATUS_SUCCESS); - status = cuBool_Matrix_Transpose(graph_transposed.back(), label_matrix, CUBOOL_HINT_NO); - assert(status == CUBOOL_STATUS_SUCCESS); - } - - // transpose automaton matrices - std::vector automaton_transposed; - automaton_transposed.reserve(automaton.size()); - for (auto label_matrix : automaton) { - automaton_transposed.emplace_back(); - if (label_matrix == nullptr) { - continue; + // transpose automaton matrices + std::vector automaton_transposed; + automaton_transposed.reserve(automaton.size()); + for (auto label_matrix : automaton) { + automaton_transposed.emplace_back(); + if (label_matrix == nullptr) { + continue; + } + + cuBool_Index nrows, ncols; + cuBool_Matrix_Nrows(label_matrix, &nrows); + cuBool_Matrix_Ncols(label_matrix, &ncols); + + status = cuBool_Matrix_New(&automaton_transposed.back(), ncols, nrows); + assert(status == CUBOOL_STATUS_SUCCESS); + status = cuBool_Matrix_Transpose(automaton_transposed.back(), label_matrix, CUBOOL_HINT_NO); + assert(status == CUBOOL_STATUS_SUCCESS); } - cuBool_Index nrows, ncols; - cuBool_Matrix_Nrows(label_matrix, &nrows); - cuBool_Matrix_Ncols(label_matrix, &ncols); - - status = cuBool_Matrix_New(&automaton_transposed.back(), ncols, nrows); - assert(status == CUBOOL_STATUS_SUCCESS); - status = cuBool_Matrix_Transpose(automaton_transposed.back(), label_matrix, CUBOOL_HINT_NO); - assert(status == CUBOOL_STATUS_SUCCESS); - } - - auto result = regular_path_query_with_transposed( - graph, source_vertices, - automaton, start_states, - graph_transposed, automaton_transposed, - inversed_labels_input, all_labels_are_inversed); + auto result = regular_path_query_with_transposed( + graph, source_vertices, + automaton, start_states, + graph_transposed, automaton_transposed, + inversed_labels_input, all_labels_are_inversed); - for (cuBool_Matrix matrix : graph_transposed) { - if (matrix != nullptr) { - cuBool_Matrix_Free(matrix); + for (cuBool_Matrix matrix : graph_transposed) { + if (matrix != nullptr) { + cuBool_Matrix_Free(matrix); + } } - } - for (cuBool_Matrix matrix : automaton_transposed) { - if (matrix != nullptr) { - cuBool_Matrix_Free(matrix); + for (cuBool_Matrix matrix : automaton_transposed) { + if (matrix != nullptr) { + cuBool_Matrix_Free(matrix); + } } - } - return result; + return result; } diff --git a/tests/main.cpp b/tests/main.cpp index 76f841f..5ebbc76 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -1,6 +1,6 @@ #include -int main(int argc, char **argv) { +int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } diff --git a/tests/rpq_tests.cpp b/tests/rpq_tests.cpp index 5e78391..d5922b6 100644 --- a/tests/rpq_tests.cpp +++ b/tests/rpq_tests.cpp @@ -14,182 +14,182 @@ #include "regular_path_query.hpp" struct Config { - std::vector graph_data; - std::vector automaton_data; - std::vector sources; - std::string expexted; - std::string meta_data; - std::string sources_data; + std::vector graph_data; + std::vector automaton_data; + std::vector sources; + std::string expexted; + std::string meta_data; + std::string sources_data; }; -static bool test_on_config(const Config &config) { - cuBool_Initialize(CUBOOL_HINT_NO); - - std::vector graph; - std::vector source_vertices; - std::vector automaton; - std::vector start_states; - - int64_t nrows = 0, ncols = 0; - std::vector rows, cols; - std::vector vals; - - // load graph - cuBool_Index graph_rows = 0; - graph.reserve(config.graph_data.size()); - for (const auto &data : config.graph_data) { - graph.emplace_back(); - if (data.empty()) { - continue; +static bool test_on_config(const Config& config) { + cuBool_Initialize(CUBOOL_HINT_NO); + + std::vector graph; + std::vector source_vertices; + std::vector automaton; + std::vector start_states; + + int64_t nrows = 0, ncols = 0; + std::vector rows, cols; + std::vector vals; + + // load graph + cuBool_Index graph_rows = 0; + graph.reserve(config.graph_data.size()); + for (const auto& data : config.graph_data) { + graph.emplace_back(); + if (data.empty()) { + continue; + } + + std::ifstream file(data); + if (!file) { + std::cout << data << std::endl; + throw std::runtime_error("error open file"); + } + fast_matrix_market::read_matrix_market_triplet(file, nrows, ncols, rows, cols, vals); + + cuBool_Matrix_New(&graph.back(), nrows, ncols); + cuBool_Matrix_Build(graph.back(), rows.data(), cols.data(), vals.size(), CUBOOL_HINT_NO); + + graph_rows = std::max(graph_rows, (cuBool_Index) nrows); } - std::ifstream file(data); - if (!file) { - std::cout << data << std::endl; - throw std::runtime_error("error open file"); + cuBool_Index automaton_rows = 0; + // load automaton + automaton.reserve(config.automaton_data.size()); + for (const auto& data : config.automaton_data) { + automaton.emplace_back(); + if (data.empty()) { + continue; + } + + std::ifstream file(data); + if (!file) { + throw std::runtime_error("error open file"); + } + fast_matrix_market::read_matrix_market_triplet(file, nrows, ncols, rows, cols, vals); + + cuBool_Matrix_New(&automaton.back(), nrows, ncols); + cuBool_Matrix_Build(automaton.back(), rows.data(), cols.data(), vals.size(), CUBOOL_HINT_NO); + + automaton_rows = std::max(automaton_rows, (cuBool_Index) nrows); } - fast_matrix_market::read_matrix_market_triplet(file, nrows, ncols, rows, cols, vals); - cuBool_Matrix_New(&graph.back(), nrows, ncols); - cuBool_Matrix_Build(graph.back(), rows.data(), cols.data(), vals.size(), CUBOOL_HINT_NO); + // temporary hardcoded + source_vertices = {0}; + start_states = {0}; - graph_rows = std::max(graph_rows, (cuBool_Index)nrows); - } - - cuBool_Index automaton_rows = 0; - // load automaton - automaton.reserve(config.automaton_data.size()); - for (const auto &data : config.automaton_data) { - automaton.emplace_back(); - if (data.empty()) { - continue; + source_vertices = config.sources; + for (cuBool_Index& s : source_vertices) { + s--; } - std::ifstream file(data); - if (!file) { - throw std::runtime_error("error open file"); + auto answer = regular_path_query(graph, source_vertices, automaton, start_states); + + cuBool_Vector P, F; + cuBool_Vector_New(&P, graph_rows); + cuBool_Vector_New(&F, automaton_rows); + + std::vector final_states(automaton_rows); + std::iota(final_states.begin(), final_states.end(), 0); + + cuBool_Vector_Build(F, final_states.data(), final_states.size(), CUBOOL_HINT_NO); + cuBool_VxM(P, F, answer, CUBOOL_HINT_NO); + uint32_t result = 0; + cuBool_Vector_Nvals(P, &result); + + bool test_result = true; + + // validate answer + cuBool_Index nvals; + cuBool_Matrix_Nvals(answer, &nvals); + rows.resize(nvals); + cols.resize(nvals); + cuBool_Matrix_ExtractPairs(answer, rows.data(), cols.data(), &nvals); + + std::set> indexes{}; + for (int i = 0; i < nvals; i++) { + indexes.insert({rows[i], cols[i]}); } - fast_matrix_market::read_matrix_market_triplet(file, nrows, ncols, rows, cols, vals); - - cuBool_Matrix_New(&automaton.back(), nrows, ncols); - cuBool_Matrix_Build(automaton.back(), rows.data(), cols.data(), vals.size(), CUBOOL_HINT_NO); - - automaton_rows = std::max(automaton_rows, (cuBool_Index)nrows); - } - - // temporary hardcoded - source_vertices = {0}; - start_states = {0}; - - source_vertices = config.sources; - for (cuBool_Index &s : source_vertices) { - s--; - } - - auto answer = regular_path_query(graph, source_vertices, automaton, start_states); - - cuBool_Vector P, F; - cuBool_Vector_New(&P, graph_rows); - cuBool_Vector_New(&F, automaton_rows); - - std::vector final_states(automaton_rows); - std::iota(final_states.begin(), final_states.end(), 0); - - cuBool_Vector_Build(F, final_states.data(), final_states.size(), CUBOOL_HINT_NO); - cuBool_VxM(P, F, answer, CUBOOL_HINT_NO); - uint32_t result = 0; - cuBool_Vector_Nvals(P, &result); - - bool test_result = true; - - // validate answer - cuBool_Index nvals; - cuBool_Matrix_Nvals(answer, &nvals); - rows.resize(nvals); - cols.resize(nvals); - cuBool_Matrix_ExtractPairs(answer, rows.data(), cols.data(), &nvals); - - std::set> indexes {}; - for (int i = 0; i < nvals; i++) { - indexes.insert({rows[i], cols[i]}); - } - - std::ifstream expected_file(config.expexted.data()); - cuBool_Index expected_nvals; - expected_file >> expected_nvals; - - if (expected_nvals != nvals) { - test_result = false; - } else { - for (int k = 0; k < expected_nvals; k++) { - int i, j; - expected_file >> i >> j; - if (!indexes.contains({i, j})) { + + std::ifstream expected_file(config.expexted.data()); + cuBool_Index expected_nvals; + expected_file >> expected_nvals; + + if (expected_nvals != nvals) { test_result = false; - break; - } + } else { + for (int k = 0; k < expected_nvals; k++) { + int i, j; + expected_file >> i >> j; + if (!indexes.contains({i, j})) { + test_result = false; + break; + } + } } - } - cuBool_Vector_Free(F); - cuBool_Vector_Free(P); - cuBool_Matrix_Free(answer); + cuBool_Vector_Free(F); + cuBool_Vector_Free(P); + cuBool_Matrix_Free(answer); - for (auto matrix : graph) { - if (matrix != nullptr) { - cuBool_Matrix_Free(matrix); + for (auto matrix : graph) { + if (matrix != nullptr) { + cuBool_Matrix_Free(matrix); + } } - } - for (auto matrix : automaton) { - if (matrix != nullptr) { - cuBool_Matrix_Free(matrix); + for (auto matrix : automaton) { + if (matrix != nullptr) { + cuBool_Matrix_Free(matrix); + } } - } - cuBool_Finalize(); + cuBool_Finalize(); - return test_result; + return test_result; } static std::string get_path(std::string_view file) { - return std::format("{}/rpq/{}", TESTS_DATA_PATH, file); + return std::format("{}/rpq/{}", TESTS_DATA_PATH, file); } TEST(RPQ, Tests) { - std::vector configs { - { - .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, - .automaton_data {get_path("1/a.mtx"), ""}, - .sources = {1}, - .expexted = get_path("1/expected.txt"), - }, - { - .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, - .automaton_data {get_path("2/a.mtx"), get_path("2/b.mtx")}, - .sources = {2}, - .expexted = get_path("2/expected.txt"), - }, - { - .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, - .automaton_data {get_path("3/a.mtx"), get_path("3/b.mtx")}, - .sources = {3, 6}, - .expexted = get_path("3/expected.txt"), - }, - { - .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, - .automaton_data {"", get_path("4/b.mtx")}, - .sources = {4}, - .expexted = get_path("4/expected.txt"), - }, - { - .graph_data = {get_path("5/graph_a.mtx"), get_path("5/graph_b.mtx")}, - .automaton_data = {get_path("5/automaton_a.mtx"), get_path("5/automaton_b.mtx")}, - .sources = {1}, - .expexted = get_path("5/expected.txt"), - }, - }; - - for (const auto &config : configs) { - EXPECT_TRUE(test_on_config(config)); - } + std::vector configs{ + { + .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, + .automaton_data{get_path("1/a.mtx"), ""}, + .sources = {1}, + .expexted = get_path("1/expected.txt"), + }, + { + .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, + .automaton_data{get_path("2/a.mtx"), get_path("2/b.mtx")}, + .sources = {2}, + .expexted = get_path("2/expected.txt"), + }, + { + .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, + .automaton_data{get_path("3/a.mtx"), get_path("3/b.mtx")}, + .sources = {3, 6}, + .expexted = get_path("3/expected.txt"), + }, + { + .graph_data = {get_path("a.mtx"), get_path("b.mtx")}, + .automaton_data{"", get_path("4/b.mtx")}, + .sources = {4}, + .expexted = get_path("4/expected.txt"), + }, + { + .graph_data = {get_path("5/graph_a.mtx"), get_path("5/graph_b.mtx")}, + .automaton_data = {get_path("5/automaton_a.mtx"), get_path("5/automaton_b.mtx")}, + .sources = {1}, + .expexted = get_path("5/expected.txt"), + }, + }; + + for (const auto& config : configs) { + EXPECT_TRUE(test_on_config(config)); + } }