-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How is pytraj different from MDAnalysis and mdtraj? #445
Comments
Design
|
Code quality
|
Easy to use?
|
number of analyses
|
FlexibilityI don't have much experience about Per This is an example from rmsds = []
for chunk in md.iterload(traj_filename, chunk=100):
rmsds.append(md.rmsd(chunk, first_frame))
print(chunk, '\n', chunk.time) this is from In [4]: import pytraj.common_actions as pyca
In [5]: pyca.calc_radgyr(traj)
Out[5]:
<pytraj.datasets.DataSet_double: size=10, name=RoG_00000, legend=RoG_00000[Max],
aspect=Max, dtype=double, format=%12.4lf>
values: [ 26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993]
In [6]: pyca.calc_radgyr([traj, traj])
Out[6]:
<pytraj.datasets.DataSet_double: size=20, name=RoG_00002, legend=RoG_00002[Max],
aspect=Max, dtype=double, format=%12.4lf>
values: [ 26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993
26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993]
In [7]: pyca.calc_radgyr([traj, traj, traj.chunk_iter(chunk=4)])
Out[7]:
<pytraj.datasets.DataSet_double: size=30, name=RoG_00004, legend=RoG_00004[Max],
aspect=Max, dtype=double, format=%12.4lf>
values: [ 26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993
26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993
26.66003587 16.50015787 17.08691826 16.55618147 15.18575198
15.86350294 14.08403482 14.65317853 14.48540094 13.69095993] |
Better trajectory iterator(I will add note about Per In [4]: import mdtraj as md
In [5]: traj_filename = mdtraj.testing.get_fn('frame0.h5')
In [6]: md.iterload(traj_filename, chunk=100)
Out[6]: <generator object iterload at 0x7feea2f583a8> while In [7]: import pytraj.io
In [8]: traj = pytraj.io.load_sample_data("tz2")
In [9]: traj
Out[9]:
<pytraj.TrajectoryIterator with 10 frames: <Topology with 1692 mols, 1704 residues, 5293 atoms,
5300 bonds, PBC with box type = ortho>>
And user never need to explicitly In [10]: traj.n_frames
Out[10]: 10
In [11]: for idx, frame in enumerate(traj):
....: pass
....:
In [12]: assert idx == 9
In [13]: for idx, frame in enumerate(traj):
pass
....:
In [14]: assert idx == 9
In [15]:
In [21]: traj
Out[21]:
<pytraj.TrajectoryIterator with 10 frames: <Topology with 1692 mols, 1704 residues, 5293 atoms,
5300 bonds, PBC with box type = ortho>>
In [22]: traj.load(fname)
In [23]: traj
Out[23]:
<pytraj.TrajectoryIterator with 20 frames: <Topology with 1692 mols, 1704 residues, 5293 atoms,
5300 bonds, PBC with box type = ortho>> |
parallel
just # mpi_example.py
from mpi4py import MPI
from pytraj.parallel import map as pymap
import pytraj.common_actions as pyca
comm = MPI.COMM_WORLD
total_arr = pymap(comm, pyca.calc_molsurf, traj, "@CA", top=traj.top, dtype='ndarray', root=0)
if comm.rank == 0:
print (total_arr) and then
pytraj's map will automatically split the Note: not always get embarrassing speeding up. See Jason's comment below. |
What's the MPI speedup? |
it's in the last sentence "Since there is minimal communication among nodes, user should get embarrassing ~4 times speedup." This is true at least for |
I have a notebook comparing http://nbviewer.ipython.org/github/pytraj/pytraj/blob/master/note-books/parallel/rmsd_mpi.ipynb |
That's only true for something that's compute-bound. I/O bound applications are another story altogether -- your speedups stop as soon as the SATA bandwidth becomes saturated (I don't know when this is, which is why I asked, and it will vary from machine to machine). For highly parallel filesystems (e.g., Lustre), you can probably get good speedup (unless the filesystem sucks or your data is very poorly striped). On a standard desktop, scaling will top out as the I/O bus fills up. Also, a lot of the most computationally demanding analyses are not embarrassingly parallel (FFTs, 2D-RMSD, and clustering to name a few). They can be parallelized, but not without communication (and in that case you may be better off going with SMP, which I think is why Dan dropped MPI for non-REMD analyses in favor of OpenMP). |
I still have very limited knowledge about MPI. But I don't know if I/O is really big problem here. For example, if I want to use 8 cores, I will create one Of course,
You are right. I should mention in previous section that user should expect speeding up if there is minimal communication among nodes. I think For the ones you mentions, they are in Analysis classes, and most of them (AFAIN) require pairwise Frame calculation. I agree that this is very difficult to parallelize with MPI. |
You're still getting hung up on communication. In MD engines (sander, pmemd, Gromacs, you name it), 99.9% of the time those programs run is spent doing calculations with the processor. In that case, the more a processor has to wait to be filled with data (communication overhead), the worse the scaling is. But with trajectory analysis, you are filling data from disk, which is orders of magnitude slower than filling data from RAM (which is probably an order of magnitude slower than filling registers from cache, but I digress). The issue is that a lot of trajectory analysis spends more time reading a single frame from disk than it spends computing an RMSD (or at least it spends a similar amount of time). So it doesn't matter how little pytraj-MPI communicates, parallel scaling will halt as soon as frame reading becomes as expensive as the calculation (or close to it) and N+1 threads can't retrieve data faster from disk than N threads. Basically, I know communication is not a bottleneck (since there's none of it), but there are other potential bottlenecks than just MPI messages (in this case, disk I/O). But maybe disks have gotten a lot better, or your machine is particularly good, or... |
thanks. I see. I will read more about this. |
@swails I just remember that pymmpbsa is using MPI too? what's the scaling? |
Universal
import pytraj as pt
pt.io.load(filename, topology_name) # default `pytraj`
pt.io.load(filename, topology_name, engine='mdtraj')
pt.io.iterload(filename, topology_name, engine='mdanalysis') |
use different engines for loading data
import pytraj as pt
traj = pt.iterload(traj_filename, topology_filename)
In [13]: from mdtraj.testing import get_fn
In [14]: fn = get_fn("frame0.h5")
In [15]: import pytraj as pt
In [16]: traj = pt.load(fn, engine='mdtraj')
In [18]: from MDAnalysisTests import datafiles
In [19]: t = pt.iterload(datafiles.DCD, datafiles.PSF, engine='mdanalysis') |
parallel - 2It's very easy to embarrassingly parallelize user's analysis function just def new_func(traj, mask, *args, **kwd):
... and call import pytraj as pt
pt.pmap(n_cores=4, func=new_func, traj, mask, *args, **kwd)
Advantages:
|
Note: this is from my experience of using
MDAnalysis
andmdtraj
. Since I spend most of my time playing withpytraj
, there will be bias for this package. If my information aboutMDAnalysis
andmdtraj
is not correct, please feel free to comment here.Each sub-section below will be filled more in future.
The text was updated successfully, but these errors were encountered: