From 7774e2a316d477c630c3808b411ffe4cadf95be7 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Mon, 17 Oct 2022 11:05:07 +0530 Subject: [PATCH 01/10] added comparision operator in the memref class --- examples/bfsExample.cpp | 7 ++++++- include/Interface/Container.h | 2 ++ lib/Interface/Container.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/examples/bfsExample.cpp b/examples/bfsExample.cpp index aef235e..339f910 100644 --- a/examples/bfsExample.cpp +++ b/examples/bfsExample.cpp @@ -38,8 +38,13 @@ int main() { 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 { T &operator[](size_t index); // release the pointer T *release(); + //comparision operator + bool operator==(const MemRef &other); protected: // Default constructor. diff --git a/lib/Interface/Container.cpp b/lib/Interface/Container.cpp index bb9d6a1..2f19acb 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 From 903f27427bdf3191573d57e1cda81737a479945b Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Mon, 17 Oct 2022 10:03:26 +0530 Subject: [PATCH 02/10] interface_testing_checkpoing1 --- CMakeLists.txt | 21 ++++++++++++ examples/CMakeLists.txt | 2 -- include/Interface/Container.h | 4 +-- lib/Interface/CMakeLists.txt | 1 + unittests/CMakeLists.txt | 2 ++ unittests/Interface/CMakeLists.txt | 12 +++++++ unittests/Interface/ContainerTest.cpp | 3 ++ unittests/Interface/GraphContainerTest.cpp | 40 ++++++++++++++++++++++ 8 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 unittests/CMakeLists.txt create mode 100644 unittests/Interface/CMakeLists.txt create mode 100644 unittests/Interface/ContainerTest.cpp create mode 100644 unittests/Interface/GraphContainerTest.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a945d7..38aa9f5 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/include/Interface/Container.h b/include/Interface/Container.h index ccd88b8..3e3c64f 100644 --- a/include/Interface/Container.h +++ b/include/Interface/Container.h @@ -31,6 +31,8 @@ // - The storage order is NCHW. template class MemRef { public: + // Default constructor. + MemRef(){}; // Constructor from shape. MemRef(intptr_t sizes[N], T init = T(0)); // Constructor from data. @@ -66,8 +68,6 @@ template class MemRef { 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/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..500a9ba --- /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) + +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..90853a1 --- /dev/null +++ b/unittests/Interface/ContainerTest.cpp @@ -0,0 +1,3 @@ +#include "Interface/Container.h" +#include + diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp new file mode 100644 index 0000000..8182e43 --- /dev/null +++ b/unittests/Interface/GraphContainerTest.cpp @@ -0,0 +1,40 @@ +#include "Interface/GraphContainer.h" +#include + +class GraphContainerTest : public ::testing::Test { +protected: + void SetUp() override { + + } + void TearDown() override{ + + } +}; + +TEST_F(GraphContainerTest, adjListUndirectedUnweighted) { + + Graph graph(graph::detail::GRAPH_ADJ_LIST_UNDIRECTED_UNWEIGHTED, 5); + graph.addEdge(0,2); + graph.addEdge(1,2); + graph.addEdge(3,2); + graph.addEdge(0,3); + graph.addEdge(1,3); + + //test only the allocated field of the memref class. + MemRef memref1; + auto memref2 = graph.get_Memref(); + + bool isEqual; + + if(memref1 == memref2) { + isEqual = true; + } + EXPECT_EQ(isEqual, true); + +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + From 4d0fed27be083d100f7bd965f7e90ee62e73db15 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Tue, 18 Oct 2022 10:22:16 +0530 Subject: [PATCH 03/10] solved linker error --- unittests/Interface/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittests/Interface/CMakeLists.txt b/unittests/Interface/CMakeLists.txt index 500a9ba..34c8779 100644 --- a/unittests/Interface/CMakeLists.txt +++ b/unittests/Interface/CMakeLists.txt @@ -4,7 +4,7 @@ add_executable( ContainerTest.cpp ) -target_link_libraries(InterfaceTests gtest gtest_main pthread) +target_link_libraries(InterfaceTests gtest gtest_main pthread BFS) add_dependencies(InterfaceTests Container GraphContainer) From 99e09e732fcdef713d211cff683be97c3e00f0a6 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Tue, 18 Oct 2022 14:03:34 +0530 Subject: [PATCH 04/10] tests working and 2 example test added --- lib/Interface/Container.cpp | 7 +-- unittests/Interface/GraphContainerTest.cpp | 69 ++++++++++++++++++---- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/lib/Interface/Container.cpp b/lib/Interface/Container.cpp index 2f19acb..dc68a49 100644 --- a/lib/Interface/Container.cpp +++ b/lib/Interface/Container.cpp @@ -301,10 +301,9 @@ bool MemRef::operator==(const MemRef &other) { 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; - } - + // if(this->aligned[i * x1 + y1] != other.aligned[i * x1 + y1]) { + // return false; + // } } } diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp index 8182e43..ff9a028 100644 --- a/unittests/Interface/GraphContainerTest.cpp +++ b/unittests/Interface/GraphContainerTest.cpp @@ -13,26 +13,71 @@ class GraphContainerTest : public ::testing::Test { TEST_F(GraphContainerTest, adjListUndirectedUnweighted) { - Graph graph(graph::detail::GRAPH_ADJ_LIST_UNDIRECTED_UNWEIGHTED, 5); - graph.addEdge(0,2); - graph.addEdge(1,2); - graph.addEdge(3,2); - graph.addEdge(0,3); + //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 orignal grpah according to the representaion. + std::cout<<"Orignal Grpah: "< memref1; + //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: "< memref1(aligned, sizes, 0); - if(memref1 == memref2) { - isEqual = true; - } - EXPECT_EQ(isEqual, true); + //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_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 orignal grpah according to the representaion. + std::cout<<"Orignal Grpah: "< memref1(aligned, sizes, 0); + + //Test + EXPECT_EQ(memref1 == memref2, true); } + int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); From dec6401e40e2f27111a361f0c736043dc8944998 Mon Sep 17 00:00:00 2001 From: Sarrah Bastawala Date: Tue, 18 Oct 2022 14:12:38 +0530 Subject: [PATCH 05/10] added tests for weighted graphs --- unittests/Interface/GraphContainerTest.cpp | 79 ++++++++++++++++++++-- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp index ff9a028..af02276 100644 --- a/unittests/Interface/GraphContainerTest.cpp +++ b/unittests/Interface/GraphContainerTest.cpp @@ -21,8 +21,8 @@ TEST_F(GraphContainerTest, adjListUndirectedUnweighted) { graph.addEdge(1,4); graph.addEdge(2,4); - //Print the orignal grpah according to the representaion. - std::cout<<"Orignal Grpah: "< graph(graph::detail::GRAPH_ADJ_LIST_DIRECTED_UNWEIGHTED, 6); @@ -54,16 +54,16 @@ TEST_F(GraphContainerTest, adjListUndirectedWeighted) { graph.addEdge(4,2); graph.addEdge(5,1); - //Print the orignal grpah according to the representaion. - std::cout<<"Orignal Grpah: "< 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: "< 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: "< memref1(aligned, sizes, 0); + + //Test + EXPECT_EQ(memref1 == memref2, true); +} int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); From 79abf7fb04c850dcf2c7895da52e2d4885858474 Mon Sep 17 00:00:00 2001 From: Sarrah Bastawala Date: Tue, 18 Oct 2022 18:27:16 +0530 Subject: [PATCH 06/10] Added tests for 8 cases and rectified weighted directed case --- CMakeLists.txt | 8 +- examples/bfsExample.cpp | 12 +- lib/Interface/GraphContainer.cpp | 6 +- unittests/Interface/ContainerTest.cpp | 2 +- unittests/Interface/GraphContainerTest.cpp | 266 ++++++++++++++++++++- 5 files changed, 279 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 38aa9f5..1440af0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,10 +76,10 @@ if (BUILD_TESTS) FetchContent_MakeAvailable(googletest) endif() -if (BUILD_TESTS) - enable_testing() - add_subdirectory(tests) -endif() +# if (BUILD_TESTS) +# enable_testing() +# add_subdirectory(tests) +# endif() # Add MLIR and LLVM headers to the include path include_directories(${LLVM_INCLUDE_DIRS}) diff --git a/examples/bfsExample.cpp b/examples/bfsExample.cpp index 339f910..a59f4a0 100644 --- a/examples/bfsExample.cpp +++ b/examples/bfsExample.cpp @@ -27,12 +27,12 @@ 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 ( " 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/Interface/ContainerTest.cpp b/unittests/Interface/ContainerTest.cpp index 90853a1..277a592 100644 --- a/unittests/Interface/ContainerTest.cpp +++ b/unittests/Interface/ContainerTest.cpp @@ -1,3 +1,3 @@ -#include "Interface/Container.h" +#include "/home/sarrah/1_data/sra/GraphMLIR/include/Interface/Container.h" #include diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp index af02276..8f99ed5 100644 --- a/unittests/Interface/GraphContainerTest.cpp +++ b/unittests/Interface/GraphContainerTest.cpp @@ -113,7 +113,139 @@ TEST_F(GraphContainerTest, adjListUndirectedWeighted) { TEST_F(GraphContainerTest, adjListDirectedWeighted) { //Create object of the Graph class and add edges. - Graph graph(graph::detail::GRAPH_ADJ_LIST_DIRECTED_WEIGHTED, 6); + 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: "< 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: "< 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: "< 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: "< 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); @@ -143,6 +275,138 @@ TEST_F(GraphContainerTest, adjListDirectedWeighted) { 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: "< 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: "< 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: "< 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: "< memref1(aligned, sizes, 0); + + //Test + EXPECT_EQ(memref1 == memref2, true); +} + int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); From a136b15050dd6995d77106f0972fd14e5c998f76 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Tue, 18 Oct 2022 18:54:58 +0530 Subject: [PATCH 07/10] trivial changes and clang-format --- lib/Interface/Container.cpp | 51 +- unittests/Interface/ContainerTest.cpp | 4 +- unittests/Interface/GraphContainerTest.cpp | 677 ++++++++++----------- 3 files changed, 346 insertions(+), 386 deletions(-) diff --git a/lib/Interface/Container.cpp b/lib/Interface/Container.cpp index dc68a49..8115793 100644 --- a/lib/Interface/Container.cpp +++ b/lib/Interface/Container.cpp @@ -279,35 +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]; +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 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; - } + // 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; - // } - } - } + 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; + return true; } #endif // CORE_CONTAINER_DEF diff --git a/unittests/Interface/ContainerTest.cpp b/unittests/Interface/ContainerTest.cpp index 277a592..2180533 100644 --- a/unittests/Interface/ContainerTest.cpp +++ b/unittests/Interface/ContainerTest.cpp @@ -1,3 +1 @@ -#include "/home/sarrah/1_data/sra/GraphMLIR/include/Interface/Container.h" -#include - +#include diff --git a/unittests/Interface/GraphContainerTest.cpp b/unittests/Interface/GraphContainerTest.cpp index 8f99ed5..c3fab19 100644 --- a/unittests/Interface/GraphContainerTest.cpp +++ b/unittests/Interface/GraphContainerTest.cpp @@ -1,414 +1,375 @@ #include "Interface/GraphContainer.h" -#include +#include class GraphContainerTest : public ::testing::Test { protected: - void SetUp() override { - - } - void TearDown() override{ - - } + 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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: "< memref1(aligned, sizes, 0); - - //Test - EXPECT_EQ(memref1 == memref2, true); + // 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(); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } - From f578d83f504dc092866164cc25e44aee0b07a971 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Mon, 24 Oct 2022 01:51:33 +0530 Subject: [PATCH 08/10] added tests for the MemRef class, constructors, and overloaded operators --- unittests/Interface/ContainerTest.cpp | 80 +++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/unittests/Interface/ContainerTest.cpp b/unittests/Interface/ContainerTest.cpp index 2180533..2d83d0e 100644 --- a/unittests/Interface/ContainerTest.cpp +++ b/unittests/Interface/ContainerTest.cpp @@ -1 +1,81 @@ +#include "Interface/Container.h" #include + +template +void ASSERT_ARRAY_EQ(const T *x, const T *y, const size_t n) { + if (std::is_integral::value) { + for (size_t i = 0; i < n; i++) { + ASSERT_EQ(x[i], y[i]); + } + } else if (std::is_same::value) { + for (size_t i = 0; i < n; i++) { + ASSERT_FLOAT_EQ(x[i], y[i]); + } + } else if (std::is_same::value) { + for (size_t i = 0; i < n; i++) { + ASSERT_DOUBLE_EQ(x[i], y[i]); + } + } +} + +class MemRefTest : public ::testing::Test { +protected: + void SetUp() override {} + void TearDown() override {} +}; + + +// Copy constructor. +TEST_F(MemRefTest, CopyConstructor2DMemref) { + // 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 m(aligned, sizes, 0); + MemRef copy(m); + EXPECT_EQ(m == copy, true); + +} + +// Copy assignment operator. +TEST_F(MemRefTest, CopyAssignment2DMemref) { + // 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 m(aligned, sizes, 0); + MemRef copy = m; + EXPECT_EQ(m == copy, true); +} + +// Move constructor. +TEST_F(MemRefTest, MoveConstructor2DMemref) { + // 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 m(aligned, sizes, 0); + + //move + MemRef move = std::move(m); + + //test + EXPECT_EQ(m == move, true); +} + +// Move assignment operator. +TEST_F(MemRefTest, MoveAssignment2DMemref) { + // 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 m(aligned, sizes, 0); + + //move + MemRef move = std::move(m); + + //test + EXPECT_EQ(m == move, true); + +} + From a2039bd5ea351a873ac4cdbc068df15da9a0daef Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Tue, 8 Nov 2022 09:07:54 +0530 Subject: [PATCH 09/10] requested changes. --- CMakeLists.txt | 8 +------ examples/bfsExample.cpp | 19 +++++++---------- lib/Interface/Container.cpp | 7 ++----- {unittests => tests/unittests}/CMakeLists.txt | 1 - .../unittests}/Interface/CMakeLists.txt | 0 .../unittests}/Interface/ContainerTest.cpp | 21 +++++++++---------- .../Interface/GraphContainerTest.cpp | 0 7 files changed, 20 insertions(+), 36 deletions(-) rename {unittests => tests/unittests}/CMakeLists.txt (96%) rename {unittests => tests/unittests}/Interface/CMakeLists.txt (100%) rename {unittests => tests/unittests}/Interface/ContainerTest.cpp (86%) rename {unittests => tests/unittests}/Interface/GraphContainerTest.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1440af0..b730240 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,16 +71,10 @@ if (BUILD_TESTS) 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}) @@ -100,7 +94,7 @@ include_directories(${GraphMLIR_SOURCE_DIR}/lib) add_subdirectory(include) add_subdirectory(lib) add_subdirectory(tools) -add_subdirectory(unittests) +add_subdirectory(tests/unittests) if(GraphMLIR_EXAMPLES) add_subdirectory(examples) diff --git a/examples/bfsExample.cpp b/examples/bfsExample.cpp index a59f4a0..aef235e 100644 --- a/examples/bfsExample.cpp +++ b/examples/bfsExample.cpp @@ -27,24 +27,19 @@ int main() { // use for weighted graph Graph sample_graph( - 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); + 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); // 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 "<::operator==(const MemRef &other) { 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; } - // if(this->aligned[i * x1 + y1] != other.aligned[i * x1 + y1]) { - // return false; - // } } } diff --git a/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt similarity index 96% rename from unittests/CMakeLists.txt rename to tests/unittests/CMakeLists.txt index 1d50731..4dc828d 100644 --- a/unittests/CMakeLists.txt +++ b/tests/unittests/CMakeLists.txt @@ -1,2 +1 @@ add_subdirectory(Interface) - diff --git a/unittests/Interface/CMakeLists.txt b/tests/unittests/Interface/CMakeLists.txt similarity index 100% rename from unittests/Interface/CMakeLists.txt rename to tests/unittests/Interface/CMakeLists.txt diff --git a/unittests/Interface/ContainerTest.cpp b/tests/unittests/Interface/ContainerTest.cpp similarity index 86% rename from unittests/Interface/ContainerTest.cpp rename to tests/unittests/Interface/ContainerTest.cpp index 2d83d0e..2386815 100644 --- a/unittests/Interface/ContainerTest.cpp +++ b/tests/unittests/Interface/ContainerTest.cpp @@ -24,7 +24,6 @@ class MemRefTest : public ::testing::Test { void TearDown() override {} }; - // Copy constructor. TEST_F(MemRefTest, CopyConstructor2DMemref) { // new hard codede MemRef object. @@ -34,7 +33,6 @@ TEST_F(MemRefTest, CopyConstructor2DMemref) { MemRef m(aligned, sizes, 0); MemRef copy(m); EXPECT_EQ(m == copy, true); - } // Copy assignment operator. @@ -56,11 +54,13 @@ TEST_F(MemRefTest, MoveConstructor2DMemref) { intptr_t sizes[2] = {6, 6}; MemRef m(aligned, sizes, 0); - //move + // create a copy of the the hardcoded MemRef and compare it with the stolen + // memref + MemRef m_copy = m; MemRef move = std::move(m); - //test - EXPECT_EQ(m == move, true); + // test + EXPECT_EQ(m_copy == move, true); } // Move assignment operator. @@ -70,12 +70,11 @@ TEST_F(MemRefTest, MoveAssignment2DMemref) { 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 m(aligned, sizes, 0); - - //move - MemRef move = std::move(m); - //test - EXPECT_EQ(m == move, true); + // create a copy of the hardcoded MemRef and compare it with the stolen MemRef + MemRef m_copy = m; + MemRef move = std::move(m); + // test + EXPECT_EQ(m_copy == move, true); } - diff --git a/unittests/Interface/GraphContainerTest.cpp b/tests/unittests/Interface/GraphContainerTest.cpp similarity index 100% rename from unittests/Interface/GraphContainerTest.cpp rename to tests/unittests/Interface/GraphContainerTest.cpp From 84d7aa046a789abcc94b0f32841dd42c78347dd7 Mon Sep 17 00:00:00 2001 From: Rishikesh Donadkar Date: Mon, 27 Feb 2023 11:51:55 +0530 Subject: [PATCH 10/10] Requested changes in Interface Tests. 1. Removed the print statements in tests. 2. Use different approach for testing the move assignment operator and the move constructor. 3. Steal the members of the original object using std::swap() as the constructor MemRef::MemRef cannot be called directly. 4. Remove unwanted variable in CMakeLists.txt --- CMakeLists.txt | 1 - lib/Interface/Container.cpp | 16 ++- tests/unittests/Interface/ContainerTest.cpp | 22 ++-- .../Interface/GraphContainerTest.cpp | 112 +++--------------- 4 files changed, 37 insertions(+), 114 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b730240..4689358 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,7 +71,6 @@ if (BUILD_TESTS) googletest URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip ) - set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_MakeAvailable(googletest) endif() diff --git a/lib/Interface/Container.cpp b/lib/Interface/Container.cpp index 669a67c..c4c5752 100644 --- a/lib/Interface/Container.cpp +++ b/lib/Interface/Container.cpp @@ -179,8 +179,16 @@ template MemRef &MemRef::operator=(MemRef &&other) noexcept { // Free the original aligned and allocated space. delete[] allocated; - // Copy members of the original object. - MemRef::MemRef(other); + // Steal members of the original object. + std::swap(strides, other.strides); + std::swap(offset, other.offset); + std::swap(sizes, other.sizes); + std::swap(size, other.size); + std::swap(allocated, other.allocated); + std::swap(aligned, other.aligned); + // Assign the NULL pointer to the original aligned and allocated members to + // avoid the double free error. + other.allocated = other.aligned = nullptr; return *this; } @@ -299,8 +307,8 @@ bool MemRef::operator==(const MemRef &other) { for (intptr_t i = 0; i < x1; i++) { for (intptr_t j = 0; j < y1; j++) { - if(this->aligned[i * x1 + y1] != other.aligned[i * x1 + y1]) { - return false; + if (this->aligned[i * x1 + y1] != other.aligned[i * x1 + y1]) { + return false; } } } diff --git a/tests/unittests/Interface/ContainerTest.cpp b/tests/unittests/Interface/ContainerTest.cpp index 2386815..278703f 100644 --- a/tests/unittests/Interface/ContainerTest.cpp +++ b/tests/unittests/Interface/ContainerTest.cpp @@ -52,15 +52,14 @@ TEST_F(MemRefTest, MoveConstructor2DMemref) { 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 m(aligned, sizes, 0); + MemRef m1(aligned, sizes, 0); + MemRef m2(aligned, sizes, 0); - // create a copy of the the hardcoded MemRef and compare it with the stolen - // memref - MemRef m_copy = m; - MemRef move = std::move(m); + // Construct using move constructor. + MemRef move = std::move(m1); // test - EXPECT_EQ(m_copy == move, true); + EXPECT_EQ(m2 == move, true); } // Move assignment operator. @@ -69,12 +68,13 @@ TEST_F(MemRefTest, MoveAssignment2DMemref) { 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 m(aligned, sizes, 0); + MemRef m1(aligned, sizes, 0); + MemRef m2(aligned, sizes, 0); - // create a copy of the hardcoded MemRef and compare it with the stolen MemRef - MemRef m_copy = m; - MemRef move = std::move(m); + MemRef move; + // Assignment using the move assignment operator. + move = std::move(m1); // test - EXPECT_EQ(m_copy == move, true); + EXPECT_EQ(m2 == move, true); } diff --git a/tests/unittests/Interface/GraphContainerTest.cpp b/tests/unittests/Interface/GraphContainerTest.cpp index c3fab19..d12a976 100644 --- a/tests/unittests/Interface/GraphContainerTest.cpp +++ b/tests/unittests/Interface/GraphContainerTest.cpp @@ -17,17 +17,10 @@ TEST_F(GraphContainerTest, adjListUndirectedUnweighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp auto memref2 = graph.get_Memref(); - std::cout << "Graph in linera 2D form: " << std::endl; - graph.printGraph(); - // new hard codede MemRef object. + // new hard coded 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}; @@ -47,15 +40,8 @@ TEST_F(GraphContainerTest, adjListDirectedUnweighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -77,15 +63,8 @@ TEST_F(GraphContainerTest, adjListUndirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -107,15 +86,8 @@ TEST_F(GraphContainerTest, adjListDirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -138,17 +110,10 @@ TEST_F(GraphContainerTest, adjMatrixUndirectedUnweighted) { 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. + // new hard coded 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}; @@ -168,15 +133,8 @@ TEST_F(GraphContainerTest, adjMatrixDirectedUnweighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -198,15 +156,8 @@ TEST_F(GraphContainerTest, adjMatrixUndirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -228,15 +179,8 @@ TEST_F(GraphContainerTest, adjMatrixDirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -259,17 +203,10 @@ TEST_F(GraphContainerTest, incMatrixUndirectedUnweighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp auto memref2 = graph.get_Memref(); - std::cout << "Graph in linera 2D form: " << std::endl; - graph.printGraph(); - // new hard codede MemRef object. + // new hard coded 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}; @@ -289,15 +226,8 @@ TEST_F(GraphContainerTest, incMatrixDirectedUnweighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -319,15 +249,8 @@ TEST_F(GraphContainerTest, incMatrixUndirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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, @@ -349,15 +272,8 @@ TEST_F(GraphContainerTest, incMatrixDirectedWeighted) { 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 + // convert the graph to MemRef using the functions in GraphContainer.cpp 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,