From 49b40d3942eeef93e8a94ae61180bdd757d585a3 Mon Sep 17 00:00:00 2001 From: Fan Jiang Date: Tue, 12 Apr 2022 13:56:36 -0400 Subject: [PATCH 1/3] Fix slow dynamic cast --- gtsam/nonlinear/Values-inl.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/gtsam/nonlinear/Values-inl.h b/gtsam/nonlinear/Values-inl.h index dfcb7e174c..078ffc502d 100644 --- a/gtsam/nonlinear/Values-inl.h +++ b/gtsam/nonlinear/Values-inl.h @@ -294,7 +294,7 @@ namespace gtsam { // Handle dynamic matrices template struct handle_matrix, true> { - Eigen::Matrix operator()(Key j, const Value* const pointer) { + inline Eigen::Matrix operator()(Key j, const Value* const pointer) { try { // value returns a const Matrix&, and the return makes a copy !!!!! return dynamic_cast>&>(*pointer).value(); @@ -308,16 +308,18 @@ namespace gtsam { // Handle fixed matrices template struct handle_matrix, false> { - Eigen::Matrix operator()(Key j, const Value* const pointer) { - try { + inline Eigen::Matrix operator()(Key j, const Value* const pointer) { + auto ptr = dynamic_cast>*>(pointer); + if (ptr) { // value returns a const MatrixMN&, and the return makes a copy !!!!! return dynamic_cast>&>(*pointer).value(); - } catch (std::bad_cast&) { + } else { Matrix A; - try { + auto ptr = dynamic_cast*>(pointer); + if (ptr) { // Check if a dynamic matrix was stored - A = handle_matrix()(j, pointer); // will throw if not.... - } catch (const ValuesIncorrectType&) { + A = ptr->value(); // will throw if not.... + } else { // Or a dynamic vector A = handle_matrix()(j, pointer); // will throw if not.... } From ed34ee324587d5f8cf64bf83a44e5988671124d9 Mon Sep 17 00:00:00 2001 From: Fan Jiang Date: Tue, 12 Apr 2022 15:09:52 -0400 Subject: [PATCH 2/3] Update the other codepath to also use ptr cast --- gtsam/nonlinear/Values-inl.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/gtsam/nonlinear/Values-inl.h b/gtsam/nonlinear/Values-inl.h index 078ffc502d..0436ade4a9 100644 --- a/gtsam/nonlinear/Values-inl.h +++ b/gtsam/nonlinear/Values-inl.h @@ -295,10 +295,11 @@ namespace gtsam { template struct handle_matrix, true> { inline Eigen::Matrix operator()(Key j, const Value* const pointer) { - try { + auto ptr = dynamic_cast>*>(pointer); + if (ptr) { // value returns a const Matrix&, and the return makes a copy !!!!! - return dynamic_cast>&>(*pointer).value(); - } catch (std::bad_cast&) { + return ptr->value(); + } else { // If a fixed matrix was stored, we end up here as well. throw ValuesIncorrectType(j, typeid(*pointer), typeid(Eigen::Matrix)); } @@ -312,13 +313,13 @@ namespace gtsam { auto ptr = dynamic_cast>*>(pointer); if (ptr) { // value returns a const MatrixMN&, and the return makes a copy !!!!! - return dynamic_cast>&>(*pointer).value(); + return ptr->value(); } else { Matrix A; + // Check if a dynamic matrix was stored auto ptr = dynamic_cast*>(pointer); if (ptr) { - // Check if a dynamic matrix was stored - A = ptr->value(); // will throw if not.... + A = ptr->value(); } else { // Or a dynamic vector A = handle_matrix()(j, pointer); // will throw if not.... From 1b63fb51eb98f10a83d525e8755cf2e9db4bc525 Mon Sep 17 00:00:00 2001 From: Fan Jiang Date: Thu, 14 Apr 2022 13:05:15 -0400 Subject: [PATCH 3/3] Address comments by Frank --- gtsam/nonlinear/Values-inl.h | 15 ++++++++------- gtsam/nonlinear/nonlinear.i | 4 ++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/gtsam/nonlinear/Values-inl.h b/gtsam/nonlinear/Values-inl.h index 0436ade4a9..0370c5ceea 100644 --- a/gtsam/nonlinear/Values-inl.h +++ b/gtsam/nonlinear/Values-inl.h @@ -279,10 +279,11 @@ namespace gtsam { template struct handle { ValueType operator()(Key j, const Value* const pointer) { - try { + auto ptr = dynamic_cast*>(pointer); + if (ptr) { // value returns a const ValueType&, and the return makes a copy !!!!! - return dynamic_cast&>(*pointer).value(); - } catch (std::bad_cast&) { + return ptr->value(); + } else { throw ValuesIncorrectType(j, typeid(*pointer), typeid(ValueType)); } } @@ -367,10 +368,10 @@ namespace gtsam { if(item != values_.end()) { // dynamic cast the type and throw exception if incorrect - const Value& value = *item->second; - try { - return dynamic_cast&>(value).value(); - } catch (std::bad_cast &) { + auto ptr = dynamic_cast*>(item->second); + if (ptr) { + return ptr->value(); + } else { // NOTE(abe): clang warns about potential side effects if done in typeid const Value* value = item->second; throw ValuesIncorrectType(j, typeid(*value), typeid(ValueType)); diff --git a/gtsam/nonlinear/nonlinear.i b/gtsam/nonlinear/nonlinear.i index 326b84d16c..3fff71978c 100644 --- a/gtsam/nonlinear/nonlinear.i +++ b/gtsam/nonlinear/nonlinear.i @@ -245,6 +245,10 @@ class Values { void insert(size_t j, const gtsam::ParameterMatrix<14>& X); void insert(size_t j, const gtsam::ParameterMatrix<15>& X); + template + void insert(size_t j, const T& val); + void update(size_t j, const gtsam::Point2& point2); void update(size_t j, const gtsam::Point3& point3); void update(size_t j, const gtsam::Rot2& rot2);