diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a945d7..1440af0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,6 +61,26 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${GraphMLIR_BINARY_DIR}) set(GraphMLIR_EXAMPLES OFF CACHE BOOL "Build examples") +#------------------------------------------------------------------------------- +# GoogleTest +#------------------------------------------------------------------------------- +set(BUILD_TESTS ON CACHE BOOL "Build tests") +if (BUILD_TESTS) + include(FetchContent) + FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip + ) + + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(googletest) +endif() + +# if (BUILD_TESTS) +# enable_testing() +# add_subdirectory(tests) +# endif() + # Add MLIR and LLVM headers to the include path include_directories(${LLVM_INCLUDE_DIRS}) include_directories(${MLIR_INCLUDE_DIRS}) @@ -80,6 +100,7 @@ include_directories(${GraphMLIR_SOURCE_DIR}/lib) add_subdirectory(include) add_subdirectory(lib) add_subdirectory(tools) +add_subdirectory(unittests) if(GraphMLIR_EXAMPLES) add_subdirectory(examples) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index ec97a1d..40e5b52 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -11,8 +11,6 @@ BFS PROPERTIES LINKER_LANGUAGE C) - - add_executable(bfsExample bfsExample.cpp) add_dependencies(bfsExample graph-opt) target_link_libraries(bfsExample BFS) diff --git a/examples/bfsExample.cpp b/examples/bfsExample.cpp index aef235e..a59f4a0 100644 --- a/examples/bfsExample.cpp +++ b/examples/bfsExample.cpp @@ -27,19 +27,24 @@ int main() { // use for weighted graph Graph sample_graph( - graph::detail::GRAPH_ADJ_MATRIX_DIRECTED_WEIGHTED, 5); - sample_graph.addEdge(0, 2, 1); - sample_graph.addEdge(2, 3, 3); - sample_graph.addEdge(3, 2, 3); - sample_graph.addEdge(2, 2, 6); - sample_graph.addEdge(1, 2, 2); + graph::detail::GRAPH_INC_MATRIX_DIRECTED_WEIGHTED, 6); + sample_graph.addEdge(1,0,2); + sample_graph.addEdge(3,1,3); + sample_graph.addEdge(4,1,4); + sample_graph.addEdge(4,2,5); + sample_graph.addEdge(5,1,6); // this will print the original graph. std::cout << "Printing graph in format it was entered ( " "GRAPH_ADJ_MARIX_DIRECTED_WEIGHTED )\n"; sample_graph.printGraphOg(); - + auto x = sample_graph.get_Memref(); + auto x1 = sample_graph.get_Memref(); + + if (x == x1) { + std::cout<< "the two memref are equal "< class MemRef { public: + // Default constructor. + MemRef(){}; // Constructor from shape. MemRef(intptr_t sizes[N], T init = T(0)); // Constructor from data. @@ -62,10 +64,10 @@ template class MemRef { T &operator[](size_t index); // release the pointer T *release(); + //comparision operator + bool operator==(const MemRef &other); protected: - // Default constructor. - MemRef(){}; // Set the strides. // Computes the strides of the transposed tensor for transpose=true. void setStrides(); diff --git a/lib/Interface/CMakeLists.txt b/lib/Interface/CMakeLists.txt index 381bd6a..a4b9fc1 100644 --- a/lib/Interface/CMakeLists.txt +++ b/lib/Interface/CMakeLists.txt @@ -1 +1,2 @@ add_library(Container Container.cpp) +add_library(GraphContainer GraphContainer.cpp) diff --git a/lib/Interface/Container.cpp b/lib/Interface/Container.cpp index bb9d6a1..8115793 100644 --- a/lib/Interface/Container.cpp +++ b/lib/Interface/Container.cpp @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include #include @@ -277,4 +279,36 @@ template T *MemRef::release() { return temp; } +template +bool MemRef::operator==(const MemRef &other) { + intptr_t x1 = this->sizes[0]; + intptr_t y1 = this->sizes[1]; + intptr_t x2 = other.sizes[0]; + intptr_t y2 = other.sizes[1]; + + // compare the sizes array and size + if (x1 != x2 || y1 != y2 || this->size != other.size) { + return false; + } + + // compare the strides + if (this->strides[0] != this->strides[0] || + other.strides[1] != other.strides[1]) { + return false; + } + + for (intptr_t i = 0; i < x1; i++) { + for (intptr_t j = 0; j < y1; j++) { + if (this->allocated[i * x1 + y1] != other.allocated[i * x1 + y1]) { + return false; + } + // if(this->aligned[i * x1 + y1] != other.aligned[i * x1 + y1]) { + // return false; + // } + } + } + + return true; +} + #endif // CORE_CONTAINER_DEF diff --git a/lib/Interface/GraphContainer.cpp b/lib/Interface/GraphContainer.cpp index f2d7beb..fd6a652 100644 --- a/lib/Interface/GraphContainer.cpp +++ b/lib/Interface/GraphContainer.cpp @@ -209,7 +209,7 @@ void Graph::addEdge(T Node1, T Node2, T EdgeWeight) { this->incMat[Node2][edgeCount] = EdgeWeight; break; case graph::detail::GRAPH_INC_MATRIX_DIRECTED_WEIGHTED: - EdgeWeight = std::abs(sqrt(EdgeWeight)); + EdgeWeight = EdgeWeight; this->incMat[Node1][edgeCount] = EdgeWeight; this->incMat[Node2][edgeCount] = -EdgeWeight; this->edgeCount += 1; @@ -461,9 +461,9 @@ template void Graph::graph_to_MemRef_descriptor() { for (k = flag + 1; k < this->incMat.size() && flag != -2; k++) { if ((this->incMat[k][j] != 0) && flag != -1) { if (this->incMat[k][j] < this->incMat[int(flag)][j]) - linear[int(flag) * x + k] = pow(incMat[k][j], 2); + linear[int(flag) * x + k] = incMat[k][j]; else - linear[k * x + int(flag)] = pow(incMat[k][j], 2); + linear[k * x + int(flag)] = incMat[k][j]; flag = -1; } } diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt new file mode 100644 index 0000000..1d50731 --- /dev/null +++ b/unittests/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(Interface) + diff --git a/unittests/Interface/CMakeLists.txt b/unittests/Interface/CMakeLists.txt new file mode 100644 index 0000000..34c8779 --- /dev/null +++ b/unittests/Interface/CMakeLists.txt @@ -0,0 +1,12 @@ +add_executable( + InterfaceTests + GraphContainerTest.cpp + ContainerTest.cpp +) + +target_link_libraries(InterfaceTests gtest gtest_main pthread BFS) + +add_dependencies(InterfaceTests Container GraphContainer) + +include(GoogleTest) +gtest_discover_tests(InterfaceTests) diff --git a/unittests/Interface/ContainerTest.cpp b/unittests/Interface/ContainerTest.cpp new file mode 100644 index 0000000..2180533 --- /dev/null +++ b/unittests/Interface/ContainerTest.cpp @@ -0,0 +1 @@ +#include diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp new file mode 100644 index 0000000..c3fab19 --- /dev/null +++ b/unittests/Interface/GraphContainerTest.cpp @@ -0,0 +1,375 @@ +#include "Interface/GraphContainer.h" +#include + +class GraphContainerTest : public ::testing::Test { +protected: + void SetUp() override {} + void TearDown() override {} +}; + +TEST_F(GraphContainerTest, adjListUndirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_LIST_UNDIRECTED_UNWEIGHTED, 6); + graph.addEdge(0, 1); + graph.addEdge(1, 3); + graph.addEdge(1, 5); + graph.addEdge(1, 4); + graph.addEdge(2, 4); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linera 2D form: " << std::endl; + graph.printGraph(); + + // new hard codede MemRef object. + float aligned[] = {0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjListDirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_LIST_DIRECTED_UNWEIGHTED, 6); + graph.addEdge(1, 0); + graph.addEdge(3, 1); + graph.addEdge(4, 1); + graph.addEdge(4, 2); + graph.addEdge(5, 1); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjListUndirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_LIST_UNDIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 2, 0, 0, 0, 0, 2, 0, 0, 3, 4, 6, 0, 0, 0, 0, 5, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjListDirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_LIST_DIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + int aligned[] = {0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjMatrixUndirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_MATRIX_UNDIRECTED_UNWEIGHTED, + 6); + graph.addEdge(0, 1); + graph.addEdge(1, 3); + graph.addEdge(1, 5); + graph.addEdge(1, 4); + graph.addEdge(2, 4); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linera 2D form: " << std::endl; + graph.printGraph(); + + // new hard codede MemRef object. + float aligned[] = {0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjMatrixDirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_MATRIX_DIRECTED_UNWEIGHTED, 6); + graph.addEdge(1, 0); + graph.addEdge(3, 1); + graph.addEdge(4, 1); + graph.addEdge(4, 2); + graph.addEdge(5, 1); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjMatrixUndirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_MATRIX_UNDIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 2, 0, 0, 0, 0, 2, 0, 0, 3, 4, 6, 0, 0, 0, 0, 5, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, adjMatrixDirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_ADJ_MATRIX_DIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, incMatrixUndirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_INC_MATRIX_UNDIRECTED_UNWEIGHTED, + 6); + graph.addEdge(0, 1); + graph.addEdge(1, 3); + graph.addEdge(1, 5); + graph.addEdge(1, 4); + graph.addEdge(2, 4); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linera 2D form: " << std::endl; + graph.printGraph(); + + // new hard codede MemRef object. + float aligned[] = {0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, incMatrixDirectedUnweighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_INC_MATRIX_DIRECTED_UNWEIGHTED, 6); + graph.addEdge(1, 0); + graph.addEdge(3, 1); + graph.addEdge(4, 1); + graph.addEdge(4, 2); + graph.addEdge(5, 1); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, incMatrixUndirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_INC_MATRIX_UNDIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + float aligned[] = {0, 2, 0, 0, 0, 0, 2, 0, 0, 3, 4, 6, 0, 0, 0, 0, 5, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +TEST_F(GraphContainerTest, incMatrixDirectedWeighted) { + + // Create object of the Graph class and add edges. + Graph graph(graph::detail::GRAPH_INC_MATRIX_DIRECTED_WEIGHTED, 6); + graph.addEdge(1, 0, 2); + graph.addEdge(3, 1, 3); + graph.addEdge(4, 1, 4); + graph.addEdge(4, 2, 5); + graph.addEdge(5, 1, 6); + + // Print the original grpah according to the representaion. + std::cout << "Original Grpah: " << std::endl; + graph.printGraphOg(); + + // convert the graph to MemRef using the functions in GraphContainer.cpp and + // print the memref + auto memref2 = graph.get_Memref(); + std::cout << "Graph in linear 2D form: " << std::endl; + graph.printGraph(); + + // new hard coded MemRef object. + int aligned[] = {0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 0, 0, 0, 0, 0, 4, 5, 0, 0, 0, 0, 6, 0, 0, 0, 0}; + intptr_t sizes[2] = {6, 6}; + MemRef memref1(aligned, sizes, 0); + + // Test + EXPECT_EQ(memref1 == memref2, true); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}