Skip to content

Commit 2b21dd7

Browse files
Merge branch 'master' of https://github.com/david-cattermole/mayaMatchMoveSolver into 174-core-solver-add-ceres-solver
2 parents 1109e5a + 5386290 commit 2b21dd7

File tree

5 files changed

+216
-78
lines changed

5 files changed

+216
-78
lines changed

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ set(SOURCE_FILES
4141
mmSolver/adjust/adjust_cminpack_base.cpp
4242
mmSolver/adjust/adjust_cminpack_lmder.cpp
4343
mmSolver/adjust/adjust_cminpack_lmdif.cpp
44+
mmSolver/adjust/adjust_logging.cpp
4445
mmSolver/adjust/adjust_measureErrors.cpp
4546
mmSolver/adjust/adjust_relationships.cpp
4647
mmSolver/adjust/adjust_results_helpers.cpp

src/mmSolver/adjust/adjust_base.cpp

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
#include <maya/MItDependencyGraph.h>
4545
#include <maya/MObject.h>
4646
#include <maya/MPoint.h>
47-
#include <maya/MStreamUtils.h>
4847
#include <maya/MString.h>
4948
#include <maya/MStringArray.h>
5049

@@ -63,6 +62,7 @@
6362
#include "adjust_measureErrors.h"
6463
#include "adjust_relationships.h"
6564
#include "adjust_results.h"
65+
#include "adjust_logging.h"
6666
#include "adjust_solveFunc.h"
6767
#include "mmSolver/mayahelper/maya_attr.h"
6868
#include "mmSolver/mayahelper/maya_camera.h"
@@ -450,53 +450,13 @@ void printSolveDetails(const SolverResult &solverResult, SolverData &userData,
450450
MMSOLVER_MAYA_VRB("Jacobian Evaluations: " << solverResult.jacobianEvals);
451451

452452
if (logLevel >= LogLevel::kInfo) {
453-
if (solverResult.success) {
454-
MStreamUtils::stdErrorStream() << "Solver returned SUCCESS | ";
455-
} else {
456-
MStreamUtils::stdErrorStream() << "Solver returned FAILURE | ";
457-
}
458-
459-
double seconds = mmsolver::debug::timestamp_as_seconds(
460-
mmsolver::debug::get_timestamp() - timer.startTimestamp);
461-
seconds = std::max(1e-9, seconds);
462-
auto evals_per_sec = static_cast<size_t>(
463-
static_cast<double>(solverResult.functionEvals) / seconds);
464-
std::string evals_per_sec_string =
465-
mmstring::numberToStringWithCommas(evals_per_sec);
466-
467-
const auto solverResult_iterations =
468-
static_cast<uint32_t>(solverResult.iterations);
469-
470-
const size_t buffer_size = 128;
471-
char formatBuffer[buffer_size];
472-
std::snprintf(formatBuffer, buffer_size,
473-
"error avg %8.4f min %8.4f max %8.4f "
474-
"iterations %03u (%s evals/sec)",
475-
solverResult.errorAvg, solverResult.errorMin,
476-
solverResult.errorMax, solverResult_iterations,
477-
&evals_per_sec_string[0]);
478-
// Note: We use std::endl to flush the stream, and ensure an
479-
// update for the user.
480-
MMSOLVER_MAYA_INFO(std::string(formatBuffer));
453+
log_solver_results(solverResult, timer);
481454
}
482455

483456
if (logLevel >= LOG_LEVEL_PRINT_SOLVER_TIMING) {
484-
unsigned int total_num = userData.iterNum + userData.jacIterNum;
457+
uint32_t total_num = userData.iterNum + userData.jacIterNum;
485458
MMSOLVER_ASSERT(total_num > 0, "There must have been some iterations.");
486-
static std::ostream &stream = MStreamUtils::stdErrorStream();
487-
timer.solveBenchTimer.print(stream, "Solve Time", 1);
488-
timer.funcBenchTimer.print(stream, "Func Time", 1);
489-
timer.jacBenchTimer.print(stream, "Jacobian Time", 1);
490-
timer.paramBenchTimer.print(stream, "Param Time", total_num);
491-
timer.errorBenchTimer.print(stream, "Error Time", total_num);
492-
timer.funcBenchTimer.print(stream, "Func Time", total_num);
493-
494-
timer.solveBenchTicks.print(stream, "Solve Ticks", 1);
495-
timer.funcBenchTicks.print(stream, "Func Ticks", 1);
496-
timer.jacBenchTicks.print(stream, "Jacobian Ticks", 1);
497-
timer.paramBenchTicks.print(stream, "Param Ticks", total_num);
498-
timer.errorBenchTicks.print(stream, "Error Ticks", total_num);
499-
timer.funcBenchTicks.print(stream, "Func Ticks", total_num);
459+
log_solver_timer(timer, total_num);
500460
}
501461
}
502462

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/*
2+
* Copyright (C) 2018, 2019 David Cattermole.
3+
*
4+
* This file is part of mmSolver.
5+
*
6+
* mmSolver is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* mmSolver is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with mmSolver. If not, see <https://www.gnu.org/licenses/>.
18+
* ====================================================================
19+
*
20+
* Logging functions for the solver to the terminal/Maya Output
21+
* Window.
22+
*/
23+
24+
#include "adjust_solveFunc.h"
25+
26+
// Maya
27+
#include <maya/MStreamUtils.h>
28+
29+
// MM Solver
30+
#include "adjust_data.h"
31+
#include "adjust_results.h"
32+
#include "mmSolver/utilities/assert_utils.h"
33+
#include "mmSolver/utilities/debug_utils.h"
34+
#include "mmSolver/utilities/number_utils.h"
35+
#include "mmSolver/utilities/string_utils.h"
36+
37+
namespace mmsolver {
38+
39+
const char *const LOG_SOLVER_RETURN_SUCCESS = "Solver returned SUCCESS | ";
40+
const char *const LOG_SOLVER_RETURN_FAILURE = "Solver returned FAILURE | ";
41+
const char *const LOG_SOLVER_ITERATION_RESIDUAL_ERROR_FORMAT =
42+
" | error avg %8.4f min %8.4f max %8.4f";
43+
const char *const LOG_SOLVER_END_RESIDUAL_ERROR_FORMAT =
44+
"error avg %8.4f min %8.4f max %8.4f iterations %03u (%s evals/sec)";
45+
46+
void log_solver_iteration_pre_solve(const LogLevel log_level,
47+
const bool is_normal_call,
48+
const bool is_jacobian_call,
49+
const bool do_calc_jacobian,
50+
const int32_t iter_num,
51+
const int32_t func_eval_num,
52+
const int32_t jac_iter_num) {
53+
const bool verbose = false;
54+
MMSOLVER_MAYA_VRB("adjust_logging log_solver_iteration_pre_solve");
55+
56+
if (is_normal_call) {
57+
if (log_level >= LOG_LEVEL_PRINT_NORMAL_ITERATIONS) {
58+
MStreamUtils::stdErrorStream() << "Iteration ";
59+
MStreamUtils::stdErrorStream()
60+
<< std::right << std::setfill('0') << std::setw(4) << iter_num;
61+
MStreamUtils::stdErrorStream() << " | Eval ";
62+
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
63+
<< std::setw(4) << func_eval_num;
64+
}
65+
} else if (is_jacobian_call && !do_calc_jacobian) {
66+
if (log_level >= LOG_LEVEL_PRINT_JACOBIAN_ITERATIONS) {
67+
MStreamUtils::stdErrorStream() << "Jacobian ";
68+
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
69+
<< std::setw(4) << jac_iter_num;
70+
MStreamUtils::stdErrorStream() << " | Eval ";
71+
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
72+
<< std::setw(4) << func_eval_num;
73+
if (do_calc_jacobian) {
74+
MStreamUtils::stdErrorStream() << "\n";
75+
}
76+
}
77+
}
78+
}
79+
80+
void log_solver_iteration_post_solve(
81+
const LogLevel log_level, const bool is_normal_call,
82+
const bool is_jacobian_call, const bool do_calc_jacobian,
83+
const double error_avg, const double error_min, const double error_max) {
84+
const bool verbose = false;
85+
MMSOLVER_MAYA_VRB("adjust_logging log_solver_iteration_post_solve");
86+
87+
if (is_normal_call) {
88+
if (log_level >= LOG_LEVEL_PRINT_NORMAL_ITERATIONS) {
89+
char formatBuffer[128];
90+
sprintf(formatBuffer, LOG_SOLVER_ITERATION_RESIDUAL_ERROR_FORMAT,
91+
error_avg, error_min, error_max);
92+
MStreamUtils::stdErrorStream() << std::string(formatBuffer) << "\n";
93+
}
94+
} else {
95+
if (log_level >= LOG_LEVEL_PRINT_JACOBIAN_ITERATIONS) {
96+
if (!do_calc_jacobian) {
97+
MStreamUtils::stdErrorStream() << "\n";
98+
}
99+
}
100+
}
101+
}
102+
103+
void log_solver_results(const SolverResult &solverResult,
104+
const SolverTimer &timer) {
105+
if (solverResult.success) {
106+
MStreamUtils::stdErrorStream() << LOG_SOLVER_RETURN_SUCCESS;
107+
} else {
108+
MStreamUtils::stdErrorStream() << LOG_SOLVER_RETURN_FAILURE;
109+
}
110+
111+
double seconds = mmsolver::debug::timestamp_as_seconds(
112+
mmsolver::debug::get_timestamp() - timer.startTimestamp);
113+
seconds = std::max(1e-9, seconds);
114+
auto evals_per_sec = static_cast<size_t>(
115+
static_cast<double>(solverResult.functionEvals) / seconds);
116+
std::string evals_per_sec_string =
117+
mmstring::numberToStringWithCommas(evals_per_sec);
118+
119+
const auto solverResult_iterations =
120+
static_cast<uint32_t>(solverResult.iterations);
121+
122+
const size_t buffer_size = 128;
123+
char formatBuffer[buffer_size];
124+
std::snprintf(formatBuffer, buffer_size,
125+
LOG_SOLVER_END_RESIDUAL_ERROR_FORMAT, solverResult.errorAvg,
126+
solverResult.errorMin, solverResult.errorMax,
127+
solverResult_iterations, &evals_per_sec_string[0]);
128+
// Note: We use std::endl to flush the stream, and ensure an
129+
// update for the user.
130+
MStreamUtils::stdErrorStream() << formatBuffer << std::endl;
131+
}
132+
133+
void log_solver_timer(const SolverTimer &timer,
134+
const uint32_t total_iteration_count) {
135+
static std::ostream &stream = MStreamUtils::stdErrorStream();
136+
timer.solveBenchTimer.print(stream, "Solve Time", 1);
137+
timer.funcBenchTimer.print(stream, "Func Time", 1);
138+
timer.jacBenchTimer.print(stream, "Jacobian Time", 1);
139+
timer.paramBenchTimer.print(stream, "Param Time", total_iteration_count);
140+
timer.errorBenchTimer.print(stream, "Error Time", total_iteration_count);
141+
timer.funcBenchTimer.print(stream, "Func Time", total_iteration_count);
142+
143+
timer.solveBenchTicks.print(stream, "Solve Ticks", 1);
144+
timer.funcBenchTicks.print(stream, "Func Ticks", 1);
145+
timer.jacBenchTicks.print(stream, "Jacobian Ticks", 1);
146+
timer.paramBenchTicks.print(stream, "Param Ticks", total_iteration_count);
147+
timer.errorBenchTicks.print(stream, "Error Ticks", total_iteration_count);
148+
timer.funcBenchTicks.print(stream, "Func Ticks", total_iteration_count);
149+
}
150+
151+
} // namespace mmsolver
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2018, 2019 David Cattermole.
3+
*
4+
* This file is part of mmSolver.
5+
*
6+
* mmSolver is free software: you can redistribute it and/or modify it
7+
* under the terms of the GNU Lesser General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* mmSolver is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with mmSolver. If not, see <https://www.gnu.org/licenses/>.
18+
* ====================================================================
19+
*
20+
* Logging functions.
21+
*/
22+
23+
#ifndef MM_SOLVER_CORE_BUNDLE_ADJUST_LOGGING_H
24+
#define MM_SOLVER_CORE_BUNDLE_ADJUST_LOGGING_H
25+
26+
#include "adjust_data.h"
27+
#include "adjust_results.h"
28+
29+
namespace mmsolver {
30+
31+
void log_solver_iteration_pre_solve(const LogLevel log_level,
32+
const bool is_normal_call,
33+
const bool is_jacobian_call,
34+
const bool do_calc_jacobian,
35+
const int32_t iter_num,
36+
const int32_t func_eval_num,
37+
const int32_t jac_iter_num);
38+
39+
void log_solver_iteration_post_solve(
40+
const LogLevel log_level, const bool is_normal_call,
41+
const bool is_jacobian_call, const bool do_calc_jacobian,
42+
const double error_avg, const double error_min, const double error_max);
43+
44+
void log_solver_results(const SolverResult &solverResult,
45+
const SolverTimer &timer);
46+
47+
void log_solver_timer(const SolverTimer &timer,
48+
const uint32_t total_iteration_count);
49+
50+
} // namespace mmsolver
51+
52+
#endif // MM_SOLVER_CORE_BUNDLE_ADJUST_LOGGING_H

src/mmSolver/adjust/adjust_solveFunc.cpp

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
#include <maya/MPoint.h>
5252
#include <maya/MProfiler.h>
5353
#include <maya/MSelectionList.h>
54-
#include <maya/MStreamUtils.h>
5554
#include <maya/MString.h>
5655
#include <maya/MStringArray.h>
5756
#include <maya/MVector.h>
@@ -66,6 +65,7 @@
6665

6766
#include "adjust_base.h"
6867
#include "adjust_data.h"
68+
#include "adjust_logging.h"
6969
#include "adjust_measureErrors.h"
7070
#include "adjust_setParameters.h"
7171
#include "mmSolver/core/matrix_bool_2d.h"
@@ -247,14 +247,6 @@ void incrementNormalIteration(SolverData *userData) {
247247

248248
++userData->funcEvalNum;
249249
++userData->iterNum;
250-
if (userData->logLevel >= LOG_LEVEL_PRINT_NORMAL_ITERATIONS) {
251-
MStreamUtils::stdErrorStream() << "Iteration ";
252-
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
253-
<< std::setw(4) << userData->iterNum;
254-
MStreamUtils::stdErrorStream() << " | Eval ";
255-
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
256-
<< std::setw(4) << userData->funcEvalNum;
257-
}
258250
return;
259251
}
260252

@@ -265,17 +257,6 @@ void incrementJacobianIteration(SolverData *userData) {
265257

266258
++userData->funcEvalNum;
267259
++userData->jacIterNum;
268-
if (userData->logLevel >= LOG_LEVEL_PRINT_JACOBIAN_ITERATIONS) {
269-
MStreamUtils::stdErrorStream() << "Jacobian ";
270-
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
271-
<< std::setw(4) << userData->jacIterNum;
272-
MStreamUtils::stdErrorStream() << " | Eval ";
273-
MStreamUtils::stdErrorStream() << std::right << std::setfill('0')
274-
<< std::setw(4) << userData->funcEvalNum;
275-
if (userData->doCalcJacobian) {
276-
MStreamUtils::stdErrorStream() << "\n";
277-
}
278-
}
279260
return;
280261
}
281262

@@ -621,6 +602,10 @@ int solveFunc(const int numberOfParameters, const int numberOfErrors,
621602
} else if (userData->isJacobianCall && !userData->doCalcJacobian) {
622603
incrementJacobianIteration(userData);
623604
}
605+
mmsolver::log_solver_iteration_pre_solve(
606+
userData->logLevel, userData->isNormalCall, userData->isJacobianCall,
607+
userData->doCalcJacobian, userData->iterNum, userData->funcEvalNum,
608+
userData->jacIterNum);
624609

625610
if (userData->isPrintCall) {
626611
// insert print statements here when nprint is positive.
@@ -710,20 +695,9 @@ int solveFunc(const int numberOfParameters, const int numberOfErrors,
710695
return calculation_status;
711696
}
712697

713-
if (userData->isNormalCall) {
714-
if (userData->logLevel >= LOG_LEVEL_PRINT_NORMAL_ITERATIONS) {
715-
char formatBuffer[128];
716-
sprintf(formatBuffer, " | error avg %8.4f min %8.4f max %8.4f",
717-
error_avg, error_min, error_max);
718-
MStreamUtils::stdErrorStream() << std::string(formatBuffer) << "\n";
719-
}
720-
} else {
721-
if (userData->logLevel >= LOG_LEVEL_PRINT_JACOBIAN_ITERATIONS) {
722-
if (!userData->doCalcJacobian) {
723-
std::cerr << "\n";
724-
}
725-
}
726-
}
698+
mmsolver::log_solver_iteration_post_solve(
699+
userData->logLevel, userData->isNormalCall, userData->isJacobianCall,
700+
userData->doCalcJacobian, error_avg, error_min, error_max);
727701

728702
return SOLVE_FUNC_SUCCESS;
729703
}

0 commit comments

Comments
 (0)