Skip to content

Commit

Permalink
Fix handling of generated rotation matrix sets in parallel with the '…
Browse files Browse the repository at this point in the history
…rotate' command (Amber-MD#1112)

* Fix accessing the internal rotation matrix data set in parallel for
'rotate'

* Class to choose correct frame number in parallel based on whether a
data set exists or is being generated

* Use ParallelSetFrameNum

* Hide debug info

* 6.29.6. Revision bump for fixed handling of input rotation matrix data
set in rotate command.
  • Loading branch information
drroe authored Oct 29, 2024
1 parent cdf7e30 commit b41f221
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 12 deletions.
21 changes: 12 additions & 9 deletions src/Action_Rotate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ int Action_Rotate::Get3x3Set(DataSetList const& DSL, std::string const& dsname)
mprinterr("Error: No 3x3 matrices data set '%s'\n", dsname.c_str());
return 1;
}
parallelNum_.SetForParallel( rmatrices_ );
return 0;
}

Expand Down Expand Up @@ -201,29 +202,31 @@ Action::RetType Action_Rotate::DoAction(int frameNum, ActionFrame& frm) {
if (all_atoms_selected_)
frm.ModifyFrm().ModifyBox().RotateUcell( RotMatrix_ );
} else if (mode_ == DATASET) {
int dsidx = parallelNum_.ParallelFrameNum(frameNum, frm.TrajoutNum());
// Rotate coordinates using rotation matrices in DataSet
if (frm.TrajoutNum() >= (int)rmatrices_->Size()) {
mprintf("Warning: Frame %i out of range for set '%s'\n",
if (dsidx >= (int)rmatrices_->Size()) {
rprintf("Warning: Frame %i out of range for set '%s'\n",
frm.TrajoutNum()+1, rmatrices_->legend());
return Action::ERR;
}
if (inverse_) {
frm.ModifyFrm().InverseRotate((*rmatrices_)[frm.TrajoutNum()], mask_);
frm.ModifyFrm().InverseRotate((*rmatrices_)[dsidx], mask_);
if (all_atoms_selected_)
frm.ModifyFrm().ModifyBox().InverseRotateUcell( (*rmatrices_)[frm.TrajoutNum()] );
frm.ModifyFrm().ModifyBox().InverseRotateUcell( (*rmatrices_)[dsidx] );
} else {
frm.ModifyFrm().Rotate((*rmatrices_)[frm.TrajoutNum()], mask_);
frm.ModifyFrm().Rotate((*rmatrices_)[dsidx], mask_);
if (all_atoms_selected_)
frm.ModifyFrm().ModifyBox().RotateUcell( (*rmatrices_)[frm.TrajoutNum()] );
frm.ModifyFrm().ModifyBox().RotateUcell( (*rmatrices_)[dsidx] );
}
} else if (mode_ == CALC) {
int dsidx = parallelNum_.ParallelFrameNum(frameNum, frm.TrajoutNum());
// Calculate rotations around X Y and Z axes from rotation matrices in DataSet
if (frm.TrajoutNum() >= (int)rmatrices_->Size()) {
mprintf("Warning: Frame %i out of range for set '%s'\n",
if (dsidx >= (int)rmatrices_->Size()) {
rprintf("Warning: Frame %i out of range for set '%s'\n",
frm.TrajoutNum()+1, rmatrices_->legend());
return Action::ERR;
}
Matrix_3x3 const& RM = (*rmatrices_)[frm.TrajoutNum()];
Matrix_3x3 const& RM = (*rmatrices_)[dsidx];
double tx, ty, tz;
RM.RotationAngles(tx, ty, tz);
tx *= Constants::RADDEG;
Expand Down
2 changes: 2 additions & 0 deletions src/Action_Rotate.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef INC_ACTION_ROTATE_H
#define INC_ACTION_ROTATE_H
#include "Action.h"
#include "ParallelSetFrameNum.h"
class DataSet_Mat3x3;
/// Rotate coordinates or calculate rotations from rotation matrices
class Action_Rotate : public Action {
Expand Down Expand Up @@ -33,5 +34,6 @@ class Action_Rotate : public Action {
DataSet* dsout_ty_; ///< Hold output theta Y (calc)
DataSet* dsout_tz_; ///< Hold output theta Z (calc)
DataSet* dsout_t_; ///< Hold output theta (calc)
Cpptraj::ParallelSetFrameNum parallelNum_;
};
#endif
21 changes: 21 additions & 0 deletions src/ParallelSetFrameNum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "ParallelSetFrameNum.h"
#include "CpptrajStdio.h"
#include "DataSet.h"
using namespace Cpptraj;

void ParallelSetFrameNum::SetForParallel(DataSet const* setIn) {
set_ = setIn;
# ifdef MPI
// In parallel, number to use will depend on whether the set exists or not
if (set_->Size() > 0)
exists_ = true;
else
exists_ = false;
# ifdef DEBUG_CPPTRAJ_PARALLELSETFRAMENUM
if (!exists_)
rprintf("DEBUG: Set '%s' does not yet exist.\n", set_->legend());
else
rprintf("DEBUG: Set '%s' exists with size %zu.\n", set_->legend(), set_->Size());
# endif
# endif /*MPI */
}
38 changes: 38 additions & 0 deletions src/ParallelSetFrameNum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef INC_PARALLELSETFRAMENUM_H
#define INC_PARALLELSETFRAMENUM_H
class DataSet;
namespace Cpptraj {
/// Used to pick the correct frame from a data set in parallel
/** In parallel, Actions that access data from DataSets need to handle
* two cases:
* 1) The data set exists already before trajectory processing.
* 2) The data set is being created during trajectory processing.
* In case 1, the data set should be accessed using ActionFrame::TrajoutNum().
* In case 2, the data set should be accessed using the frameNum variable
* since the set has not yet been synced.
*/
class ParallelSetFrameNum {
public:
/// CONSTRUCTOR
ParallelSetFrameNum() : set_(0), exists_(false) {}
/// Initialize with DataSet, record if it has any data yet.
void SetForParallel(DataSet const*);
/// \return Correct frame number in parallel based on whether set exists or is being generated
int ParallelFrameNum(int frameNum, int trajoutNum) const {
# ifdef MPI
// In parallel, number to use depends on whether the set is being generated or not.
if (exists_)
return trajoutNum;
else
return frameNum;
# else
// In serial, just return the frame number.
return frameNum;
# endif
}
private:
DataSet const* set_; ///< The DataSet in question
bool exists_; ///< True if set exists, false if it is being generated.
};
} // END namespace Cpptraj
#endif
2 changes: 1 addition & 1 deletion src/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* Whenever a number that precedes <revision> is incremented, all subsequent
* numbers should be reset to 0.
*/
#define CPPTRAJ_INTERNAL_VERSION "V6.29.5"
#define CPPTRAJ_INTERNAL_VERSION "V6.29.6"
/// PYTRAJ relies on this
#define CPPTRAJ_VERSION_STRING CPPTRAJ_INTERNAL_VERSION
#endif
5 changes: 3 additions & 2 deletions src/cpptrajdepend

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/cpptrajfiles
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ COMMON_SOURCES= \
PairList.cpp \
Parallel.cpp \
ParallelNetcdf.cpp \
ParallelSetFrameNum.cpp \
ParmFile.cpp \
Parm_Amber.cpp \
Parm_CharmmPsf.cpp \
Expand Down

0 comments on commit b41f221

Please sign in to comment.