main.cpp 9.36 KB
Newer Older
Dmitry Bagaev's avatar
Dmitry Bagaev committed
1
2
3
4
5
6
7
#include "inmost.h"
#include <string>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <cstdio>

Dmitry Bagaev's avatar
Dmitry Bagaev committed
8
#include <inmost_optimizer.h>
9
#include "series.h"
Dmitry Bagaev's avatar
Dmitry Bagaev committed
10
#include <Source/Misc/utils.h>
Dmitry Bagaev's avatar
Dmitry Bagaev committed
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

using namespace INMOST;

#if defined(USE_MPI)
#define BARRIER MPI_Barrier(MPI_COMM_WORLD)
#else
#define BARRIER
#endif


int main(int argc, char **argv) {
    int rank = 0, size = 1;

#if defined(USE_MPI)
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);  // Get the rank of the current process
    MPI_Comm_size(MPI_COMM_WORLD, &size); // Get the total number of processors used
#endif


    {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
32
        std::string seriesFilePath     = "";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
33
        std::string seriesDirectory    = "";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
34
35
        std::string databaseFilePath   = "";
        std::string parametersFilePath = "";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
36
        std::string solverName         = "fcbiilu2";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
37

Dmitry Bagaev's avatar
Dmitry Bagaev committed
38
        bool seriesFound     = false;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
39
        bool parametersFound = false;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
40
        bool databaseFound   = false;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
41
        bool waitNext        = false;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
42
43
44
45
46
47
48
49
50
51
52
53

        //Parse argv parameters
        if (argc == 1) goto helpMessage;
        int i;
        for (i = 1; i < argc; i++) {
            //Print help message and exit
            if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
                helpMessage:
                if (rank == 0) {
                    std::cout << "Help message: " << std::endl;
                    std::cout << "Command line options: " << std::endl;
                    std::cout << "Required: " << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
54
55
                    std::cout << "-s, --series <Series file path>" << std::endl;
                    std::cout << "-p, --parameters <Optimizer parameters file path>" << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
56
                    std::cout << "Optional: " << std::endl;
57
58
59
60
                    std::cout << "-sd, --series-dir <Series directory path>" << std::endl;
                    std::cout << "-b,  --bvector <RHS vector file name>" << std::endl;
                    std::cout << "-d,  --database <Solver parameters file name>" << std::endl;
                    std::cout << "-t,  --type <Solver type name>" << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
61
                    std::cout << "-w,  --wait " << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
62
63
64
                    std::cout << "  Available solvers:" << std::endl;
                    Solver::Initialize(NULL, NULL, NULL);
                    std::vector<std::string> availableSolvers = Solver::getAvailableSolvers();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
65
                    for (auto                it               = availableSolvers.begin(); it != availableSolvers.end(); ++it) {
Dmitry Bagaev's avatar
2prev    
Dmitry Bagaev committed
66
67
68
                        std::cout << "      " << *it << std::endl;
                    }
                    std::cout << "  Available optimizers:" << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
69
                    std::vector<std::string> availableOptimizers = INMOST::Optimizers::GetAvailableOptimizers();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
70
                    for (auto                it                  = availableOptimizers.begin(); it != availableOptimizers.end(); ++it) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
71
72
73
74
75
76
                        std::cout << "      " << *it << std::endl;
                    }
                    Solver::Finalize();
                }
                return 0;
            }
77
78
            //Series file name found with -s or --series options
            if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--series") == 0) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
79
                seriesFound      = true;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
80
81
                seriesFilePath   = std::string(argv[i + 1]);
                FILE *seriesFile = fopen(seriesFilePath.c_str(), "r");
82
                if (seriesFile == NULL) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
83
                    if (rank == 0) {
84
                        std::cout << "Series file not found: " << argv[i + 1] << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
85
86
87
88
                        exit(1);
                    }
                } else {
                    if (rank == 0) {
89
                        std::cout << "Series file found: " << argv[i + 1] << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
90
91
                    }
                }
92
                fclose(seriesFile);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
93
94
95
                i++;
                continue;
            }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
            if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "--parameters") == 0) {
                parametersFound      = true;
                parametersFilePath   = std::string(argv[i + 1]);
                FILE *parametersFile = fopen(parametersFilePath.c_str(), "r");
                if (parametersFile == NULL) {
                    if (rank == 0) {
                        std::cout << "Parameters file not found: " << argv[i + 1] << std::endl;
                        exit(1);
                    }
                } else {
                    if (rank == 0) {
                        std::cout << "Series file found: " << argv[i + 1] << std::endl;
                    }
                }
                fclose(parametersFile);
                i++;
                continue;
            }
114
115
116
            //Series directory path found with -sd or --series-dir options
            if (strcmp(argv[i], "-sd") == 0 || strcmp(argv[i], "--series-dir") == 0) {
                seriesDirectory = std::string(argv[i + 1]);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
117
                if (rank == 0) {
118
                    std::cout << "Series directory prefix found: " << argv[i + 1] << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
119
120
121
122
123
124
125
126
127
                }
                i++;
                continue;
            }
            //Parameters file name found with -d or --database options
            if (strcmp(argv[i], "-d") == 0 || strcmp(argv[i], "--database") == 0) {
                if (rank == 0) {
                    std::cout << "Solver parameters file found: " << argv[i + 1] << std::endl;
                }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
128
129
                databaseFound    = true;
                databaseFilePath = std::string(argv[i + 1]);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
130
131
132
133
134
135
136
137
138
139
140
141
                i++;
                continue;
            }
            //Solver type found with -t ot --type options
            if (strcmp(argv[i], "-t") == 0 || strcmp(argv[i], "--type") == 0) {
                if (rank == 0) {
                    std::cout << "Solver type index found: " << argv[i + 1] << std::endl;
                }
                solverName = std::string(argv[i + 1]);
                i++;
                continue;
            }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
