Skip to content

Commit c8ff7d8

Browse files
jeongseok-metafacebook-github-bot
authored andcommitted
Use indicators library for ProgressBar (#278)
Summary: Pull Request resolved: #278 - Replace the ProgressBar implementation with a 3rd-party library, indicators, to support various terminals - Remove the visible option. Downstream should handle enabling and disabling the progress bar programmatically if needed. Reviewed By: yutingye, juliencbmeta Differential Revision: D73077845 fbshipit-source-id: d8c0e07f3d9cc596dc6c7cea1a2fab81b925d568
1 parent fe07ef0 commit c8ff7d8

File tree

9 files changed

+122
-66
lines changed

9 files changed

+122
-66
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ find_package(ezc3d CONFIG REQUIRED)
100100
find_package(Microsoft.GSL CONFIG REQUIRED)
101101
find_package(fmt CONFIG REQUIRED)
102102
find_package(fx-gltf CONFIG REQUIRED)
103+
find_package(indicators 2.3 CONFIG REQUIRED)
103104
find_package(nlohmann_json CONFIG REQUIRED)
104105
find_package(openfbx CONFIG REQUIRED)
105106
find_package(re2 MODULE REQUIRED)
@@ -163,6 +164,7 @@ mt_library(
163164
SOURCES_VARS common_sources
164165
PUBLIC_LINK_LIBRARIES
165166
fmt::fmt
167+
indicators::indicators
166168
spdlog::spdlog
167169
PUBLIC_COMPILE_DEFINITIONS
168170
MOMENTUM_WITH_SPDLOG=1

cmake/momentum-config.cmake.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ find_dependency(ezc3d CONFIG)
2121
find_dependency(Microsoft.GSL CONFIG)
2222
find_dependency(fmt CONFIG)
2323
find_dependency(fx-gltf CONFIG)
24+
find_dependency(indicators 2.3 CONFIG)
2425
find_dependency(nlohmann_json CONFIG)
2526
find_dependency(openfbx CONFIG)
2627
find_dependency(re2 MODULE)

momentum/character_sequence_solver/sequence_solver.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ template <typename T>
207207
double SequenceSolverT<T>::processPerFrameErrors_serial(
208208
SequenceSolverFunctionT<T>* fn,
209209
OnlineBandedHouseholderQR<T>& qrSolver,
210-
ProgressBar& progress) {
210+
ProgressBar* progress) {
211211
double errorSum = 0;
212212
for (size_t iFrame = 0; iFrame < fn->getNumFrames(); ++iFrame) {
213213
auto [jacobian, residual, errorCur, nFunctions] = computePerFrameJacobian(fn, iFrame);
@@ -221,7 +221,9 @@ double SequenceSolverT<T>::processPerFrameErrors_serial(
221221
residual);
222222
}
223223

224-
progress.increment(nFunctions);
224+
if (progress) {
225+
progress->increment(nFunctions);
226+
}
225227
}
226228
return errorSum;
227229
}
@@ -259,7 +261,7 @@ double SequenceSolverT<T>::processErrorFunctions_parallel(
259261
OnlineBandedHouseholderQR<T>& qrSolver)>& processJac,
260262
SequenceSolverFunctionT<T>* fn,
261263
OnlineBandedHouseholderQR<T>& qrSolver,
262-
ProgressBar& progress) {
264+
ProgressBar* progress) {
263265
const size_t end = fn->getNumFrames();
264266

265267
// We will buffer at the end of the pipeline to ensure the universal parts of the matrices are
@@ -323,7 +325,9 @@ double SequenceSolverT<T>::processErrorFunctions_parallel(
323325
} else {
324326
qrSolver.addMutating(toProcess.jacobian, toProcess.residual);
325327
errorSum += toProcess.error;
326-
progress.increment(toProcess.nFunctions);
328+
if (progress) {
329+
progress->increment(toProcess.nFunctions);
330+
}
327331
}
328332
}
329333
}
@@ -338,7 +342,9 @@ double SequenceSolverT<T>::processErrorFunctions_parallel(
338342
while (!readyJacobians.empty()) {
339343
qrSolver.addMutating(readyJacobians.front().jacobian, readyJacobians.front().residual);
340344
errorSum += readyJacobians.front().error;
341-
progress.increment(readyJacobians.front().nFunctions);
345+
if (progress) {
346+
progress->increment(readyJacobians.front().nFunctions);
347+
}
342348
readyJacobians.pop_front();
343349
}
344350
}
@@ -348,7 +354,9 @@ double SequenceSolverT<T>::processErrorFunctions_parallel(
348354
while (!reorderBuffer.empty()) {
349355
qrSolver.addMutating(reorderBuffer.top().jacobian, reorderBuffer.top().residual);
350356
errorSum += reorderBuffer.top().error;
351-
progress.increment(reorderBuffer.top().nFunctions);
357+
if (progress) {
358+
progress->increment(reorderBuffer.top().nFunctions);
359+
}
352360
reorderBuffer.pop();
353361
}
354362
}
@@ -362,7 +370,7 @@ template <typename T>
362370
double SequenceSolverT<T>::processPerFrameErrors_parallel(
363371
SequenceSolverFunctionT<T>* fn,
364372
OnlineBandedHouseholderQR<T>& qrSolver,
365-
ProgressBar& progress) {
373+
ProgressBar* progress) {
366374
return processErrorFunctions_parallel(
367375
[](size_t iFrame,
368376
SequenceSolverFunctionT<T>* fn,
@@ -403,7 +411,7 @@ template <typename T>
403411
double SequenceSolverT<T>::processSequenceErrors_serial(
404412
SequenceSolverFunctionT<T>* fn,
405413
OnlineBandedHouseholderQR<T>& qrSolver,
406-
ProgressBar& progress) {
414+
ProgressBar* progress) {
407415
if (fn->numTotalSequenceErrorFunctions_ == 0) {
408416
return 0;
409417
}
@@ -434,7 +442,9 @@ double SequenceSolverT<T>::processSequenceErrors_serial(
434442
residual);
435443
}
436444

437-
progress.increment(nFunctions);
445+
if (progress) {
446+
progress->increment(nFunctions);
447+
}
438448
}
439449
return errorSum;
440450
}
@@ -454,20 +464,22 @@ void SequenceSolverT<T>::doIteration() {
454464

455465
fn->setFrameParametersFromJoinedParameterVector(this->parameters_);
456466

457-
ProgressBar progress(
458-
"Solving sequence",
459-
fn->numTotalPerFrameErrorFunctions_ + fn->numTotalSequenceErrorFunctions_,
460-
progressBar_);
467+
std::unique_ptr<ProgressBar> progress;
468+
if (progressBar_) {
469+
progress = std::make_unique<ProgressBar>(
470+
"Solving sequence",
471+
fn->numTotalPerFrameErrorFunctions_ + fn->numTotalSequenceErrorFunctions_);
472+
}
461473

462474
this->error_ = 0;
463475
if (this->multithreaded_) {
464-
this->error_ += processPerFrameErrors_parallel(fn, qrSolver, progress);
476+
this->error_ += processPerFrameErrors_parallel(fn, qrSolver, progress.get());
465477

466478
// Sequence errors still have to be be processed serially, at least for now.
467-
this->error_ += processSequenceErrors_serial(fn, qrSolver, progress);
479+
this->error_ += processSequenceErrors_serial(fn, qrSolver, progress.get());
468480
} else {
469-
this->error_ += processPerFrameErrors_serial(fn, qrSolver, progress);
470-
this->error_ += processSequenceErrors_serial(fn, qrSolver, progress);
481+
this->error_ += processPerFrameErrors_serial(fn, qrSolver, progress.get());
482+
this->error_ += processSequenceErrors_serial(fn, qrSolver, progress.get());
471483
}
472484

473485
// Now, extract the delta:

momentum/character_sequence_solver/sequence_solver.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,16 @@ class SequenceSolverT : public SolverT<T> {
8080
static double processPerFrameErrors_parallel(
8181
SequenceSolverFunctionT<T>* fn,
8282
OnlineBandedHouseholderQR<T>& qrSolver,
83-
ProgressBar& progress);
83+
ProgressBar* progress);
8484
static double processPerFrameErrors_serial(
8585
SequenceSolverFunctionT<T>* fn,
8686
OnlineBandedHouseholderQR<T>& qrSolver,
87-
ProgressBar& progress);
87+
ProgressBar* progress);
8888

8989
static double processSequenceErrors_serial(
9090
SequenceSolverFunctionT<T>* fn,
9191
OnlineBandedHouseholderQR<T>& qrSolver,
92-
ProgressBar& progress);
92+
ProgressBar* progress);
9393

