timeFactorOverhead.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* ----------------------------------------------------------------------------
  2. * GTSAM Copyright 2010, Georgia Tech Research Corporation,
  3. * Atlanta, Georgia 30332-0415
  4. * All Rights Reserved
  5. * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
  6. * See LICENSE for the license information
  7. * -------------------------------------------------------------------------- */
  8. /**
  9. * @file timeFactorOverhead.cpp
  10. * @brief Compares times of solving large single-factor graphs with their multi-factor equivalents.
  11. * @author Richard Roberts
  12. * @date Aug 20, 2010
  13. */
  14. #include <gtsam/base/timing.h>
  15. #include <gtsam/linear/GaussianBayesNet.h>
  16. #include <gtsam/linear/GaussianFactorGraph.h>
  17. #include <gtsam/linear/NoiseModel.h>
  18. #include <gtsam/linear/VectorValues.h>
  19. #include <random>
  20. #include <vector>
  21. using namespace gtsam;
  22. using namespace std;
  23. static std::mt19937 rng;
  24. static std::uniform_real_distribution<> uniform(0.0, 1.0);
  25. int main(int argc, char *argv[]) {
  26. Key key = 0;
  27. size_t vardim = 2;
  28. size_t blockdim = 1;
  29. size_t nBlocks = 4000;
  30. size_t nTrials = 20;
  31. double blockbuild, blocksolve, combbuild, combsolve;
  32. cout << "\n1 variable of dimension " << vardim << ", " <<
  33. nBlocks << " blocks of dimension " << blockdim << "\n";
  34. cout << nTrials << " trials\n";
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Timing test with blockwise Gaussian factor graphs
  37. {
  38. // Build GFG's
  39. cout << "Building blockwise Gaussian factor graphs... ";
  40. cout.flush();
  41. gttic_(blockbuild);
  42. vector<GaussianFactorGraph> blockGfgs;
  43. blockGfgs.reserve(nTrials);
  44. for(size_t trial=0; trial<nTrials; ++trial) {
  45. blockGfgs.push_back(GaussianFactorGraph());
  46. SharedDiagonal noise = noiseModel::Isotropic::Sigma(blockdim, 1.0);
  47. for(size_t i=0; i<nBlocks; ++i) {
  48. // Generate a random Gaussian factor
  49. Matrix A(blockdim, vardim);
  50. for(size_t j=0; j<blockdim; ++j)
  51. for(size_t k=0; k<vardim; ++k)
  52. A(j,k) = uniform(rng);
  53. Vector b(blockdim);
  54. for(size_t j=0; j<blockdim; ++j)
  55. b(j) = uniform(rng);
  56. blockGfgs[trial].push_back(boost::make_shared<JacobianFactor>(key, A, b, noise));
  57. }
  58. }
  59. gttoc_(blockbuild);
  60. tictoc_getNode(blockbuildNode, blockbuild);
  61. blockbuild = blockbuildNode->secs();
  62. cout << blockbuild << " s" << endl;
  63. // Solve GFG's
  64. cout << "Solving blockwise Gaussian factor graphs... ";
  65. cout.flush();
  66. gttic_(blocksolve);
  67. for(size_t trial=0; trial<nTrials; ++trial) {
  68. // cout << "Trial " << trial << endl;
  69. GaussianBayesNet::shared_ptr gbn = blockGfgs[trial].eliminateSequential();
  70. VectorValues soln = gbn->optimize();
  71. }
  72. gttoc_(blocksolve);
  73. tictoc_getNode(blocksolveNode, blocksolve);
  74. blocksolve = blocksolveNode->secs();
  75. cout << blocksolve << " s" << endl;
  76. }
  77. /////////////////////////////////////////////////////////////////////////////
  78. // Timing test with combined-factor Gaussian factor graphs
  79. {
  80. // Build GFG's
  81. cout << "Building combined-factor Gaussian factor graphs... ";
  82. cout.flush();
  83. gttic_(combbuild);
  84. vector<GaussianFactorGraph> combGfgs;
  85. for(size_t trial=0; trial<nTrials; ++trial) {
  86. combGfgs.push_back(GaussianFactorGraph());
  87. SharedDiagonal noise = noiseModel::Isotropic::Sigma(blockdim, 1.0);
  88. Matrix Acomb(blockdim*nBlocks, vardim);
  89. Vector bcomb(blockdim*nBlocks);
  90. for(size_t i=0; i<nBlocks; ++i) {
  91. // Generate a random Gaussian factor
  92. for(size_t j=0; j<blockdim; ++j)
  93. for(size_t k=0; k<vardim; ++k)
  94. Acomb(blockdim*i+j, k) = uniform(rng);
  95. Vector b(blockdim);
  96. for(size_t j=0; j<blockdim; ++j)
  97. bcomb(blockdim*i+j) = uniform(rng);
  98. }
  99. combGfgs[trial].push_back(boost::make_shared<JacobianFactor>(key, Acomb, bcomb,
  100. noiseModel::Isotropic::Sigma(blockdim*nBlocks, 1.0)));
  101. }
  102. gttoc(combbuild);
  103. tictoc_getNode(combbuildNode, combbuild);
  104. combbuild = combbuildNode->secs();
  105. cout << combbuild << " s" << endl;
  106. // Solve GFG's
  107. cout << "Solving combined-factor Gaussian factor graphs... ";
  108. cout.flush();
  109. gttic_(combsolve);
  110. for(size_t trial=0; trial<nTrials; ++trial) {
  111. GaussianBayesNet::shared_ptr gbn = combGfgs[trial].eliminateSequential();
  112. VectorValues soln = gbn->optimize();
  113. }
  114. gttoc_(combsolve);
  115. tictoc_getNode(combsolveNode, combsolve);
  116. combsolve = combsolveNode->secs();
  117. cout << combsolve << " s" << endl;
  118. }
  119. /////////////////////////////////////////////////////////////////////////////
  120. // Print per-graph times
  121. cout << "\nPer-factor-graph times for building and solving\n";
  122. cout << "Blockwise: total " << (1000.0*(blockbuild+blocksolve)/double(nTrials)) <<
  123. " build " << (1000.0*blockbuild/double(nTrials)) <<
  124. " solve " << (1000.0*blocksolve/double(nTrials)) << " ms/graph\n";
  125. cout << "Combined: total " << (1000.0*(combbuild+combsolve)/double(nTrials)) <<
  126. " build " << (1000.0*combbuild/double(nTrials)) <<
  127. " solve " << (1000.0*combsolve/double(nTrials)) << " ms/graph\n";
  128. cout << "Fraction of time spent in overhead\n" <<
  129. " total " << (((blockbuild+blocksolve)-(combbuild+combsolve)) / (blockbuild+blocksolve)) << "\n" <<
  130. " build " << ((blockbuild-combbuild) / blockbuild) << "\n" <<
  131. " solve " << ((blocksolve-combsolve) / blocksolve) << "\n";
  132. cout << endl;
  133. return 0;
  134. }