142
143
144
145
146
            //Wait for each iteration
            if (strcmp(argv[i], "-w") == 0 || strcmp(argv[i], "--wait") == 0) {
                waitNext = true;
                continue;
            }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
147
148
        }

149
        if (!seriesFound) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
150
151
            if (rank == 0) {
                std::cout <<
152
                          "Series file not found, you can specify series file name using -s or --series options, otherwise specify -h option to see all options, exiting...";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
153
154
155
156
            }
            return -1;
        }

Dmitry Bagaev's avatar
Dmitry Bagaev committed
157
158
159
160
161
162
163
164
        if (!parametersFound) {
            if (rank == 0) {
                std::cout <<
                          "Parameters file not found, you can specify series file name using -p or --parameters options, otherwise specify -h option to see all options, exiting...";
            }
            return -1;
        }

165
        // Initialize series
Dmitry Bagaev's avatar
Dmitry Bagaev committed
166
        MatrixSeries series(seriesFilePath, seriesDirectory);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
167

168
        if (series.end()) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
169
170
            if (rank == 0) {
                std::cout <<
171
                          "Series file found, but it looks empty or invalid, please check series file, exiting...";
Dmitry Bagaev's avatar
Dmitry Bagaev committed
172
            }
173
            return -1;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
174
175
176
        }

        // Initialize the linear solver in accordance with args
Dmitry Bagaev's avatar
Dmitry Bagaev committed
177
        Solver::Initialize(&argc, &argv, databaseFound ? databaseFilePath.c_str() : NULL);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
178
179
180
181
182
183
184
185
186

        if (!Solver::isSolverAvailable(solverName)) {
            if (rank == 0) std::cout << "Solver " << solverName << " is not available" << std::endl;
            Solver::Finalize();
            exit(1);
        }

        Solver solver = Solver(solverName, "test");

187
        solver.SetVerbosityLevel(SolverVerbosityLevel::SolverVerbosityLevel0);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
188
        solver.SetParameter("eps", "1e-12");
Dmitry Bagaev's avatar
Dmitry Bagaev committed
189

Dmitry Bagaev's avatar
Dmitry Bagaev committed
190
191
        if (rank == 0) std::cout << "Solving with " << solverName << std::endl;

192
        INMOST::TTSP::Initialize(parametersFilePath);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
193

194
        double total_time = 0.0;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
195

196
        while (!series.end()) {
Dmitry Bagaev's avatar
Dmitry Bagaev committed
197

198
            std::pair<const char *, const char *> next = series.next();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
199

200
201
202
203
            INMOST::Sparse::Matrix matrix("A");
            INMOST::Sparse::Vector rhs("b");
            INMOST::Sparse::Vector x("x");

Dmitry Bagaev's avatar
Dmitry Bagaev committed
204
205
            matrix.Load(next.first);

206
207
208
209
            INMOST_DATA_ENUM_TYPE mbeg, mend;
            matrix.GetInterval(mbeg, mend);

            x.SetInterval(mbeg, mend);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
210
            for (int k = mbeg; k < mend; ++k) {
211
212
213
214
215
216
217
218
219
220
                x[k] = 0.0;
            }

            if (next.second != nullptr) {
                rhs.Load(next.second);
            } else {
                rhs.SetInterval(mbeg, mend);
                for (int k = mbeg; k < mend; ++k) rhs[k] = 1.0;
            }

221
            INMOST::TTSP::SolverOptimize(solver);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
222

223
224
            INMOST::Sparse::Vector SOL("SOL", rhs.GetFirstIndex(), rhs.GetLastIndex());
            std::fill(SOL.Begin(), SOL.End(), 0.0);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
225

226
            INMOST::MPIBarrier();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
227

228
229
230
231
            double tmp_time = Timer();
            solver.SetMatrix(matrix);
            bool is_solved = solver.Solve(rhs, SOL);
            INMOST::MPIBarrier();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
232

233
            double time = Timer() - tmp_time;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
234

235
            total_time += time;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
236

237
            INMOST::TTSP::SolverOptimizeSaveResult(solver, time, is_solved);
Dmitry Bagaev's avatar
Dmitry Bagaev committed
238

Dmitry Bagaev's avatar
Dmitry Bagaev committed
239
240
241
            if (rank == 0 && waitNext) {
                std::cin.get();
            }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
242

Dmitry Bagaev's avatar
Dmitry Bagaev committed
243
            INMOST::MPIBarrier();
Dmitry Bagaev's avatar
Dmitry Bagaev committed
244
        }
Dmitry Bagaev's avatar
Dmitry Bagaev committed
245

246
        std::cout << "Metrics total from " << series.size() << " iterations: " << total_time << " (mean = " << total_time / series.size() << ")" << std::endl;
Dmitry Bagaev's avatar
Dmitry Bagaev committed
247
248
249
250
251
    }

    Solver::Finalize(); // Finalize solver and close MPI activity
    return 0;
}