1
2 #include "Mongoose_EdgeCut.hpp"
3 #include "Mongoose_IO.hpp"
4 #include <iostream>
5 #include "Mongoose_Test.hpp"
6
7 using namespace Mongoose;
8
9 int RunAllTests(const std::string &inputFile, EdgeCut_Options*);
10
11 int RunTest(const std::string &inputFile, const EdgeCut_Options*, int allowedMallocs);
12
13 /* Custom memory management functions allow for memory testing. */
14 int AllowedMallocs;
15
myMalloc(size_t size)16 void *myMalloc(size_t size)
17 {
18 if(AllowedMallocs <= 0) return NULL;
19 AllowedMallocs--;
20 return malloc(size);
21 }
22
myCalloc(size_t count,size_t size)23 void *myCalloc(size_t count, size_t size)
24 {
25 if(AllowedMallocs <= 0) return NULL;
26 AllowedMallocs--;
27 return calloc(count, size);
28 }
29
myRealloc(void * ptr,size_t newSize)30 void *myRealloc(void *ptr, size_t newSize)
31 {
32 if(AllowedMallocs <= 0) return NULL;
33 AllowedMallocs--;
34 return realloc(ptr, newSize);
35 }
36
myFree(void * ptr)37 void myFree(void *ptr)
38 {
39 if(ptr != NULL) free(ptr);
40 }
41
runMemoryTest(const std::string & inputFile)42 int runMemoryTest(const std::string &inputFile)
43 {
44 EdgeCut_Options *options = EdgeCut_Options::create();
45
46 if(!options)
47 {
48 LogTest("Error creating Options struct in Memory Test");
49 return EXIT_FAILURE; // Return early if we failed.
50 }
51
52 /* Override SuiteSparse memory management with custom testers. */
53 SuiteSparse_config.malloc_func = myMalloc;
54 SuiteSparse_config.calloc_func = myCalloc;
55 SuiteSparse_config.realloc_func = myRealloc;
56 SuiteSparse_config.free_func = myFree;
57
58 int status = RunAllTests(inputFile, options);
59
60 options->~EdgeCut_Options();
61
62 return status;
63 }
64
RunAllTests(const std::string & inputFile,EdgeCut_Options * options)65 int RunAllTests (const std::string &inputFile, EdgeCut_Options *options)
66 {
67 LogTest("Running Memory Test on " << inputFile);
68
69 int m = 0;
70 int remainingMallocs;
71
72 MatchingStrategy matchingStrategies[4] = {Random, HEM, HEMSR, HEMSRdeg};
73 InitialEdgeCutType guessCutStrategies[3] = {InitialEdgeCut_QP, InitialEdgeCut_Random, InitialEdgeCut_NaturalOrder};
74 Int coarsenLimit[3] = {64, 256, 1024};
75
76 for(int c = 0; c < 2; c++)
77 {
78 options->do_community_matching = static_cast<bool>(c);
79
80 for(int i = 0; i < 4; i++)
81 {
82 options->matching_strategy = matchingStrategies[i];
83
84 for(int j = 0; j < 3; j++)
85 {
86 options->initial_cut_type = guessCutStrategies[j];
87 for(int k = 0; k < 3; k++)
88 {
89 options->coarsen_limit = coarsenLimit[k];
90 m = 0;
91 do {
92 remainingMallocs = RunTest(inputFile, options, m);
93 if (remainingMallocs == -1)
94 {
95 // Error!
96 LogTest("Terminating Memory Test Early");
97 return EXIT_FAILURE;
98 }
99 m += 1;
100 } while (remainingMallocs < 1);
101 }
102 }
103 }
104 }
105
106 // Run once with no options struct
107 m = 0;
108 do {
109 remainingMallocs = RunTest(inputFile, NULL, m);
110 if (remainingMallocs == -1)
111 {
112 // Error!
113 LogTest("Terminating Memory Test Early");
114 return EXIT_FAILURE;
115 }
116 m += 1;
117 } while (remainingMallocs < 1);
118
119 LogTest("Memory Test Completed Successfully");
120 return EXIT_SUCCESS;
121 }
122
RunTest(const std::string & inputFile,const EdgeCut_Options * O,int allowedMallocs)123 int RunTest (const std::string &inputFile, const EdgeCut_Options *O, int allowedMallocs)
124 {
125 /* Set the # of mallocs that we're allowed. */
126 AllowedMallocs = allowedMallocs;
127
128 /* Read and condition the matrix from the MM file. */
129 Graph *U = read_graph(inputFile);
130 if (!U) return AllowedMallocs;
131
132 EdgeCut *result;
133
134 if (O)
135 {
136 result = edge_cut(U, O);
137 }
138 else
139 {
140 result = edge_cut(U);
141 }
142
143 U->~Graph();
144
145 if (result != NULL)
146 result->~EdgeCut();
147
148 return AllowedMallocs;
149 }