9494
struct UniversalJacobianResid {
9595
size_t frameIndex = SIZE_MAX;
@@ -116,7 +116,7 @@ class SequenceSolverT : public SolverT<T> {
116116
OnlineBandedHouseholderQR<T>&)>& processJac,
117117
SequenceSolverFunctionT<T>* fn,
118118
OnlineBandedHouseholderQR<T>& qrSolver,
119-
ProgressBar& progress);
119+
ProgressBar* progress);
120120

121121
// Returns the [Jacobian, residual, error] for all the error functions applying to a single frame:
122122
static std::tuple<Eigen::MatrixX<T>, Eigen::VectorX<T>, double, size_t> computePerFrameJacobian(

momentum/common/progress_bar.cpp

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,29 @@
77

88
#include "momentum/common/progress_bar.h"
99

10-
#include <iostream>
11-
1210
namespace momentum {
1311

14-
ProgressBar::ProgressBar(const std::string& name, const int64_t numOperations, bool visible)
15-
: numHashes_(std::max(maxWidth - (int64_t)name.size() - 1, (int64_t)50)),
16-
numOperations_(numOperations),
17-
visible_(visible) {
18-
if (visible_) {
19-
std::cout << name << " " << std::flush;
20-
}
12+
ProgressBar::ProgressBar(const std::string& name, const int64_t numOperations) {
13+
using namespace indicators;
14+
15+
bar_.set_option(option::BarWidth(kMaxWidth - name.size() - 9));
16+
bar_.set_option(option::MaxProgress(numOperations));
17+
bar_.set_option(option::Start{"["});
18+
bar_.set_option(option::Fill{"="});
19+
bar_.set_option(option::Lead{">"});
20+
bar_.set_option(option::Remainder{" "});
21+
bar_.set_option(option::End{"]"});
22+
bar_.set_option(option::PrefixText{name});
23+
bar_.set_option(option::ShowPercentage{true});
24+
bar_.set_option(option::FontStyles{std::vector<FontStyle>{FontStyle::bold}});
2125
}
2226

2327
void ProgressBar::increment(int64_t count) {
24-
set(curOp_ + count);
28+
bar_.set_progress(bar_.current() + count);
2529
}
2630

2731
void ProgressBar::set(int64_t count) {
28-
curOp_ = count;
29-
const int64_t expectedPrinted = (curOp_ * numHashes_) / numOperations_;
30-
31-
while (numHashesPrinted_ < expectedPrinted) {
32-
if (visible_) {
33-
std::cout.put('#');
34-
std::cout.flush();
35-
}
36-
++numHashesPrinted_;
37-
}
38-
}
39-
40-
ProgressBar::~ProgressBar() {
41-
const size_t nBackspace = maxWidth - (numHashes_ - numHashesPrinted_);
42-
if (visible_) {
43-
for (size_t i = 0; i < nBackspace; ++i) {
44-
std::cout << "\b";
45-
}
46-
for (size_t i = 0; i < nBackspace; ++i) {
47-
std::cout << " ";
48-
}
49-
std::cout << "\r" << std::flush;
50-
}
32+
bar_.set_progress(count);
5133
}
5234

5335
} // namespace momentum

momentum/common/progress_bar.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@
77

88
#pragma once
99

10+
// clang-format off
11+
#include <cstdint> // Must come first. See https://github.com/p-ranav/indicators/pull/124
12+
#include <indicators/progress_bar.hpp>
13+
// clang-format on
14+
1015
#include <string>
1116

1217
namespace momentum {
1318

14-
// A simple progress bar that prints hash marks, e.g.
15-
// Reticulating splines #####################################
19+
// A simple progress bar that prints hash marks (e.g., "Name [===> ] 60%")
1620
class ProgressBar {
17-
const int64_t maxWidth = 80;
21+
static constexpr int64_t kMaxWidth = 80;
1822

1923
public:
20-
ProgressBar(const std::string& name, int64_t numOperations, bool visible = false);
24+
/// @param name Displayed prefix (visible=true only)
25+
/// @param numOperations Total operations (determines progress ratio)
26+
ProgressBar(const std::string& name, int64_t numOperations);
2127
void increment(int64_t count = 1);
2228
void set(int64_t count);
23-
~ProgressBar();
2429

2530
private:
26-
const int64_t numHashes_;
27-
const int64_t numOperations_;
28-
const bool visible_;
29-
30-
int64_t numHashesPrinted_ = 0;
31-
int64_t curOp_ = 0;
31+
indicators::ProgressBar bar_;
3232
};
3333

3434
} // namespace momentum

momentum/marker_tracking/marker_tracker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ Eigen::MatrixXf trackPosesPerframe(
281281
}
282282

283283
{ // scope the ProgressBar so it returns
284-
ProgressBar progress("", numFrames, true);
284+
ProgressBar progress("", numFrames);
285285
for (size_t iFrame = 0; iFrame < numFrames; iFrame += frameStride) {
286286
// reinitialize if not continuous
287287
if (!continuous) {

0 commit comments

Comments
 (0)